Enhance PHP session management

来源:百度文库 编辑:神马文学网 时间:2024/04/28 06:57:29

Enhance PHP session management

InPHP, sessions can keep track of authenticated in users. They are anessential building block in today's websites with big communities and alot of user activity. Without sessions, everyone would be an anonymousvisitor.
In system terms, PHP sessions are little files, stored on the server'sdisk. But on high traffic sites, the disk I/O involved, and not beingable to share sessions between multiple webservers make this defaultsystem far from ideal. This is how to enhance PHP session management interms of performance and shareability.

Session sharing in web clusters

If you have multiple webservers all serving the same site, sessionsshould be shared among those servers, and not reside on each server'sindividual disk. Because once a user gets load-balanced to a differentserver, the session cannot be found, effectively logging the user out.

A common way around this is to use custom session handlers. Writing aclass that overrules default behavior and stores sessions in a MySQLdatabase.

Sessions in Database

All webservers connect to the same database and so, as soon as www01registers a session (insert in a sessions table), www02 can read it. Allservers can now see all sessions: problem solved?

Yes, and no. This sure is functional and tackles the shareabilityissue. But databases seem to be the biggest bottlenecks of web clustersthese days. They are the hardest to scale, and so in high trafficenvironments you don't want to (ab)use them for session management ifyou don't have to. We have to tackle the 'performance' issue.

Database memory

Memory is about 30 times faster than disk storage. So storing our sessions in memory somehow, could deliver great performance.

MySQL query caching

One form of using database memory is the standard MySQL querycaching. But MySQL query caching isn't very effective because itinvalidates all cache related a table, if only one record in that tableis changed.

Of course the session table is changed all the time, so the sessioncache is purged all the time, rendering it quite useless for ourpurposes.

Heap tables / Memory tables

We're really closing in to our goal now. Storing the sessions in aheap/memory table (a table that lives in your database server's RAM)speeds up things greatly. Many demanding sites have opted for thissolution.

In my eyes however, it's still not optimal. Because it still requiresa lot of additional queries that your database server(s) shouldn'tnecessarily have to process.

One other possible solution is using Memcache. And you will find it'seasier to setup and has a smaller footprint than most alternatives. Forone thing, because you will not have to code custom session handlerclasses in PHP. Memcache session support comes native.

Memcache

Memcache is a little program originally written by Live Journal. It'squite straight forward: It reserves some memory, opens a socket andjust stays there.

We can connect to the socket and store variables in it, and laterretrieve them later on. The storage of the variables is done in RAM. Soit's lighting fast ;)

Memcache is used for caching a lot things: function results, entirehtml blocks, database query results. But now we're going to use it tostore our site's user sessions.

Architecture

From system point of view, Memcache looks a lot like MySQL. You have a:

  • Server
    Where information is stored. Should be running at all times.
  • Client module
    Interface to save & get information from the server.
    It's integrated in our programming language.

There is one important difference though. If the Memcache server isshut down, the information in it is lost. So remember to use memcache asa cache only. Don't store information in it, that can't be retrieved insome other way. For sessions this is a risk I'm willing to take. Worstcase scenario is that my users will be logged out. If you cannot livewith this, you could combine database & memcache session handlers.Database will be the safe storage, memcache will be in front of it forperformance. If it crashes, you will only lose performance, and not thedata.

Installing a Memcache server

For session sharing, use a centralized server. If you only have onewebserver, it still makes sense to use Memcache from performance pointof view. Just limit it's maximum allowed memory size to 64MB (dependingon your server & wishes), and use the localhost (127.0.0.1) toconnect to it.

If you don't have a Memcache server already, you can install it veryeasily with package management. I use Ubuntu so in my case that wouldtranslate to:

aptitude install memcached

Adjust the settings in /etc/memcached/memcached.conf. In my case the defaults were OK, I only increased the max allowed memory, and allowed more hosts to connect to it.

Now let's spawn the Memcache Daemon (yes that's what the 'd' stands for):

/etc/init.d/memcached start

Done, we're ready to use it... But how?

Installing a Memcache 'client'

You could just open a socket and go talk to Memcache, but that wouldeventually cause headaches. So there is a standard PHP module we can usethat does a lot of work for us, and allows us to talk object orientedto it. This works much like installing a MySQL module. If it's in yourdistro's package management, good for your, let's:

aptitude install php5-memcache

If not, no problem. Make sure you have pecl available and:

pear install pecl/memcache

(I used 'pear' and not directly pecl to circumvent the bug that caused a Fatal error: Allowed memory size of 8388608 bytes exhausted).

And please choose:

Enable memcache session handler support? [yes] : yes

You must enable PHP to use the memcache.so module we now have. So please add a

extension=memcache.so

to your php.ini (usually located at /etc/php5/apache2/php.ini)

Great, we have all the prerequisites to start Memcaching!

Sessions in Memcache

PHP allows you to overrule the default session handler in two ways:

  1. session_set_save_handler(). By programming your own session handlers, allowing you to virtually use any type of storage, as long as you can read/write to it from PHP. This example uses a MySQL database. We could also use this method to connect to Memcache.
  2. session.save_handler. By specifying one of the default handlers in the php.ini file using the session.save_handler & session.save_path directives.

Option 1 allows greater flexibiliy. And it even allows you to create acombined database/memcache mechanism. Resulting in afallback-on-database in case memcache goes offline and loses all of it'ssessions (effictively logging out all users).

Option 2 is very easy to implement, doesn't require changing your existing code, and is the one I'm going to show you today.

session.save_handler

Assuming that you have one webserver, and installed the Memacheserver on that same machine, the hostname will be 127.0.0.1. If you haveit on a different server, you will know what IP to substitute it with.

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

Done! Huh? what just happened?

Well, because we enabled Memcache session handler support, all work is done for us. PHP will now know not to use the default files handler so save session files in /var/lib/php5 but uses memcache running at 127.0.0.1 instead.

Don't forget to restart your webserver to activate your changes to the php.ini

/etc/init.d/apache2 restart

The Catch

Update - As Manuel de Ruiter says in the comments, the following is no longer true thanks to some updates

As with anything too cool, there is a catch: Locking. Thestandard PHP Session module locks the whole session until the requestfinishes. Memcache is build for speed and as a result, does not supportthis kind of locking. This could lead to problems when using frames orajax. Some actions may request a session-variable before it's actuallysaved.

Further reading

What we have just done with Memcache is the low-hanging fruit. We'veenabled RAM sessions with minimum effort and without changing even oneline of your existing code.

But now that you have memcache running, you might want to use it forstoring other often-used, rarely-changed variables as well. Feel free toexpiriment and review the documentation. You will learn that Memcache can enhance your serverside performance dramatically.