redis的phpredis扩展必须启用serialize且禁用igbinary,因多机部署下序列化协议不一致会导致unserialize错误;thinkphp默认用serialize,需统一php.ini中redis.serializer为php,禁用igbinary模块,配置中勿设serializer=igbinary。

Redis 的 phpredis 扩展必须启用 serialize 且禁用 igbinary
多机部署下,ThinkPHP 默认使用 serialize 序列化缓存数据;若某台机器启用了 igbinary(比如通过 redis.serializer = igbinary 配置),其他机器读取时会直接报 unserialize(): Error at offset —— 这不是 ThinkPHP 的 bug,而是序列化协议不一致导致的硬解失败。
- 确认所有节点的
php.ini中redis.serializer值统一为php(即默认) - 检查
php -m | grep redis和php --ri redis输出,确保没有启用igbinary模块或相关配置 - ThinkPHP 6+ 的
cache.php配置中不要手动设'serializer' => 'igbinary',它不兼容跨环境反序列化
Memcached 不支持自动集群同步,addServer() 不能替代一致性哈希
ThinkPHP 使用 Memcached 驱动时,常误以为调用多次 addServer() 就能实现“多节点共享缓存”。实际它只是客户端负载均衡(默认轮询),每个 key 固定落在某一台机器上 —— A 机写入的 user:1001,B 机根本查不到。
- 若坚持用 Memcached,必须在应用层做 key 显式路由,或改用
libketama+ 一致性哈希扩展(但 ThinkPHP 原生不支持) - 更现实的做法:换 Redis,或至少启用
Memcached::OPT_LIBKETAMA_COMPATIBLE并配好服务端memcached -b启动参数 - 注意 ThinkPHP 的
memcached驱动默认不开启OPT_LIBKETAMA_COMPATIBLE,需在配置里显式加'options' => [Memcached::OPT_LIBKETAMA_COMPATIBLE => true]
think cache:clear 命令只清本机缓存,分布式场景下完全无效
执行 php think cache:clear 时,ThinkPHP 只会连接当前配置的 Redis/Memcached 实例,删掉那个节点上的 key。其他机器的缓存照旧存在,导致“刚清完缓存,页面还是旧内容”。
- 上线或配置变更时,必须手动连每台缓存服务器执行
FLUSHDB(Redis)或重启 memcached 进程(Memcached) - 生产环境建议用带前缀的缓存键(如
tp6:v2:user:1001),通过KEYS tp6:v2:*+DEL批量清理,避免误删其他系统缓存 - ThinkPHP 本身不提供跨节点广播清缓存机制,别依赖命令行工具做分布式清理
Redis 主从架构下,ThinkPHP 写操作可能读到过期数据
当 Redis 配置了主从(比如主写、从读),ThinkPHP 的 Redis 缓存驱动默认走 readwrite 模式,但它的读操作不保证打到主节点 —— 尤其是 get、has 这类方法,默认走从库。而主从同步有延迟,刚 set 完立刻 get 可能返回空或旧值。
- 对强一致性要求高的场景(如登录态、库存扣减),必须强制读主:在配置中设
'read_write_separation' => false - 若启用了读写分离,
set后立即get要加sleep(0.01)或重试逻辑(不推荐,治标不治本) - Redis Cluster 模式下,ThinkPHP 原生驱动不支持,需自行封装
Predis\Client或切换至redis-cluster驱动扩展
缓存同步本质是数据一致性问题,不是配置开关能一键解决的。最容易被忽略的是序列化协议和主从延迟这两点——它们不会报错,只会悄悄返回错误结果。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










