redis expire不生效踩坑级
Contents
一.flask-limit限流原理
项目配置采用了固定时间窗口策略 incr和expire配合,每次请求来的时候 incr后的值与amount上限比较,如果超过则返回http 429
|
|
<!-- more -->
二.排查redis服务
1.redis有其他阻塞操作,引起了expire失效?
|
|
2.其他人操作了同样的key?
1.换个db, 取特殊的key名称
2.监控redis命令操作
|
|
3.redis过期机制
1.定时删除
对于每一个设置了过期时间的key都会创建一个定时器,一旦到达过期时间就立即删除。该策略可以立即清除过期的数据,对内存较友好,但是缺点是占用了大量的CPU资源去处理过期的数据,会影响Redis的吞吐量和响应时间
2.惰性删除
当访问一个key时,才判断该key是否过期,过期则删除。该策略能最大限度地节省CPU资源,但是对内存却十分不友好。有一种极端的情况是可能出现大量的过期key没有被再次访问,因此不会被清除,导致占用了大量的内存。
3.定期删除
每隔一段时间,扫描Redis中过期key字典,并清除部分过期的key。该策略是前两者的一个折中方案,还可以通过调整定时扫描的时间间隔和每次扫描的限定耗时,在不同情况下使得CPU和内存资源达到最优的平衡效果。 默认是每秒运行 10 次, 平均每 100 毫秒运行一次。 从 Redis 2.8 开始, 用户可以通过修改 hz选项来调整 serverCron 的每秒执行次数, 具体信息请参考 redis.conf 文件中关于 hz 选项的说明。
4.当内存达到maxmemory配置时候,会触发Key的删除操作
当mem_used内存已经超过maxmemory的设定,对于所有的读写请求,都会触发redis.c/freeMemoryIfNeeded(void)函数以清理超出的内存。 注意这个清理过程是阻塞的,直到清理出足够的内存空间。 清理时会根据用户配置的maxmemory-policy来做适当的清理(一般是LRU或TTL)
三.故障分析
线下我们配置的是redis主从服务,线上阿里云的连接方式为直连,所以线下连接redis也为直连master 某日哨兵检测到master故障,进行了主从切换,之前的主节点降级为从节点,导致我们变为了直连从节点。 经过测试,redis在从节点设置expire的话,ttl一直减少到0后,从节点不自行执行删除key到操作,key的清除操作只能由主节点发起来,然后rsync到从节点进行同步。 故我们从节点的expire操作一直不生效,限流的时间窗口不过期,限流计数一直在累加!!!
To “maintain consistency”, slaves aren’t allowed to expire keys unless they receive a DEL from the master branch, even if they know the key is expired. The only exception is when a slave becomes master. So basically, if the master doesn’t send a DEL to the slave, the key (which might have been set with a TTL using the Redis API contract), is not guaranteed to respect the TTL it was set with. This is when you scale to have read slaves, which, apparently, is a shocking requirement in production systems. 为了维护一致性,salve不被容许删除key除非从master收到del命令
附录:redis相关命令
1.expire key
|
|
2.某个时间点expire
|
|
3.查询key存活时间
|
|
4.清除expire
|
|
5.判断某个key是否存在
|
|
参考 https://cloud.tencent.com/developer/article/1044436
https://www.hoohack.me/2019/06/24/redis-expire-strategy
https://www.w3cschool.cn/redis_all_about/redis_all_about-xzio26xj.html
https://www.digitalocean.com/community/cheatsheets/how-to-expire-keys-in-redis
https://engineering.grab.com/a-key-expired-in-redis-you-wont-believe-what-happened-next
Author tmackan
LastMod 2020-08-22