How to Share PHP Sessions Across Load‑Balanced Servers Using Redis
This guide explains the session‑sharing problem caused by load balancing, introduces Redis as a shared storage solution, and provides step‑by‑step instructions—including php.ini changes, runtime ini_set calls, and a custom session‑handler class—to configure PHP to store sessions in Redis, with code examples and verification commands.
Load Balancing and Session Sharing Problem
Load balancing distributes incoming requests across multiple servers to reduce individual server load. When the same domain resolves to different IPs (e.g., www.baidu.com → 111.13.101.208 then 111.13.101.209), each server maintains its own PHP session. Users experience repeated logins because the session data is not shared.
Redis Overview
Redis is a key‑value, non‑relational database that supports persistence (RDB full snapshots and AOF incremental logs), five data types (string, hash, list, set, zset), and both in‑memory and disk storage. It is commonly used for shared session storage in multi‑server environments.
Core Idea: Shared Session via Redis
Because the browser sends the same cookie regardless of which backend server handles the request, storing the session data in a single Redis instance (or cluster) ensures that all servers can retrieve the same session using the cookie as the key.
Configure PHP to Use Redis for Sessions
There are three ways to switch PHP’s session handler from the default file‑based storage to Redis.
1. Modify php.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"2. Set at runtime with ini_set
ini_set("session.save_handler", "redis");
ini_set("session.save_path", "tcp://127.0.0.1:6379");If the Redis server requires a password (e.g., requirepass in redis.conf), append ?auth=yourpwd to the path.
3. Use a Custom Session‑Handler Class
The class redisSession implements the required session handler methods ( open, close, read, write, destroy, gc) and connects to Redis using the provided host, port, and lifetime settings.
class redisSession {
private $_options = array(
'handler' => null,
'host' => null,
'port' => null,
'lifeTime' => null,
'prefix' => 'PHPREDIS_SESSION:'
);
public function __construct($options = array()) {
if (!class_exists('Redis', false)) {
die("必须安装redis扩展");
}
if (!isset($options['lifeTime']) || $options['lifeTime'] <= 0) {
$options['lifeTime'] = ini_get('session.gc_maxlifetime');
}
$this->_options = array_merge($this->_options, $options);
}
public function begin() {
if ($this->_options['host'] === null || $this->_options['port'] === null) {
return false;
}
$redis = new Redis();
$redis->connect($this->_options['host'], $this->_options['port']);
$this->_options['handler'] = $redis;
return true;
}
public function open($savePath, $sessionName) {
if (is_resource($this->_options['handler'])) return true;
$redis = new Redis();
$redis->connect($this->_options['host'], $this->_options['port']);
$this->_options['handler'] = $redis;
return true;
}
public function read($sessionId) {
$key = $this->_options['prefix'] . $sessionId;
return $this->_options['handler']->get($key);
}
public function write($sessionId, $sessionData) {
$key = $this->_options['prefix'] . $sessionId;
return $this->_options['handler']->setex($key, $this->_options['lifeTime'], $sessionData);
}
public function destroy($sessionId) {
$key = $this->_options['prefix'] . $sessionId;
return $this->_options['handler']->delete($key) >= 1;
}
public function close() {
return $this->_options['handler']->close();
}
public function gc($lifeTime) {
return true; // Redis handles expiration automatically
}
}Initialization (init.php)
<?php
require_once "redisSession.php";
$handler = new redisSession(array(
'host' => '127.0.0.1',
'port' => '6379'
));
$handler->begin();
session_start();
?>Test Script (test.php)
<?php
include "init.php";
$_SESSION['isex'] = "Hello";
$_SESSION['sex'] = "Corwien";
print_r($_SESSION);
?>Running test.php creates a session key in Redis such as PHPREDIS_SESSION:29a111bcs120sv48ibmmjqdag4. The stored value is a serialized string containing both session variables.
Verification via Redis CLI:
127.0.0.1:6379> get PHPREDIS_SESSION:29a111bcs120sv48ibmmjqdag4
"sex|s:7:\"Corwien\";isex|s:5:\"Hello\";"Thus the session data is successfully shared across all load‑balanced servers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
