目录

为什么用 Redis 替代 Memcached 做 Session 共享

一、架构规划

二、环境前提

三、详细安装步骤

第1步:在 redis01 安装并配置 Redis

第2步:在 web01 和 web02 安装 LNMP 环境

第3步:配置 PHP-FPM Session 存储到 Redis

第4步:配置 Nginx 使用 PHP-FPM

第5步:测试 Session 共享


在分布式 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,这样 web01web02 的 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'];
?>

host51host52 分别访问:

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 共享生效

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