由网络副手--寻路人于2017.04.05 17:51:11发布在NoSql技术 一个如何避过读到Redis过期Key的方案 阅读2915 评论0 喜欢1 说道问题,先说一个场景吧,便于大家理解。 在很久之前,PM打来电话说问答用户反馈说,用户的抽奖次数有问题,说今天一次也没抽奖怎么提示没有无抽奖次数了呢? 后来经过追查发现问题如下: 1. 由于Redis做了读写分离 2. 有的服务器集群读取的是从服务器 3. 从服务器key已经过期,但是没有删除. 说道这里,或许又会有朋友说这是一个 XXX坑了, 也不能尽然这么描述,这个问题是确实存在的,咱们来梳理下Redis的删除机制。 redis 从服务器是无写权限的,所以没法做删除操作。 解决方案: 1. 在程序拉取是否过期的时候不能只判断值是否存在,同时判断下 ttl 2. 从存储入手,通过scan扫库(以下为原理) 当redis中的key被scan的时候,相当于访问了该key,同样也会做过期检测,充分发挥redis惰性删除的策略。这个方法能大大降低了脏数据读取的概率,但缺点也比较明显,会造成一定的数据库压力,谨慎合理使用,否则有可能影响线上业务的效率 3. 升级Redis3.2 版本 说到这来,咱们向下延伸下. 一、Redis key的三种过期策略 惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key,很明显,这是被动的! 定期删除:由于惰性删除策略无法保证冷数据被及时删掉,所以redis会定期主动淘汰一批已过期的key。 主动删除:当前已用内存超过maxmemory限定时,触发主动清理策略,该策略由启动参数的配置决定,可配置参数及说明如下: volatile-lru:从已设置过期时间的数据集中根据LRU算法删除数据(redis3.0之前的默认策略) volatile-ttl:从已设置过期时间的数据集中挑选过期时间最小的数据删除 volatile-random:从已设置过期时间的数据集中随机选择数据删除 allkeys-lru:从所有数据集中根据LRU算法删除数据 allkeys-random:从所有数据集中任意选择删除数据 noenviction:禁止从内存中删除数据(从redis3.0 开始默认策略) maxmemory-samples:删除数据的抽样样本数,redis3.0之前默认样本数为3,redis3.0开始默认样本数为5,该参数设置过小会导致主动删除策略不准确,过大会消耗多余的cpu 赞 1 分享 赏 您可以选择一种方式赞助本站 支付宝扫码赞助 BraveDu 署名: 网络副手~寻路人