laravel 11可通过自定义compressedredisstore实现条件zlib压缩、精简eloquent模型序列化字段、集成msgpack扩展及按场景分层控制压缩策略来优化数据库缓存体积。

Laravel 11 虽未原生支持 Laravel 13 的 serializer 配置项,但完全可以通过适配方式实现数据库缓存的压缩存储优化——核心在于对缓存值在写入前压缩、读取后解压,同时规避默认序列化带来的体积膨胀问题。重点不是升级框架,而是精准干预缓存数据的“进出路径”。
用自定义 RedisStore 实现条件压缩
Laravel 11 的缓存系统仍基于 Illuminate\Cache\RedisStore,你可以继承它并重写序列化逻辑,只对大体积值启用 zlib 压缩,避免小键因压缩头反而变大。
- 新建
app/Cache/CompressedRedisStore.php,继承RedisStore - 重写
serialize():判断原始值字符串长度(如 >512 字节)再调用gzcompress() - 重写
unserialize():先尝试gzuncompress(),失败则回退到原生unserialize() - 在
config/cache.php的stores中注册该 Store,例如:'compressed-redis' => [ 'driver' => 'redis', 'connection' => 'default', 'store' => \App\Cache\CompressedRedisStore::class ] - 使用时显式指定:
Cache::store('compressed-redis')->put('html_content', $longHtml, 3600)
精简 Eloquent 模型缓存内容
数据库缓存常用于保存查询结果(如 Category::all()),但默认缓存整个模型实例,含大量元数据和隐藏字段,体积虚高。
- 在模型中设置
$hidden屏蔽敏感或冗余字段(如password,remember_token,updated_at) - 清空
$appends或仅保留必要访问器,防止序列化时执行计算逻辑并缓存结果 - 改用数组方式缓存:
Cache::remember('categories', 3600, fn() => Category::select('id', 'name', 'slug')->get()->toArray()) - 若用 Spatie Permission,配置
config/permission.php中的column_names_except排除时间戳等字段
换用 msgpack 序列化(需手动集成)
Laravel 11 不内置 msgpack 支持,但可通过扩展 + 自定义序列化器达成类似效果,比原生 serialize() 减少约 35–40% 体积。
- 安装 PHP msgpack 扩展:
pecl install msgpack(确认php -m | grep msgpack可见) - 创建
app/Cache/MsgpackSerializer.php,实现Illuminate\Contracts\Cache\Serializer接口 - 在
serialize()中用msgpack_pack($value),unserialize()中用msgpack_unpack($payload) - 将该 Serializer 注入到自定义 RedisStore 构造函数中,替代默认行为
按场景分层控制压缩策略
并非所有缓存都适合压缩。结合业务语义做粒度控制更高效:
- 对 HTML 片段、导出 CSV、长 JSON API 响应等大文本类缓存,强制走压缩 Store
- 对计数器、开关状态、短 token 等小体积键(
- 利用缓存标签(Tags)区分类型:
Cache::tags(['html', 'compressed'])->put(...),便于后续清理或监控 - 在缓存键中加入标识,如
cache:html:home_page:compressed,方便运维识别与调试











