Storing your PHP sessions using memcached

August 25th, 2008 | by Guillaume Plessis |

Using PHP sessions can be a problem when your PHP applications are load-balanced on many web servers. You can store them on a NFS export or recode the session_set_save_handler using a SQL backend for example. But there is no solution more efficient, more scalable, more performant and easier to deploy than using memcached…

Memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load…

Many well-known huge architecture (Facebook, Livejournal, Youtube…) are using it as memory caching to reduce the load on their servers. It can also be used to share PHP sessions among several servers. Let’s see how…

Installation

The first thing is to install the memcached server on your Debian server :

apt-get install memcached

Then, since the memcache PECL extension now provides its own session handler, it’s easy to plug PHP and memcached servers. Just install the appropriate extension (from Dotdeb) :

apt-get install php5-memcache

and change some of your PHP settings :

session.save_handler = files
; session.save_path = "N;/path"

to :

session.save_handler = memcache
; change server:port to fit your needs...
session.save_path="tcp://server:port?persistent=1&weight=1&timeout=1&retry_interval=15"

That’s all! After relaunching your Apache2 server, your PHP sessions will be stored on the memcached server.

Tags:

  1. 18 Responses to “Storing your PHP sessions using memcached”

  2. By Alex on Oct 6, 2008 | Reply

    I followed this guide step by step but I can’t store my sessions in memcached. The memcache module is configured (appears in php_info()) but when I try to do a session_start this fails.

  3. By Guillaume Plessis on Oct 9, 2008 | Reply

    It works without any problem.

    Be sure that /etc/php5/conf.d/memcache.ini contains this line :

    extension=memcache.so

    and that your session.save_path is well set in your php.ini. For example :

    session.save_path=”tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15″

    Check your firewall settings if you installed one.

    Then stop and start Apache (not restart) and display a phpinfo(), it should work.

  4. By Joao Alfredo on Dec 5, 2008 | Reply

    Hello Guillaume,

    I was looking for something like memcached to use it with php_sessions.

    It looks amazing!

    But some doubts arose and I think you can help me.

    Do you know if its possible to have control over the sessions in memcached ?

    Like to know the number of sessions and the possibilite to kill a session.

    Thanks.

  5. By Guillaume Plessis on Dec 5, 2008 | Reply

    It could be possible to manipulate sessions directly by using the memcache_* functions. Take a look at the source code of the memcache session handler, it seems to be a Memcache::delete call :

    http://cvs.php.net/viewvc.cgi/pecl/memcache/memcache_session.c?revision=1.9&view=markup

  6. By Ruben Vandille on Dec 12, 2008 | Reply

    The same considerations are valid for other save_handler settings … the default ‘file’ handler for example:

    $dh = @opendir(ini_get(’session.save_path’));
    while (false !== ($file = readdir($dh))) {
    if (strstr($file, ’sess_’)) {
    @unlink(unlink(ini_get(’session.save_path’) . “/$file”));
    }
    }

  7. By Son on Dec 14, 2008 | Reply

    Like Alex, I am not able to get the memcache to work with my session handler. I am currently running two VM’s. One for the memcache and one for the Front-end server. Both VM’s are running Debian Etch with Apache, and php5-memcache installed.

    The MemCached VM is located at xxx.xxx.xx.xxx and running on port 11211.

    On my front-end server, I have set the session handler in php.ini as below:

    session.save_handler = memcache
    session.save_path = “tcp://xxx.xxx.xx.xxx:11211″

    When I run session_start(), I get the following warning: “Warning: session_start() [function.session-start]: Cannot find save handler memcache”.

    Does anyone have any idea why this is happening? Your help is greatly appreciated.

  8. By Son on Dec 14, 2008 | Reply

    In addition to my last post:

    Strange thing is that it works fine when I use the php’s MemCache api’s.

    For example, from my front-end server, I am able to run the following code without any problems:

    $memcache = new Memcache;
    $memcache->connect(’xxx.xxx.xx.xxx’, 11211) or die (”Could not connect”);

    $version = $memcache->getVersion();
    echo “Server’s version: “.$version.”\n”;

    $tmp_object = new stdClass;
    $tmp_object->str_attr = ‘test’;
    $tmp_object->int_attr = 123;

    $memcache->set(’key’, $tmp_object, false, 5000) or die (”Failed to save data at the server”);
    echo “Store data in the cache (data will expire in 10 seconds)\n”;

    $get_result = $memcache->get(’key’);
    echo “Data from the cache:\n”;

    var_dump($get_result);

  9. By Guillaume Plessis on Dec 14, 2008 | Reply

    @Son : Could you please provide a phpinfo() so that I check that everything is ok?

  10. By Son on Dec 14, 2008 | Reply

    Hi Guillaume,

    Thanks for the quick reply. At the moment, the VM’s are not in a public domain. Nonetheless, below is the phpinfo that pertains to memcache:

    System Linux fe1 2.6.18-6-amd64 #1 SMP Wed Oct 15 10:07:11 UTC 2008 x86_64
    Build Date Sep 30 2008 18:29:09
    Server API Apache 2.0 Handler
    Virtual Directory Support disabled
    Configuration File (php.ini) Path /etc/php5/apache2/php.ini
    Scan this dir for additional .ini files /etc/php5/apache2/conf.d
    additional .ini files parsed /etc/php5/apache2/conf.d/mysql.ini, /etc/php5/apache2/conf.d/mysqli.ini, /etc/php5/apache2/conf.d/pdo.ini, /etc/php5/apache2/conf.d/pdo_mysql.ini
    PHP API 20041225
    PHP Extension 20060613
    Zend Extension 220060519
    Debug Build no
    Thread Safety disabled
    Zend Memory Manager enabled
    IPv6 Support enabled
    Registered PHP Streams zip
    Registered Stream Socket Transports tcp, udp, unix, udg, ssl, sslv3, sslv2, tls
    Registered Stream Filters string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, convert.iconv.*, bzip2.*, zlib.*

    apache2handler
    Apache Version Apache/2.2.3 (Debian) mod_python/3.2.10 Python/2.4.4 PHP/5.2.0-8+etch13 mod_perl/2.0.2 Perl/v5.8.8
    Apache API Version 20051115
    Server Administrator webmaster@local.sandbox
    Hostname:Port local.sandbox:0
    User/Group www-data(33)/33
    Max Requests Per Child: 0 – Keep Alive: on – Max Per Connection: 100
    Timeouts Connection: 300 – Keep-Alive: 15
    Virtual Server Yes
    Server Root /etc/apache2
    Loaded Modules core mod_log_config mod_logio prefork http_core mod_so mod_alias mod_auth_basic mod_authn_file mod_authz_default mod_authz_groupfile mod_authz_host mod_authz_user mod_autoindex mod_cache mod_cgi mod_dir mod_env mod_mem_cache mod_mime mod_python mod_negotiation mod_perl mod_php5 mod_rewrite mod_setenvif mod_status

    memcache
    memcache support enabled
    Active persistent connections 0
    Revision $Revision: 1.39 $

    session
    Session Support enabled
    Registered save handlers files user
    Registered serializer handlers php php_binary wddx

    Directive Local Value Master Value
    session.auto_start Off Off
    session.bug_compat_42 On On
    session.bug_compat_warn On On
    session.cache_expire 180 180
    session.cache_limiter nocache nocache
    session.cookie_domain no value no value
    session.cookie_httponly Off Off
    session.cookie_lifetime 0 0
    session.cookie_path / /
    session.cookie_secure Off Off
    session.entropy_file no value no value
    session.entropy_length 0 0
    session.gc_divisor 100 100
    session.gc_maxlifetime 1440 1440
    session.gc_probability 0 0
    session.hash_bits_per_character 4 4
    session.hash_function 0 0
    session.name PHPSESSID PHPSESSID
    session.referer_check no value no value
    session.save_handler memcache memcache
    session.save_path tcp://xxx.xxx.xx.xxx:11211 tcp://xxx.xxx.xx.xxx:11211
    session.serialize_handler php php
    session.use_cookies On On
    session.use_only_cookies Off Off
    session.use_trans_sid 0 0

    Thanks in advance!

  11. By Guillaume Plessis on Dec 14, 2008 | Reply

    @Son Your memcache version does not match mine, so please ensure you did install php5-memcache and all the php5-related packages from Dotdeb. You should obtain the same result as http://www.moolfreet.com/phpinfo.php

  12. By Son on Dec 17, 2008 | Reply

    Thanks. I’ll look into this.

  13. By Son on Dec 17, 2008 | Reply

    Guillaume,

    I followed your steps and still, I am getting the same results.

    Any idea?

    -Son

  14. By Guillaume Plessis on Dec 17, 2008 | Reply

    @Son : something’s wrong, you should se “Version : 3.0.2″ in the memcache section of your phpinfo(). What is the output of :

    dpkg -l ‘*php5*’

    You should only see packages from Dotdeb. Debian’s php5-memcache does not include the memcache session handler!

  15. By Lewis Carr on Jan 18, 2009 | Reply

    Check that there is only 1 session save path, I had 2 in my php.ini and this caused the problem.

  16. By Laph on May 8, 2009 | Reply

    An important side-note: Debian cleans up sessions using a cron job – and therefore disables PHP’s internal session cleanup by setting “session.gc_probability” to 0 (zero). You should set this to something > 0 when using memcached as session storage.

  17. By Guillaume Plessis on May 9, 2009 | Reply

    @Laph : thanks for this useful comment.

  18. By Lazy on Jun 1, 2009 | Reply

    @Laph you shouldn’t set touch that, each record in memcached has its ttl, when it’s reached object is automagicly removed from cache so php has no garbage to collect

  1. 1 Trackback(s)

  2. Nov 7, 2008: JohnPuPu » Blog Archive » links for 2008-11-06

Post a Comment