We get a lot of support tickets regarding slow and/or inaccessible writable directories. In just about every case, the culprit is the same — sessions. In this post, we’ll explain why storing sessions in writable storage can negatively affect your app’s performance and why Redis is the best alternative for session storage.
Important: By default, sessions are stored to tmp/pagoda/sessions, which is mounted as a shared writable directory. This was done to provide a session store out of the box whenever an app is created. In the near future, shared writable directories will not be created unless specifically defined in the Boxfile and this form of session storage will no longer be the default.
What you should understand about writable storage is that it is network storage provided through a cluster manager. Most file operations such as read, write, create, and delete are passed directly through to underlying storage nodes. In these cases your cluster manager acts as a network router on top of a multi Gb/s network. The overhead is isolated entirely to network throughput, which in most cases, is negligible on a multi-gigabit backbone.
When session_start() is called within the php interpreter, a stat() file operation is called for the sole purpose of determining whether the session file has recently changed. stat() operations force your cluster manager to compare hash checksums with all nodes that may have a copy of that file. This operation will also trigger a self-heal algorithm if your cluster has reason to believe any two nodes are out of sync. While this has little, if any, impact on the underlying storage nodes, the time required for your web process to wait for a stat response can result in serious queuing delays. Multiply this by however many sessions are being created, whether by a surge in traffic or an aggressive bot, and these queueing delays quickly turn into timeouts and/or complete unresponsiveness. A network file system is no place for session storage.
In-memory cache engines, like Memcached or Redis, are better suited to serve the role of a session store in a distributed environment. Out of the box, performance is significantly better and you don’t have to worry about the stat() overhead of a network file-store. Out of the two, we recommend using Redis over Memcached. The performance difference is negligible, but Redis routinely persists to disk, maintaining a certain level of data persistence in the event of an outage. Luckily, configuring your app to use Redis as a native PHP session-store is extremely simple.
Using Redis as a Session-Store on Pagoda Box
To start storing native PHP sessions in Redis, add a Redis component to your app and add the following to your Boxfile:
Note: if you have more than one Redis component in your application, the port will increment up from 6379.
Deploy the changes and and enjoy faster, more stable session storage. It’s really that simple.
Thanks for the post. I haven’t seen any issues yet but I’m happy to start using redis just in case.
Can you explain the last line ( php_session_save_path: “tcp://tunnel.pagodabox.com:6379″)?
I’m assuming that no changes are required to our current PHP session code?
Thanks!
Correct. The php_session_save_path is just telling php where to save the sessions. These are the connection details for your Redis component. You don’t have to modify any of your php session code.
Thanks for the tips!
However, when I try adding a redis cache engine, not only is it still in beta but there are no private clouds either… ?
BTW – still waiting to hop on the new dashboard… sent my request over a month ago and was told I’d be in by now.
Thanks!
Jad
Hey Jad, currently only cloud resources are available for cache components, but in the very new future, all components will have access to cloud, private cloud, and bare metal resources.
Sorry for the wait on the beta. Our previous post explains the delay.
@jad
Redis is still flagged as beta, but I’ve been using it in production for quite some time and not had any issues. In fact, my stability has improved by using it since redis is much harder to overwhelm with surges of traffic.
Could you advice how much ram we should allocate to a redis server for different levels of concurrent users? I’m wondering how many users I can support at the default 10mb level.
Do the session keys have a TTL set? I’m concerned about the data not being cleaned up efficiently.
The session length can be set in the Boxfile as well. 3600 seconds is the default.
php_session_length: "3600"Pingback: Pagoda Boxen | Bradezone