本周主要处理一个节前发现的风险项。某个服务,在使用 Redis 的时候并没有为键设置 TTL,而是寄希望于 redis 的淘汰策略。我看这个服务使用的 Redis 设置了 LRU 淘汰策 略。这种策略看似比较完美,但是当某一较短时间段内,写入流量很大的时候,存在隐患。 这个时候 Redis 会触发淘汰过程,并集中尽力于此,以求能腾出足够的空间。这意味 着,Redis 不能很好地执行查询等正常操作了。这会造成业务层对 Redis 的读写延时均出 现剧烈波动。到现在,我已经遇到过 2 次这样的问题了。而且不设置 TTL,Redis 一直处 于 100%的使用率状态,我们从容量上并不能获知按照现在的业务量配置多少购买容量足 够。业务低峰时期是否能够通过缩容降低成本也是不能确定的。所以,为 Redis 留出一个 足够的可用空间是十分重要的。
所以,我需要改造这个服务,使之对每个写入的新键设置 TTL。按照 Redis 的逻辑,如果 键在写入的时候已经存在,则也会被设置一个 TTL。为了业务稳定,我不求所有的键都设置 TTL。所以舍弃了在遍历 Redis 寻找未设置 TTL 的键的方案。其实我调研过这个方案,在 遍历的时候,使用需要游标来做。设置的 TTL 长短也有讲究,为了防止同一时间大量键过 期造成延时的大波动,设置 TTL 的时候在基础时长后加入了随机时长。假设基础时长为 T,那么加入随机时长后,TTL 的长度会处于 T ~ 2T 之间。这意味着,要求存留时间越长 的键,过期的分布也越广。这能够确保业务延时更加平稳,防止数据库压力过大。