1.1.1. 18.过期策略

Redis 所有数据结构都可以设置过期时间,但是有没有想过,如果大量的 key 在同一时间过期,而 Redis 又是单线程,会不会因为处理这些过期 key 导致线上服务暂时卡顿。

过期的 key 集合

Redis 会将每个设置了过期时间的 key 单独放入一个字典中。以后会定期扫描这个字典来删除过期的 key。

除了会定时删除过期的 key 之外,还会使用惰性删除来删除过期的 key。

惰性删除:当客户端访问这个 key 时,会检测 key 是否过期,如果过期直接删除。

定时删除就是集中处理,惰性删除是零散处理。

定时扫描策略

Redis 默认每秒进行 10 次过期扫描,但是不是全量扫描,而是采用另一种策略:

  1. 从过期字典中随机取 20 个 key。
  2. 删除这 20 个 key 中过期的。
  3. 如果删除的 key 比例没有超过 1/4,则重复执行步骤 1。

可能会发生这种情况,如果每次都没有超过 1/4,那岂不是会无限循环下去。导致线程卡死。导致线程卡死的另一个原因还可能是,内存管理器需要频繁回收内存,这也会产生 CPU 消耗。

为了保证不过度循环,导致线程卡死,算法上增加了扫描时间上限,默认不超过 25ms。

当有大量的 key 在同一时间过期,恰好客户端有请求过来,那么客户端至少需要等待 25ms,如果客户端将超过时间设置的比较短如 10ms,那么将会有大量的连接因为超时而关闭,导致服务异常。这个时候也没办法通过 slow log 查看,因为慢查询指的是逻辑处理过程慢,不包含等待时间。

所以为了解决这个问题,开发人员可以在设置过期时间时,增加一个随机范围,来确保 key 不会在同一时间过期。

    $redis->set('key','value',["nx","px"=>100000+random_int(0,3000));

从库的过期策略

从库的过期策略是被动的,是根据主库的 del 指令同步到从库,从而从库进行 key 的删除。但是有可能存在 del 指令没有同步到从库,导致主从 key 不一致。这也是导致分布式锁算法漏洞的原因。

Copyright © Kagami丶 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-10-17 19:28:44

results matching ""

    No results matching ""