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.

ITPUB
ITPUB
ITPUB
How to Share PHP Sessions Across Load‑Balanced Servers Using Redis

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.com111.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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

load balancingRedisPHPSession
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.