一、背景
有一天,企微收到了一条告警:Redis实例内存达到80%已自动扩容。通过分析内存变化曲线,发现是近几天才开始涨得比较快。通过大key分析拿到了几个key,命名分别是ts_file_0、ts_file_1、…、ts_file_9,很明显这些大key都是同一个场景下生成的,然后通过查看问题代码可以发现也刚好是前几天才上线的,那么问题就明确了,现在就需要来看看如何解决这些大key。(具体可参考《如何处理Redis的大key问题?》)

二、具体分析
首先我们能想到的就是优化value结构,让功能不变的前提下,尽可能减少存储数据量。
原先的value结构是:
json
{"id": 123, "index": 1, "type": 2, "message": "xxx", "duration": 66, "extend": "xxx"}
我们的需求是只需要取到这里面的index和duration字段,所以我们并不需要把整个对象存进去,我们优化一下value结构:
json
{"index": 1, "duration": 66}
三、结果分析
在Redis 4.0以后,我们可以通过memory usage <key>
来查看某个key的内存占用情况:

在优化之前,一个key的元素的内存占用大概是400字节,优化后大概在150字节左右,所以整体算下来大概优化了62.5%,具体为:
- 优化前:每5秒生成一个元素,每天大约会有25w分钟(并行跑),所以一天占用内存为
25w * 60 / 5 / 1024 / 1024 ≈ 1G
- 优化后:每个元素由400字节优化到150字节,所以一天占用内存大约为
1G / (150 / 400) = 0.375G
但是时间久了的话,很多key加起来也不是一个小数目,所以我们也加入了自动过期,如7天清理、15天清理,根据场景需求适当调整清理频率。