7

I've done some research into this and have not found a definitive answer.

We have a web app that is using the PHP+Memcache session handler.

I have several questions, all interrelated, but ultimately my issue is, "Why are PHP sessions apparently not expiring when we think they should be?" i.e. The end user should be logged out of the app after a set time, but is not.

Here are the dots, please help me connect them, and tell me where I am mistaken:

  • My understanding is that Memcache expires keys based on the set time, in seconds (or unix timestamp for larger values).
  • The expiration is lazy -- i.e. nothing is deleted in advance
  • The PHP memecache session handler uses the sessions.gc_max_lifetime to set the memcache key expiration. idk, maybe it doesn't?
  • Memcache should, on serving a requested key and seeing that it is expired, not serve it (and then maybe also delete it?). But at least not serve it.
  • This act of not serving it should, to PHP, equate to a deleted session and the user being logged out.

Users are not being logged out.

How can I even debug this? Memcache isn't exactly transparent.

The example case that has not been working is a site with a session timeout set to two hours. An example user would last use the site at night, and then, 8 - 10 hours later, come back to the site and still be logged on.

c33s
  • 1,465
  • 3
  • 20
  • 39
JDS
  • 2,508
  • 4
  • 29
  • 48
  • maybe the following bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=620258 – c33s Dec 19 '11 at 15:36
  • The problem with memcache based session handling, is if you run out of memcached memory space, your sessions will start to disappear... and your users getting angry. – Jauzsika Jan 13 '12 at 10:12

1 Answers1

10

We've encountered this as well, but have managed to dig into it and work out exactly what's going on. The symptoms we encountered was that memcache (with a reasonably large memory allocation running across multiple servers) started to evict content. This is undesirable, as it can adversely affect current visitors on the site.

By monitoring network traffic, we saw messages from PHP to Memcache as follows:

set memc.sess.key.abcdabcdabcdabcdabcdabcd 0 0 1823 data...

It's the second zero that causes the problems - this dictates the length of time that memcache caches the item. By setting it to zero, memcache never expires this item. In your case this meant users could return hours later and continue accessing your site. In our case, memcache was filling up and causing desired data to be evicted.

I dug further, and it boils down to the PHP memcached extension. As of 1.0.2 (which we're running), this code reads:

sess_lifetime = zend_ini_long(ZEND_STRL("session.gc_maxlifetime"), 0);
if (sess_lifetime > 0) {
    expiration = time(NULL) + sess_lifetime;
} else {
    expiration = 0;
}

In this excerpt, it's ZEND_STRL("session.gc_maxlifetime") which isn't returning the expected value. This has been reported as a bug to PHP, and a fix to the memcached library is described at https://bugs.php.net/bug.php?id=59641.

I've deployed this patch, reviewed network traffic, and found that it does set the expiry time as expected.

Bart De Vos
  • 17,761
  • 6
  • 62
  • 81
rtshilston
  • 121
  • 1
  • 3
  • How is your PHP deployed? Custom compiled from source? Linux distro binaries + distro updates? Etc.. Othewise, thanks for the tip, this sounds very promising! – JDS Jan 23 '12 at 19:10