Redis写入字节报错无法缓存,跨函数调用Cache::remember是否为最佳实践
问题1:跨函数通过Cache::remember访问同key缓存是否为最佳实践
该模式本身是合法的缓存复用方式,但你的当前实现存在严重问题,不符合最佳实践:
- 同一个key存储了完全不同类型的数据:第一个函数里
all_clients_number存储的是调用get()返回的Collection集合实例,第二个过滤函数中同一个key存储的是未调用get()的QueryBuilder查询构造器实例,完全违背了缓存key与业务含义唯一对应的原则。 - 权限相关的缓存key未做用户隔离:你当前合伙人角色使用的
all_partner_clients_number是全局key,不同合伙人登录时会互相覆盖缓存,导致其他合伙人拿到不属于自己的数据。 - 硬编码缓存key容易出错:建议将常用缓存key定义为全局常量,避免不同位置拼写错误导致缓存无法命中或者写入错误key。
问题2:Redis无法写入的常见原因
你当前代码的直接报错原因就是第二个函数缓存写入的是QueryBuilder实例,该实例包含PDO数据库连接等不可序列化的资源,序列化失败导致无法写入Redis,你只需要在第二个函数的闭包最后加上->get()返回集合即可解决大部分问题。
其他可能的原因包括:
- Redis服务配置的
maxmemory上限已满,且配置的内存淘汰策略不允许写入新数据 - Laravel的Redis配置有误,比如未配置正确的密码、数据库编号,或者客户端连接超时设置过短
- Redis持久化文件所在磁盘已满,或者Redis进程没有持久化文件的写入权限
- 你存储的其他缓存数据存在不可序列化的内容,比如请求实例、连接实例等
Redis缓存高效使用建议
- 仅缓存可序列化的纯数据:禁止存储查询构造器、连接对象、请求对象等包含不可序列化资源的实例,优先缓存标量、数组、Eloquent集合这类轻量数据
- 缓存key设计要唯一:与用户、权限、租户相关的缓存必须在key中拼接唯一标识,比如合伙人缓存key可以写成
all_partner_clients_number_{partner_id},避免数据串用 - 优先缓存最终计算结果:如果你的业务只需要求和结果,直接缓存sum的数值即可,不需要缓存整个数据集再二次计算,大幅降低缓存占用和计算开销
- 合理设置缓存过期时间:按业务数据的更新频率设置TTL,不要统一设置过长的过期时间,避免脏数据;热点key的过期时间可以增加随机偏移值,避免缓存雪崩
- 做好异常兜底:缓存读取、写入失败时要有降级逻辑,直接走数据库查询,避免缓存故障直接导致业务报错
内容的提问来源于stack exchange,提问作者shiro
相关产品推荐
相关产品推荐

