AWS DynamoDB For Session Redundancy And Failover

This article will go over what DynamoDB is and how we use it to backup our session data. It allows us to failover from one datacenter (AWS region) to another without losing session data and logging people out of our system.

Amazon Web Services (AWS) DynamoDB

DynamoDB is a cloud NoSQL database hosted by Amazon. You simply create a table and set the read/write capacity you want and Amazon takes care of the rest. No servers to manage or scale. Pretty awesome. Actually it’s so awesome that Amazon DynamoDB is the fastest growing new service in the history of AWS.

What’s is DynamoDB good at?

  • No hassle data store that is performant, scalable, and reliable.
  • Quick reads/writes. You decide the performance you need and pay for that.
  • Relatively cheap.
  • Access data via a key.
  • Store data that is in the 1-10KB range per item (you can store more but it gets expensive).

What’s does DynamoDB suck at?

  • It’s not a relational database. You can’t query it with joins or complex selects.
  • It’s not as fast as memcache (in our experience).
  • For large items or extremely high throughput it can get expensive (compared to running your own memcache service for example).
  • There is no simple way to back up your data (they do have a process by which you can get data to S3 but it’s pretty complicated and involves two other totally separate services from AWS).

Where can you read more about DynamoDB?

Using DynamoDB For Session Backup

In the blog post Scalable Session Handling in PHP Using Amazon DynamoDB they cover how to implement session handling for PHP using DynamoDB. I experimented with this, but what I found was it was too slow for our needs. Our session reads with DynamoDB were taking 20+ms. Our memcache session reads are an order of magnitude faster than that. We also already have memcache session handling implemented and working beautifully.

Why Do We Need To Backup Our Sessions?

For some applications it might be acceptable to log everyone out if you failed from one datacenter to another (heck lots of applications run in only one datacenter and don’t have any failover). Our application is mission critical for our customers – if we’re down they’re losing money. We run completely redundant setups in two different AWS regions on EC2.

If there’s a problem we have to switch customers from one datacenter to the other. Not having the sessions backed up in a way that both datacenters can access would mean everyone using our system would be logged out. This is a real hassle for our users because sometimes the stores are operating with a manager login and associates just have PINs to switch to their profile. If they get logged out they have to have the manager come by and log back in. What if the manager is out on lunch? Out of luck.

We previously stored our session backup in our MySQL database. But this became unscalable as the number of concurrent sessions grew. A few months ago we turned off our MySQL session storage and have been running just on memcache sessions. It improved performance, but it meant we might log everyone out if we had to switch datacenters.

DynamoDB To The Rescue

I looked at a number of different NoSQL type solutions for our session backup. DynamoDB made it to the top of the list because of it’s easy of management, scalability and price.

The basic concept is:

  • Session are stored and read from Memcache (every page hit)
  • Every 15 minutes we write the session to DynamoDB (each session stores its time since last DynamoDB write)
  • If we can’t find a session in Memcache (datacenter failure, or Memcache reboot) we look for it in DynamoDB.
  • Result: Users aren’t logged out if we switch datacenters or reboot Memcache.

DynamoDB PHP Code Samples

I gleaned a lot of this code from AWS blog post on PHP DynamoDB sessions.

readDynamoDB

This reads our session data out of DynamoDB when we need it. We call this from our custom session reading function (see session_set_save_handler)

[php]
function readDynamoDB($ses_id)
{
$this->initDynamoDB();
$result = ”;
$response = $this->_dynamodb->get_item(
array( ‘TableName’ => self::DYNAMODB_TABLE,
‘Key’ => array(‘HashKeyElement’ => $this->_dynamodb->attribute($ses_id)),
‘ConsistentRead’ => true, )
);

$node_name = ‘Item’;
if ($response->isOK())
{
$item = array();
// Get the data from the DynamoDB response
if ($response->body->{$node_name})
{
foreach ($response->body->{$node_name}->children() as $key => $value)
{
$item[$key] = (string) current($value);
}
}
if (isset($item['expires']) && isset($item['data']))
{
// Check the expiration date before using
if ($item['expires'] > time())
{
$result = $item['data'];
}
else
{
$this->deleteDynamoDB($ses_id);
}
}
}
return $result;
}[/php]

writeDynamoDB

This reads our session data out of DynamoDB when we need it. We call this from our custom session reading function (see session_set_save_handler)
[php]function writeDynamoDB($ses_id,$data,$expire_minutes)
{
$this->initDynamoDB();
// Write the session data to DynamoDB
$response = $this->_dynamodb->put_item(
array( ‘TableName’ => self::DYNAMODB_TABLE,
‘Item’ => $this->_dynamodb->attributes(
array( self::DYNAMODB_HASH => $ses_id,
‘expires’ => time() + ($expire_minutes*60),
‘data’ => $data,
)
),
)
);
return $response->isOK();
}[/php]

deleteDynamoDB

This delete our session data from DynamoDB when we are done with it. We call this from our custom session destroy and gc function (see session_set_save_handler)
[php]function deleteDynamoDB($ses_id)
{
$this->initDynamoDB();
$delete_options = array( ‘TableName’ => self::DYNAMODB_TABLE,
‘Key’ => array(‘HashKeyElement’ => $this->_dynamodb->attribute($ses_id)),
);
// Send the delete request to DynamoDB
$response = $this->_dynamodb->delete_item($delete_options);
return $response->isOK();
}[/php]

10 thoughts on “AWS DynamoDB For Session Redundancy And Failover

  1. kevin said...

    how does this help you across regions? are you writing to two regions at a time?

    On
  2. You can access DynamoDB across regions. So if you have DynamoDB running in East, you can access it from West. We thought about writing to both regions at once for even more redundancy, but it seemed like diminishing returns. This at least keeps us from logging users out if we switch reasons for a more minor reason. If we switch because the entire Amazon region went offline, then our users would get logged out. But this is very rare, so a logout in that situation is acceptable.

    On
  3. james said...

    So you have to ensure that connections arrive at the same server since sessions aren’t backed up for the first 15 mins? i.e if server1 created a session and stored it in it’s memcache, server2 cannot see the session information until after 15 mins. So, you have to somehow make sure that the user connection always lands in server1.

    On
  4. Memcache is distributed, so all the web servers are accessing the same pool of memcache servers (or a single memcache server). So there are no issues like that. If you have multiple web servers but each is only accessing a localhost memcache, then you’ll have the problem your talking about, but that’s not the normal way memcache is used.

    On
  5. Hi Justin,

    I was wondering if you ever did a cost analysis of storing sessions in DynamoDB vs in memory-sessions? I am currently working on a similar solution and wanted to get someone’s opinion on this.

    –Akhil

    On
  6. Akhill, What type of in memory sessions? Like memcache?

    On
  7. I was actually referring to in-memory sessions that are stored in, lets say, JVM heap and distributed via session replication.

    I am not referring to AWS elasticache(This seems very expensive from a small experiment standpoint)

    On
  8. We’re using PHP, so I didn’t investigate options with JVM etc. I haven’t heard many people using in memory session replication with PHP. Maybe it’s more common with Java.

    On
  9. Ramesh Moorthy said...

    Hi,
    If online mode, I can delete a session data’s easily, because I can get a session hash key id. But I can’t get a expired session data’s in offline mode. So how can I delete the expired session data’s in offline mode?

    On
  10. I’m not sure what you mean. If you issue a user a new session id then they will no longer be linked to that session data.

    On

Leave a Reply

Your email address will not be published. Required fields are marked *