thinkphp 6 万级并发下需用 redishash 驱动替代默认 session,隔离 session/cache 前缀,并彻底关闭 php 原生 session 机制。

ThinkPHP 6 在万级并发下用 Redis 替代默认 Session,核心不是“能不能连上 Redis”,而是让会话数据真正可伸缩、可原子更新、不掉状态。关键在于三点:驱动类型必须用 RedisHash(而非原生 Redis 字符串驱动),前缀必须与缓存隔离,且 PHP 原生 session 机制必须彻底关闭。
确认 Redis 扩展与连接可用
先确保底层通路没问题:
- 执行
php -m | grep redis,输出必须含redis(注意是 phpredis,不是 predis);若无,需安装 phpredis 扩展并重启 PHP 进程 - 检查
config/cache.php中stores.redis配置:host、port、password(为空必须显式写null)、database、timeout 都要准确;特殊字符密码需 URL 编码 - 运行
php think run后,在控制器中执行dump(cache()->store('redis')->handler()),应返回 Redis 实例对象,不能是null或报错
改用 RedisHash 驱动支持字段级更新
默认 Redis Session 用 STRING 存整个序列化数据,高并发下每次刷新登录时间都要反序列化→改→再序列化,锁竞争大、CPU 消耗高。换成 HASH 类型后,可直接 HSET sess:abc last_login_time "1723890240",无需读取全量数据。
- 在
app/extend/Driver/Session/RedisHash.php创建驱动类,继承think\session\driver\Redis -
write()方法里调用$cache->hSet($key, 'data', $serialized),并单独设 TTL -
read()方法只取hGet($key, 'data'),解序列化后返回 - 修改
config/session.php的'type' => 'redis_hash',并注册该驱动(如通过服务提供者或自动加载)
严格隔离 Session 与 Cache 的 Redis Key 前缀
这是万并发下不误删、不冲突的底线规则:
- Session 前缀配在
config/session.php的'redis' => ['prefix' => 'sess:'] - Cache 前缀配在
config/cache.php的'stores.redis.prefix' => 'cache:' - 绝对不要共用前缀(比如都用
tp6:),否则FLUSHDB或运维脚本一执行,所有用户瞬间登出 - 过期时间由
session.max_lifetime控制(单位秒),PHP 的session.gc_maxlifetime对 Redis 驱动无效
关闭 PHP 原生 Session 机制
这是最常被忽略却导致“明明写了 Redis 却还是掉登录态”的根本原因:
- 确保 PHP 配置中
session.use_trans_sid = Off、session.auto_start = Off(TP6 不会帮你关) - 检查项目中有没有
ini_set('session.save_handler', 'files')这类硬编码,尤其在中间件或公共函数里,必须删掉或注释 - 前后端分离场景下,还要确认前端请求带了
withCredentials: true,后端 CORS 配置允许凭据(Access-Control-Allow-Credentials: true),否则 Cookie 不会发送
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











