64

I'm working with a couple of Web Servers behind a Load Balancer and I can enable Sticky Sessions to hold a user to the one specific Web Servers - this will work.

I have been reading about PHP Sessions & MemCache. I must say what I've read is a touch confusing as some pages say its a good idea and others the opposite.

Questions:

  1. is it possible to keep php sessions in memcache?
  2. is it better to use sticky sessions over memcache?
  3. what are the problems with php sessions in memcache - note: I can get enough cache (amazon so its expandable).
Cœur
  • 37,241
  • 25
  • 195
  • 267
Adam
  • 19,932
  • 36
  • 124
  • 207
  • A third option is storing sessions in the database. You can use the session_set_save_handler() method: http://php.net/manual/en/function.session-set-save-handler.php. You'd get a performance benefit that scales easier. – Jabari Sep 12 '16 at 23:36
  • 2
    Never use a database as session handler. That is very bad advice from @Jabari. Actually you should minimize the use of databases to a minimum to save load and memory. That is why we have stuff like memcached and apc. I use memcached for frequent read/writes like sessions and apc for storing stuff that is fairly constant like articles and options for select boxes in forms. The database is then used as a fallback and to reinitialize memcache and apc if necessary... – Jette Jul 31 '19 at 18:52
  • @Jette Keep in mind, that comment was back in 2012. Yes, memcache and/or Redis is a much better option. – Jabari Aug 01 '19 at 06:07
  • I tried it even before 2012, and it was a disaster. – Jette Aug 01 '19 at 09:01
  • @Jette I've done it countless times with extremely high rates of traffic without issue. Implementing something and implementing it correctly aren't always the same thing. It's a moot point as memcache, Redis, and other solutions are much better for the task, as I stated above. That said, I'd be happy to look at the implementation you did. Do you have a link or code sample? – Jabari Sep 15 '19 at 02:34
  • 1
    @Jabari, I am not able to link to an implementation where the database is used as a sessionhandler. We tried it briefly and then switched to memcache. The read/write load on the database was way too heavy. Maybe the database server used at the time was not big enough for the task, but the difference between using mysql as session handler and using something else, was so obvious that I would never do it again. – Jette Sep 17 '19 at 10:09

4 Answers4

71

1: YES. And I strongly recommend storing PHP sessions in Memcached. Here's why:

Memcached is great for storing small chunks of data that are frequently accessed by the database and filesystem.

Memcached was designed specifically for sessions. It was originally the brainchild of the lead developer of livejournal.com and later used to also cache the content of users' posts. The benefit was immediate: most of the action was taking place in memory. Page load times greatly improved.

Thankfully, PHP and Apache have an easy implementation to handle sessions with Memcached. Simply install with a few shell commands

example for Debian:

sudo apt-get -t stable install php7.4-memcached

and

change your php.ini settings to something similar to:

