Full-service Internet Marketing & Web Development
Recent Posts

Sponsors
![]() |
Memcached for PHP SessionsDawn Rossi, 10-14-2008 |
Sessions are a great way to store data pertaining to a single end-user browsing through your site, before the user logged in.
Each user is assigned a unique ID and that ID serves as the key to a dataset, where you can store the user name, email address, referral, affiliate_id etc.
Since sessions are accessed on every page load, it is important to optimize the amount of time it takes to read/write sessions.
PHP sessions can typically be stored as either files or database records.
Files are fast, but don't allow you to scale beyond a single server.
Database records support scaling but are "expensive" to read/write.
As part of this post, I will walk you through the process of using Memcached for PHP sessions.
Memcached is a very efficient in-memory database that supports scaling to multiple machines, expiration and built-in garbage collection. We're going to hit Memcached first on all session queries. If we don't have a match, we read it from the database (once) and store the information into Memcached for later fast retrieval.
Step 1: Install Memcached
Step 2: We're going to use PHP function overrides feature and define new session handling functions. Save dbsession.php in your includes directory and replace all references to "payments" with the name of your global database.
Step 3: Create the sessions table under your global database:
CREATE TABLE sessions (
session_expire int(11) unsigned NOT NULL DEFAULT '0',
session_value longtext,
session_key char(32) NOT NULL DEFAULT '',
PRIMARY KEY (session_key)
)
Step 4: Save common_cache.php under your includes directory. This file is used by dbsession.php and serves as the wrapper class for accessing the Memcached server. Update the array at the top of common_cache.php with the ip addresses of your Memcached servers. You can have multiple Memcached servers and as long as they're all aware of each other, everything will scale gracefully.
Step 5: Include dbsession.php at the top of your php files (or add it to one of your global includes that is included everywhere). Make sure you include dbsession.php before the first call to session_start
All it takes is a single include at the top of your php files and voila - all sessions are now handled by Memcached first, then reverting to the database if no match found.
require_once("dbsession.php");
Each user is assigned a unique ID and that ID serves as the key to a dataset, where you can store the user name, email address, referral, affiliate_id etc.
Since sessions are accessed on every page load, it is important to optimize the amount of time it takes to read/write sessions.
PHP sessions can typically be stored as either files or database records.
Files are fast, but don't allow you to scale beyond a single server.
Database records support scaling but are "expensive" to read/write.
As part of this post, I will walk you through the process of using Memcached for PHP sessions.
Memcached is a very efficient in-memory database that supports scaling to multiple machines, expiration and built-in garbage collection. We're going to hit Memcached first on all session queries. If we don't have a match, we read it from the database (once) and store the information into Memcached for later fast retrieval.
Step 1: Install Memcached
Step 2: We're going to use PHP function overrides feature and define new session handling functions. Save dbsession.php in your includes directory and replace all references to "payments" with the name of your global database.
Step 3: Create the sessions table under your global database:
CREATE TABLE sessions (
session_expire int(11) unsigned NOT NULL DEFAULT '0',
session_value longtext,
session_key char(32) NOT NULL DEFAULT '',
PRIMARY KEY (session_key)
)
Step 4: Save common_cache.php under your includes directory. This file is used by dbsession.php and serves as the wrapper class for accessing the Memcached server. Update the array at the top of common_cache.php with the ip addresses of your Memcached servers. You can have multiple Memcached servers and as long as they're all aware of each other, everything will scale gracefully.
Step 5: Include dbsession.php at the top of your php files (or add it to one of your global includes that is included everywhere). Make sure you include dbsession.php before the first call to session_start
All it takes is a single include at the top of your php files and voila - all sessions are now handled by Memcached first, then reverting to the database if no match found.
require_once("dbsession.php");
![]() |
James, 10-20-2008 |
This article confuses me. Why on earth try re-inventing the wheel and writing your own session handler for memcache when you can use the one that the PECL memcache module ships with?
if(MEMCACHE_HAVE_SESSION) {
ini_set('session.save_handler','memcache');
ini_set('session.save_path', <session save path info>);
} else {
// fall back to a db session
}
Unfortunately I don't think that the author has a firm grasp of memcached and/or sessions.
if(MEMCACHE_HAVE_SESSION) {
ini_set('session.save_handler','memcache');
ini_set('session.save_path', <session save path info>);
} else {
// fall back to a db session
}
Unfortunately I don't think that the author has a firm grasp of memcached and/or sessions.
![]() |
George, 10-24-2008 |
James,
Your approach would fall back to a db session upon a memcache miss. It doesn't handle reading data from the db, and updating memcache to retain the speed advantage of using memcache. Dawn's approach is designed to use memcache in all instances and update the memcache contents from db in the case of a cache miss. The session handler in the PECL memcache does not do this.
Your approach would fall back to a db session upon a memcache miss. It doesn't handle reading data from the db, and updating memcache to retain the speed advantage of using memcache. Dawn's approach is designed to use memcache in all instances and update the memcache contents from db in the case of a cache miss. The session handler in the PECL memcache does not do this.
![]() |
Dawn Rossi, 10-31-2008 |
Thank you George,
You got it!
We have been implementing Memcached for PHP sessions for a few years now. I'd like to think we know a thing or two about how to get the most out of Memcached.
You got it!
We have been implementing Memcached for PHP sessions for a few years now. I'd like to think we know a thing or two about how to get the most out of Memcached.
![]() |
Sung, 11-17-2008 |
Functions in common_cache.php doesn't seem to be used in dbsession.php. For example, who calls mcache_connect()? Could you give me an explanation kindly?
![]() |
Sung, 11-18-2008 |
One more thing.
Whenever a client JUST reads session variable, sessionWrite() is called to update session expiration time. Thus, it seems that this rarely utilizes memcached.
Whenever a client JUST reads session variable, sessionWrite() is called to update session expiration time. Thus, it seems that this rarely utilizes memcached.
![]() |
Caner, 12-17-2008 |
Can we use this method on a multi-server architecture?
![]() |
John, 04-17-2009 |
We are using this exact same approach for our session handling using memcached. it's working brilliantly. However, we are receiving the occasional random logout. As if memcached returned true but didn't actually have the sessionid stored. Has this ever happened to you? Here is an example of our session read() function:
function read($sessionID) {
$db =& $this->_db;
$cache =& $this->_cache;
if($cache->get(CACHE_SESSION . $sessionID) !== false) {
return $cache->get(CACHE_SESSION . $sessionID);
} else {
$sql = "SELECT value FROM session WHERE sessionid = ? AND expiration > ?";
return $db->getOne($sql, array($sessionID, time()));
}
}
function read($sessionID) {
$db =& $this->_db;
$cache =& $this->_cache;
if($cache->get(CACHE_SESSION . $sessionID) !== false) {
return $cache->get(CACHE_SESSION . $sessionID);
} else {
$sql = "SELECT value FROM session WHERE sessionid = ? AND expiration > ?";
return $db->getOne($sql, array($sessionID, time()));
}
}
![]() |
Phil, 05-03-2009 |
Interesting article, however wouldn't the fact you are still doing at least a write to the database every time kinda defeat the object of using memcache? That database write will always be the bottleneck for this script. The PECL memcache package supports writing PHP sessions to multiple memcache servers which is probably best for a redundant solution.
![]() |
Mike Peters, 06-09-2009 |
Caner -
Absolutely. This approach is specifically designed to support multi server architecture.
John -
We're not seeing any issues with this method. You may want to check your code and make sure you are calling session set save handler in all places. Otherwise, your web server will be reverting to 'files' session handling. That could possibly explain what you're seeing.
Phil -
Memcached is first checked for the session value. If Memcached has it, no db access is ever initiated.
Absolutely. This approach is specifically designed to support multi server architecture.
John -
We're not seeing any issues with this method. You may want to check your code and make sure you are calling session set save handler in all places. Otherwise, your web server will be reverting to 'files' session handling. That could possibly explain what you're seeing.
Phil -
Memcached is first checked for the session value. If Memcached has it, no db access is ever initiated.
![]() |
Mike, 06-23-2009 |
Do you think we can have an example of using this ?
As in a test login form maybe with the test table for logins/etc
As in a test login form maybe with the test table for logins/etc
|
|
Subscribe Now to receive new posts via Email as soon as they come out.
Comments
Post your comments










