知识库的文档片段缓存在 Redis 7.2 里,一个 key 存了整个文件的全部 chunk,体积 20MB,前端预览时用 get 一次取回,监控里网卡出流量瞬间到 1.6Gbps,其他接口的 P99 同时涨到 3 秒。

一开始怀疑是「客户端在事件循环里同步取大 key,阻塞了其他请求」,查了一圈,方向不对。

排查方向其实有限,先把可能性排一排。单个 value 过大,GET 时序列化与网络传输都成为瓶颈。也可能是缓存设计把列表整体塞进一个 string,没有按片段拆分。

还有一种情况,同一份大 key 被多个实例同时拉取,出流量叠加。

第一件事是找出体积排名靠前的 key

redis-cli --bigkeys

随后用 memory usage 确认具体大小

redis-cli memory usage kb:doc:8821 samples 0

接着改成分片存并按需取一段

redis-cli lrange kb:doc:8821 0 9

给大 key 加压缩后再对比体积

python -c "import zlib;print(len(zlib.compress(b'x'*20000000)))"

改完先别撤,确认这几项。预览接口单次取回的数据降到百 KB 级,网卡出流量回到正常水位,其他接口 P99 恢复到 300 毫秒以内。

补一句。缓存不是越整越好,大 value 会把读写、网络、序列化三处一起拖慢,按业务访问粒度拆分比换更大带宽有效。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189