(taken from https://www.php.net/manual/en/memcached.sessions.php)

 session.save_handler = memcached
 ; change server:port to fit your needs...
 session.save_path = "localhost:11211"

The key is the session.save_path

It will no longer point to a relative file path on your server. APC was mentioned - APC for the caching of .php files used by the program. APC and Memcached will reduce IO significantly and leave Apache/Nginx free to server resources, such as images, faster.

2: No

3: The fundamental disadvantage of using Memcached is data volatility

Session data is not persistent in Memcached. So if and when the server crashes, all data in memory is lost. Everyone will have to log in again.

And then you have memory consumption...

Remember: the sessions are stored in the memory. If your website handles a large number of concurrent users, you may have to shell out a little extra money for a larger memory allocation.

Oleg Abrazhaev
  • 2,751
  • 2
  • 28
  • 41
FredTheWebGuy
  • 2,546
  • 3
  • 27
  • 34
  • 1
    We use this extensively and Memcached is the way to go hands down. I wouldn't even suggest you use file system storage for the obvious reasons here in the answer. – akahunahi Mar 18 '14 at 00:07
  • 5
    It has been a couple of years since I've posted this answer, and it's worth noting that there is a robust alternative for scaling sessions: Redis. PHP has a great drop-in solution known as the Predis library and implementation takes just a few minutes, almost as easy as the above Memcached solution. – FredTheWebGuy Mar 18 '14 at 19:46
  • 2
    I agree with Dreadful code, depending on the usability here Redis could be a better solution. But it depends on the software stack being used IMHO. For us we tend to use both Memcache and Redis due to PHP's built-in session variables in our application. Redis functions as a product key lookup. It's done by design, legacy support, and organization. Redis could easily be used instead for everything. – akahunahi Jul 28 '14 at 19:15
  • 1
    Please note that the answer is providing information about memcacheD, but the php.ini config is for memcache **only**. – Toto Dec 15 '18 at 11:14
  • For memcacheD (as of PHP7), the `session.save_path` has to be declared without protocol, eg: `server:port?persistent=1&weight=1&timeout=1&retry_interval=15` – 4levels May 08 '19 at 11:49
  • 2
    Also keep in mind that there's one caveat: session locking does not work with memcached, meaning you can run into race conditions.. – 4levels May 08 '19 at 11:50
  • @4levels I wonder where you got that info from. The PHP memcached session handler does handle locking just fine. However, the redis session handler was missing locking IIRC, and I cannot say if this has been fixed after I looked at it. In general: Watch out if any solution that is suggested supports proper locking. It is essential for PHP sessions to have it, and for any implementations, either as an extension or as PHP code, to provide it. – Sven Jul 16 '20 at 16:30
  • @sven first contributed note here: https://www.php.net/manual/en/memcached.sessions.php – 4levels Jul 20 '20 at 11:16
  • @4levels I go to the linked page, and I search for "lock" in the browser, and all I find is a comment from "Andrei Darashenka" from 11 years ago that states: "This extension supports Session-locking!" - quite the opposite of your claim. The first contributed note I see is from "nfoo at naver dot com" and discusses the differences of memcache vs memcached extension and session configuration. – Sven Jul 23 '20 at 10:56
  • Hi @Sven, I meant the info on the "not specifying the protocol" is in the first comment. From experience I know that memcached is not suitable for different reasons, the most problematic ones being it not having a precise clock nor persistence.. – 4levels Aug 17 '20 at 14:22
9

1. Yes, it is possible to keep PHP sessions in memcached.

The memcache extension even comes with a session handler that takes very little configuration to get up and running. http://php.net/manual/en/memcached.sessions.php

2. Memcache/Sticky Sessions

I don't really know which is "better". I feel this is going to be one of those "it depends" answers. It likely depends on your reasons for load balancing. If a small number of users cause lots of load each, or if it's a large number causing a small load each.

3. Cons of Memcache

There are probably 2 main cons to using memcache for sessions storage.

Firstly, it is volatile. This means, if one of your memcached instances is restarted/crashes etc. any sessions stored in that instance are lost. While if they were using traditional file based sessions, they will be still there when the server returns.

Secondly and probably more relevant, memcached doesn't guarantee persistance, it is only meant to be a cache. Data can be purged from memcached at any time, for any reason. While, in reality, the only reasons data should be purged is if the cache is nearing its size limits. The least recently accessed data will be expelled. Again, this might not be an issue, as the user is probably gone if their session is stale, but it depends on your needs.

Brenton Alker
  • 8,947
  • 3
  • 36
  • 37
  • Are you sure about 3? I don't think you lose session from memcache if you do a memcache restart – johnlemon Aug 08 '13 at 06:50
  • 2
    Yes, I'm sure. At least in its normal configurations. Memcached stores data in memory (RAM) only. If you restart the computer, or even just the service it will be lost. It is designed as a cache, not as persistent storage. If you require persistence, other options like memcacheDB, redis or many other more traditional databases (eg. MySQL) can also be used for sessions (Check the answers here http://stackoverflow.com/questions/1316852/alternative-to-memcached-that-can-persist-to-disk - it's a Java question, but many (most/all?) answers still apply) – Brenton Alker Aug 08 '13 at 08:26
  • With any reasonable config your sessions can last through a memcache restart. You need to do a periodic write through where you update the session in the DB also every X page loads or similar. Then the session stays up to date. If you session is very very data loaded this may not work. – GL_Stephen Apr 23 '14 at 18:00
  • The native Memcache server does not have any "writethrough" or persistance implemented. Restarting the server will erase any data. On the positive side: Every time PHP writes back a session, it will use the session_max_lifetime as the expiry time for Memcache, so Memcache will clean up expired sessions automatically without any additional effort. Compare that to the default file based session storage that uses a random chance of triggering the cleanup of session files. – Sven Jul 16 '20 at 16:47
5

If you want to use "memcacheD" extension not "memcache" (there are two different extensions) for session control, you should pay attention to modify php.ini.

Most web resources from Google is based on memcache because it's earlier version than memcacheD. They will say as following:

session.save_handler = memcache 
session.save_path = "tcp://localhost:11211" 

But it's not valid when it comes to memcacheD.

You should modify php.ini like that:

session.save_handler = memcached 
session.save_path = "localhost:11211" 

There is no protocol indentifier.

From: http://php.net/manual/en/memcached.sessions.php#99646

DustWolf
  • 516
  • 7
  • 10
ribluc
  • 51
  • 2
  • 3
2

As my point of view its not recommended storing sessions in Memcached.If a session disappears, often the user is logged out,If a portion of a cache disappears or either due to a hardware crash it should not cause your users noticable pain.According to the memcached site, “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.” So while developing your application, remember that you must have a fall-back mechanism to retrieve the data once it is not found in the Memcached server.

indika
  • 821
  • 7
  • 13