12

I currently have a huge problem. Two days ago my site running on one server was too much, so I purchased two more and had them clustered (rsync and load balanced).

I then start noticing that a user would hit server-1 and then on the next request hit server3 but that their session was still on server1 instead of server3 and they were no longer logged in.

I was recommended to use memcache for session stores.

My script already uses $_SESSION.

  • Can we get memcache installed and enable session handler support and set session.save_handler = "memcache" to force php to use memcache?

  • Is there any application programming that needs to be done to use memcache?

  • Will this solve my session between server issue?

  • Are the session stores stored on all the servers when they are created or is one like a master memcache server?

I'm using the codeiginiter framework

Kev
  • 118,037
  • 53
  • 300
  • 385
William
  • 1,033
  • 2
  • 13
  • 25

7 Answers7

14

There are two parts to the question:

How to deal with requests going to different servers?

This is down to your load balancer/reverse-proxy. It's common to make clients stick to one server, usually by IP address or a transparent cookie set by the proxy. However, it's not necessary to have client stickiness for the sake of sessions if you have a distributed session store, which brings us to memcache.

How to use memcache for session storage on multiple servers?

memcache has a proper shared-nothing distributed architecture, so most of the intelligence is at the client end. So what you should do is go ahead and use the memcache session storage, but instead of pointing at one server, point it at ALL of them. This is covered in the docs. In your php.ini you should set session.save_path to the list of memcached servers, for example server1:11211, server2:11211.

Be aware that there are two distinct memcache client libraries available in PHP called memcache and memcached and they have different syntax for this property.

Because of the way that memcache works, you don't care where your session data is stored - it's taken care of for you.

As NathanD points out, memcache is volatile and loses data on a restart, and when you have multiple servers this would mean that some (but not all) of your users would be logged out if one was restarted. If one server dies completely your session storage will stay working. Users whose session data was on the dead server will be kicked off, but they can log back in and carry on without that server being present.

Community
  • 1
  • 1
Synchro
  • 35,538
  • 15
  • 81
  • 104
5

Both of the major memcache PHP PECL extensions have session handlers. Either will require you to install a PECL module before use.

The Memcache PECL extension session handler is enabled with the following in php.ini:

session.save_handler = "memcache"
session.save_path = "tcp://memcacheServerAddressHere:11211?persistent=1&weight=2&timeout=2&retry_interval=10"

The Memcached PECL extension session handler is enabled with the following in php.ini:

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

Note that the Memcache extension appears to allow more configuration of the Memcache environment.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
2

You would need to set up memcache to run on one of the servers and have all of the servers use that same memcache instance for the sessions. Otherwise, if they each run their own memcache instance, you'll have the same problem as before.

Other than configuring memcache accordingly and telling PHP to use it as your session handler, you shouldn't have to make any changes to your code.

~

To clarify the advice I gave here, if you group all three servers into a single pool, you won't have any problems as long as every PHP instance references those servers in the same order. memcache uses client side hashing, so you will be guaranteed that the same key is read / written on the same server. Of course, if you alter that list in any way, then sessions will become invalidated.

The memcache developers actually don't even recommend that you use memcache for storing session data because it isn't persistent, and thus if you have to restart memcache (or something happens), then all of your users will be logged out.

Matthew
  • 47,584
  • 11
  • 86
  • 98
  • Do you think dedicating 4gb of memory from our server is good enough? we have 24gb each server – William Oct 07 '10 at 21:06
  • 1
    That seems like a huge number, but it depends on how many simultaneous sessions you have and how much data you store in them. Just doing a directory listing of the /tmp (or wherever the files are currently stored) should give you a good idea of how big your session data is. I just checked a site I run and it uses ~1MB per 200 users, with the median session size only being 85 bytes. But obviously those numbers are only applicable to that particular site. – Matthew Oct 07 '10 at 23:33
  • 2
    Eek! Old as it is, this answer is completely wrong, and completely misunderstands how memcache works. – Synchro Mar 02 '12 at 00:03
  • As said by the user above me, this answer is no longer correct and is outdated. – skrilled Jul 23 '14 at 17:13
  • 1
    skillred and Syncho, could you please clarify how it's wrong? – Scott Buchanan Sep 18 '14 at 18:21
  • @ScottSB: By using a single memcache server, it's reintroducing a single point of failure; memcache's consistent hashing doesn't guarantee the same server, merely that it ends up in the same place on a unit circle, which could mean the server that handles it varies - this keeps it working if a server dies; For this reason, all servers should use **all** memcache instances, not just one. This also reduces the impact of restarting one memcache server. You can avoid most of the downsides by using redis instead of memcached as it's similarly fast but can also have persistence. – Synchro May 04 '15 at 05:53
1

You want to be careful about doing this. One thing to be careful about is to not host session info with other non-session data. It isn't the biggest deal to clear your cache when it only contains your own site's data but you do not want to wipe out people's sessions along with it.

As long as your are using the same key with memcache you should hit the same server every time. So that issue should go away.

Wix
  • 2,144
  • 1
  • 15
  • 13
  • Exactly the server only has 1 site on it so do you think that will be an issue? we are doing mem cache with a db server – William Oct 07 '10 at 20:47
  • 2
    You should be fine. You just need to be careful when you want to refresh the server. We have put one of our application's sessions on Memcache and we are very careful about it. – Wix Oct 08 '10 at 10:54
0

it is better to use memcachedb as a persistent storage for memcache itself or even to use the more smarter redis which I highly recommend in your case

Muhammad Soliman
  • 21,644
  • 6
  • 109
  • 75
0

You can also write your sessions to a SQL DB. This will also give you persistent sessions across servers. See the tutorial below: http://culttt.com/2013/02/04/how-to-save-php-sessions-to-a-database/

If you insist on running the sessions in memcached (in order to have better performance, but lower consistency) you can simply rewrite his code in a couple of places

Daan
  • 1,663
  • 1
  • 15
  • 13
0

You can sync file-based sessions too. I do it on my two load-balanced servers. On Ubuntu and a bunch of other Linuxes, sessions are stored in /var/lib/php5.

I followed the steps over here on Superuser, mounting the PHP session folder from one server on the other.

Community
  • 1
  • 1
Skylar Ittner
  • 802
  • 11
  • 26