必须使用支持Redis Cluster协议的客户端(如predis)实现多Web节点会话共享,禁用单点连接;需验证集群拓扑、开放全部master节点端口,并按框架规范配置集群地址与参数。

在PHP框架(如Laravel、ThinkPHP、CodeIgniter)部署于多台Web服务器并接入Redis集群时,必须确保所有节点读写同一份会话数据,否则用户在负载均衡切换后会话丢失、登录态中断、购物车清空。这要求Session存储层具备高可用、自动故障转移与数据一致性能力,不能仅依赖单点Redis实例。
确认Redis集群拓扑与连接方式
先验证Redis是否已构成真正意义上的集群(非主从哨兵),运行redis-cli -c -h 192.168.1.40 -p 6379 cluster nodes。输出中应包含多个master节点、slot分配信息及connected状态。若返回(error) CLUSTERDOWN或仅显示单个节点,则当前是单机或哨兵模式,不满足集群会话共享前提。
集群地址不能写成tcp://192.168.1.41:6379这种单点形式——PHP的redis扩展原生不支持集群自动重定向。必须使用支持Cluster协议的客户端,例如phpredis扩展需启用redis.cluster配置项,或改用predis/predis这类纯PHP实现库。
【关键前提】 所有Web服务器必须能同时访问集群全部master节点IP(如192.168.1.41、192.168.1.42、192.168.1.43),且防火墙放行各节点6379端口。仅连VIP(192.168.1.40)无法触发集群路由逻辑。
立即学习“PHP免费学习笔记(深入)”;
PHP框架适配Redis集群的三种方法
方法一:使用predis库接管Session Handler(推荐)
1. 在项目根目录执行composer require predis/predis安装客户端
2. 创建app/Session/RedisClusterHandler.php,继承SessionHandlerInterface,内部用Predis\Client连接集群:
构造时传入节点数组['tcp://192.168.1.41:6379', 'tcp://192.168.1.42:6379', 'tcp://192.168.1.43:6379'],并设置'cluster' => 'redis'选项启用集群模式
3. 在框架入口或中间件中调用session_set_save_handler(new RedisClusterHandler(), true),再执行session_start()
注意:predis默认不启用密码认证,若集群节点设置了requirepass,需在每个节点URL后追加?auth=yourpwd
方法二:ThinkPHP6专用配置(无需编码)
1. 修改config/session.php,将'type'设为'cache','store'设为'redis'
2. 在config/cache.php的'redis'驱动下,把'host'改为数组:'host' => ['192.168.1.41', '192.168.1.42', '192.168.1.43'],
并添加'cluster' => 'redis'键值对
【易错点】 TP6的redis缓存驱动仅当'cluster'存在且值为'redis'时才启用集群模式,写成'cluster' => true无效。
方法三:Laravel通过.env强制走集群(覆盖默认Redis Facade)
1. 在.env中删除REDIS_HOST单点配置,改为定义多个节点:REDIS_CLUSTER_1=192.168.1.41:6379REDIS_CLUSTER_2=192.168.1.42:6379REDIS_CLUSTER_3=192.168.1.43:6379
2. 修改config/database.php的redis段,用'clusters'键替代'client':
在'clusters'数组内声明'default'子项,其'servers'值为array_map('env', ['REDIS_CLUSTER_1', 'REDIS_CLUSTER_2', 'REDIS_CLUSTER_3'])
3. 确保SESSION_DRIVER=redis且REDIS_CLIENT=predis(Laravel 9+默认使用phpredis,但phpredis不支持原生集群,必须切predis)
验证会话是否真正跨节点生效
第一步:在任意Web服务器上部署测试脚本test_session.php:
<?php session_start(); $_SESSION['test_key'] = uniqid(); echo $_SESSION['test_key']; ?>
第二步:用curl分别请求三台服务器的该脚本,记录返回的PHPSESSID Cookie和输出字符串
第三步:用redis-cli逐个连接三个集群节点,执行get "PHPREDIS_SESSION:{session_id}",确认同一session_id只在一个节点命中数据(符合集群slot分配规则),且内容与脚本输出一致
第四步:在另一台服务器发起带该Cookie的请求,检查$_SESSION['test_key']能否正确读取——若读取失败,说明Session未被集群路由到对应slot节点,需检查predis配置中的parameters是否遗漏'cluster' => 'redis'



















