二零二三年二月第三周技术周报

本周主要处理一个节前发现的风险项。某个服务,在使用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之间。这意味着,要求存留时间越长的键,过期的分布也越广。这能够确保业务延时更加平稳,防止数据库压力过大。