Redis 替代 Memcached:实现 PHP Session 分布式共享
目录
为什么用 Redis 替代 Memcached 做 Session 共享
第2步:在 web01 和 web02 安装 LNMP 环境
第3步:配置 PHP-FPM Session 存储到 Redis
在分布式 Web 架构中,当我们部署多台 Web 服务器(如 Nginx + PHP-FPM)时,每台服务器都会独立维护自己的 Session 文件。如果没有统一的 Session 存储,当用户的请求被负载均衡到不同节点时,Session 信息就会丢失,导致用户登录状态异常、购物车清空等问题。
为了解决这一痛点,我们通常会使用 集中式 Session 存储。
早期常用 Memcached,但如今更多人选择 Redis——它性能更高、支持持久化、结构更丰富,非常适合做 Session 共享。
本文将以 CentOS 7 为例,介绍如何使用 YUM 安装 PHP + PHP-FPM + Redis,并实现多台 Web 节点之间的 Session 共享,确保用户无论被分配到哪台服务器,都能保持同一个登录状态。
为什么用 Redis 替代 Memcached 做 Session 共享
| 对比项 | Memcached | Redis |
|---|---|---|
| 数据类型 | 仅支持字符串 | 支持多种类型(String、Hash、List、Set等) |
| 持久化 | 不支持 | 支持(RDB、AOF) |
| 主从复制 | 较麻烦 | 支持完善(Redis Sentinel、Cluster) |
| 脚本扩展 | 不支持 | 支持 Lua 脚本 |
| 性能 | 极高 | 略低,但差距不大 |
一、架构规划
| 主机 | 角色 | 示例 IP | 主要功能 |
|---|---|---|---|
| host51 | Nginx + PHP-FPM | 192.168.4.51 | Web 应用节点1 |
| host52 | Nginx + PHP-FPM | 192.168.4.52 | Web 应用节点2 |
redis01 |
Redis Server | 192.168.4.57 | Session 存储中心 |
当用户访问负载均衡(或直接访问任意 web 节点),PHP 把会话信息存入 Redis,这样 web01 和 web02 的 session 是共享的。
二、环境前提
三台服务器系统版本:
CentOS 7
需要有:
-
root 权限
-
各节点互通(ping 通)
-
同步时间(建议开启 chronyd 或 ntp)
-
防火墙可选择关闭
三、详细安装步骤
第1步:在 redis01 安装并配置 Redis
[root@redis01 ~]# yum -y install gcc
[root@redis01 ~]# tar -zxvf redis-4.0.8.tar.gz
[root@redis01 ~]# cd redis-4.0.8/
[root@redis01 redis-4.0.8]# make && make install
[root@redis01 redis-4.0.8]# ./utils/install_server.sh 一路回车即可
也可以直接用yum进行安装
yum install -y redis
编辑 /etc/redis/6379.conf:
bind 0.0.0.0 # 允许外网访问
protected-mode no # 禁用保护模式
requirepass 123456 # 设置密码
注:如果你使用的yum源进行安装,则修改/etc/redis.conf,后续起服务也是直接用systemctl启动
启动 Redis:
[root@redis01 ~]# ss -antulp | grep redis 看一下是否启用了6379端口,没有的话再进行启动
[root@redis01 ~]# /etc/init.d/redis_6379 start
测试:
[root@redis01 ~]# redis-cli -a 123456 ping
# 输出 PONG 表示成功
第2步:在 web01 和 web02 安装 LNMP 环境
这里我们用最简单的方式,只部署 Nginx + PHP(MySQL 不影响 session 共享)
[root@redis01 ~]# yum install -y nginx php php-fpm php-redis
第3步:配置 PHP-FPM Session 存储到 Redis
编辑 FPM pool 配置 /etc/php-fpm.d/www.conf:
host51和host52都要配置
; Redis session 配置
php_value[session.save_handler] = redis
php_value[session.save_path] = "tcp://192.168.4.57:6379?auth=123456"
本来我是选择在/etc/php.ini上配的,结果发现配置之后重启服务session配置依然没生效,所以选择在FPM pool配置,直接就生效了
注意:
-
Redis IP 和密码要和你的 Redis 服务器一致
-
引号必须是英文双引号
重启 PHP-FPM:
[root@host51 ~]# systemctl restart php-fpm
[root@host51 ~]# systemctl restart nginx
第4步:配置 Nginx 使用 PHP-FPM
编辑 /etc/nginx/conf.d/default.conf 或自建 server 块:
host51和host52都要配置
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
[root@host51 ~]# systemctl restart nginx
第5步:测试 Session 共享
创建 /usr/share/nginx/html/test_session.php:
<?php
session_start();
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 1;
} else {
$_SESSION['count']++;
}
echo "Session ID: " . session_id() . "<br>";
echo "Count: " . $_SESSION['count'];
?>
在 host51 和 host52 分别访问:
curl http://192.168.4.51/test_session.php
curl http://192.168.4.52/test_session.php


登录 Redis 检查:
[root@redis01 ~]# redis-cli -a 123456
127.0.0.1:6379> keys *
1) "PHPREDIS_SESSION:tjrlulc951hpuh57cfhfca0ij5"
2) "PHPREDIS_SESSION:e2334a19a9hi3k2ednlgckrls4"
可以看到Redis 已经成功写入 PHP Session
但是两个的session ID不同,当时我以为是session没有成功共享,但是经过一系列验证后都没有问题,最后终于找到了原因
因为我用的是curl命令,每次 curl 都是新的请求,没有带上上一次的 PHPSESSID,所以 FPM 生成新 Session
所以这里使用同一个浏览器 Cookie:
[root@host51 ~]# curl http://192.168.4.51/test_session.php
Session ID: 7adpmoo2vkskebt8l9ce6umc21<br>Count: 1
[root@host52 ~]# curl -b "PHPSESSID=7adpmoo2vkskebt8l9ce6umc21" http://192.168.4.52/Session ID: 7adpmoo2vkskebt8l9ce6umc21<br>Count: 2
可以看到host52输出了相同的session ID,且输出 Count 会递增,说明 Session 共享生效
更多推荐
所有评论(0)