The DynamoDB Session Handler is a custom session handler for PHP that allows Amazon DynamoDB to be used as a session store while still using PHP’s native session functions.
The native PHP session handler stores sessions on the local file system. This is unreliable in distributed web applications, because the user may be routed to servers that do not contain the session data. To solve this problem, PHP developers have implemented custom solutions for storing user session data using databases, shared file systems, Memcache servers, tamper-proof cookies, etc., by taking advantage of the interface provided by PHP via the session_set_save_handler()
function. Unfortunately, most of these solutions require a lot of configuration or prior knowledge about the storage mechanism in order to setup. Some of them also require the provisioning or management of additional servers.
The DynamoDB Session Handler uses Amazon DynamoDB as a session store, which alleviates many of the problems with existing solutions. There are no additional servers to manage, and there is very little configuration required. The Amazon DynamoDB is also fundamentally designed for low latency (the data is even stored on SSDs), so the performance impact is much smaller when compared to other databases. Since the Session Handler is designed to be a drop in replacement for the default PHP session handler, it also implements session locking in a familiar way.
The first step is to instantiate the Amazon DynamoDB client and register the session handler.
require_once 'AWSSDKforPHP/sdk.class.php'; // Instantiate the Amazon DynamoDB client. // REMEMBER: You need to set 'default_cache_config' in your config.inc.php. $dynamodb = new AmazonDynamoDB(); // Register the DynamoDB Session Handler. $handler = $dynamodb->register_session_handler(array( 'table_name' => 'my-sessions-table' ));
Before you can use the session handler, you need to create a table to store the sessions in. This can be done through the AWS Console for Amazon DynamoDB, or using the session handler class (which you must configure with the table name like in the example above).
// Create a table for session storage with default settings. $handler->create_sessions_table();
If you create the table via the AWS Console, you need to make sure the primary key is a string. By default the DynamoDB Session Handler looks for a key named "id", so if you name the key something else, you will need to specify that when you configure the session handler (see the Configuration section below).
Once the session handler is registered with a valid table, you can write to (and read from) the session using the standard $_SESSION
superglobal.
// Start the session. This will acquire a lock if session locking is enabled. session_start(); // Alter the session data. $_SESSION['username'] = 'jeremy'; $_SESSION['role'] = 'admin'; // Close and write to the session. // REMEMBER: You should close the session ASAP to release the session lock. session_write_close();
The session handler ties into PHP's native session garbage collection functionality, so expired sessions will be deleted periodically and automatically based on how you configure PHP to do the garbage collection. See the PHP manual for the following PHP INI settings: session.gc_probability, session.gc_divisor, and session.gc_maxlifetime. You may also manually call the DynamoDBSessionHandler::garbage_collect()
to clean up the expired sessions.
You may configure the behavior of the session handler using a the following settings:
0
is used, then the actual lifetime value that will be used is ini_get('session.gc_maxlifetime')
.session_locking
is true
.session_locking
is true
.session_locking
is true
.To configure the Session Handle, you must pass the configuration data into the constructor. (Note: The values used below are actually the default settings.)
$dynamodb = new AmazonDynamoDB(); $handler = $dynamodb->register_session_handler(array( 'table_name' => 'sessions', 'hash_key' => 'id', 'session_lifetime' => 0, 'consistent_reads' => true, 'session_locking' => true, 'max_lock_wait_time' => 15, 'min_lock_retry_utime' => 5000, 'max_lock_retry_utime' => 50000, ));
The default session handler for PHP locks sessions using a pessimistic locking algorithm. If a request (process) opens a session for reading using the session_start()
function, it first acquires a lock. The lock is closed when that request writes back to the session, either when the request is complete, or via the session_write_close()
function. Since the DynamoDB Session Handler is meant to be a drop in replacement for the default session handler, it also implements the same locking scheme. However, this can be slow, undesirable, and costly when multiple, simultaneous requests from the same user occur, particularly with ajax requests or HTML iframes. In some cases, you may not want or need the session to be locked. After evaluating whether or not your application actually requires session locking, you may turn off locking when you configure the session handler by setting session_locking
to false
.
Aside from nominal data storage and data transfer fees, the costs associated with using Amazon DynamoDB are calculated based on provisioned throughput capacity and item size (see the Amazon DynamoDB pricing details). Throughput is measured in units of Read Capacity and Write Capacity. Ultimately, the throughput and costs required for your sessions table is going to be based on your website traffic, but the following is a list of the capacity units required for each session-related operation:
session_start()
With locking enabled: 1 unit of Write Capacity + 1 unit of Write Capacity for each time it must retry acquiring the lock
With locking disabed: 1 unit of Read Capacity (or 0.5 units of Read Capacity if consistent reads are disabled)
session_write_close()
1 unit of Write Capacity
session_destroy()
1 unit of Write Capacity
DyanamoDBSessionHandler::garbage_collect()
0.5 units of Read Capacity per KB of data in the sessions table + 1 unit of Write Capacity per expired item
For more information on the Amazon DynamoDB service please visit the Amazon DynamoDB homepage.