[Redis]删除机制

目录

1.redis三种不同的删除策略

2. 优缺点

3. 算法

4. RDB和AOF时过期键的处理

5. 时间事件

6.总结(重要)


1.redis三种不同的删除策略

redis数据库键的过期时间都保存在过期字典中,根据系统时间和存活时间判断是否过期。

  1,定时删除:实现方式,创建定时器

  2,惰性删除:每次获取键时,检查是否过期

  3,定期删除:每隔一段时间,对数据库进行一次检查,删除过期键,由算法决定删除多少过期键和检查多少数据库

2. 优缺点

  1,定时删除,对内存友好,但是对cpu很不友好(因为单线程)

  2,惰性删除,对cpu友好,对内存很不友好(容易积压)

  3,定期删除,是两种折中,但是,如果删除太频繁,将退化为定时删除,如果删除次数太少,将退化为惰性删除。

3. 算法

  1,惰性删除

              因为有些key可能永远不会被访问到,所以并不是很友好的()。

    策略由expireIfNeeded函数实现,所有读写命令在执行之前都会调用该函数进行检查,键写入和获取过程如图所示:

    

    

  2,定时删除

    删除策略由activeExpireCycle算法决定

    关键点,遍历数据库,如果时间到,则终止;遍历数据库接着上次的进度,直到所有数据库遍历完,再接着遍历;遍历库时候,随机取出一定数量的随机键

              (随机取出一部分数据,遍历之后删除过期的)

4. RDB和AOF时过期键的处理

  1,RDB生成时,过期键会被过滤

     RDB载入时,以主服务器运行,则过滤过期键

          以从服务器运行,则忽略过期键,不做处理

  2,AOF生成时,如果过期键还没被删除,则忽略,当被删除以后,会追加记录一条DEL命令(生成的时候追加DEL命令)

     AOF载入时,过期键会被过滤

5. 时间事件

对于持续运行的服务器来说, 服务器需要定期对自身的资源和状态进行必要的检查和整理, 从而让服务器维持在一个健康稳定的状态, 这类操作被统称为常规操作(cron job)

在 Redis 中, 常规操作由 redis.c/serverCron 实现, 它主要执行以下操作

  • 更新服务器的各类统计信息,比如时间、内存占用、数据库占用情况等。
  • 清理数据库中的过期键值对。
  • 对不合理的数据库进行大小调整。
  • 关闭和清理连接失效的客户端。
  • 尝试进行 AOF 或 RDB 持久化操作。
  • 如果服务器是主节点的话,对附属节点进行定期同步。
  • 如果处于集群模式的话,对集群进行定期同步和连接测试。

在 Redis 2.6 版本中, 程序规定 serverCron 每秒运行 10 次, 平均每 100 毫秒运行一次。 从 Redis 2.8 开始, 用户可以通过修改 hz选项来调整 serverCron 的每秒执行次数, 具体信息请参考 redis.conf 文件中关于 hz 选项的说明也叫定时删除,这里的“定期”指的是Redis定期触发的清理策略,由位于src/redis.c的activeExpireCycle(void)函数来完成。

serverCron是由redis的事件框架驱动的定位任务,这个定时任务中会调用activeExpireCycle函数,针对每个db在限制的时间REDIS_EXPIRELOOKUPS_TIME_LIMIT内迟可能多的删除过期key,之所以要限制时间是为了防止过长时间 的阻塞影响redis的正常运行。这种主动删除策略弥补了被动删除策略在内存上的不友好。

Redis会周期性的随机测试一批设置了过期时间的key并进行处理。测试到的已过期的key将被删除。典型的方式为,Redis每秒做10次如下的步骤:

  1. 随机测试100个设置了过期时间的key
  2. 删除所有发现的已过期的key
  3. 若删除的key超过25个则重复步骤1 (这个思想挺重要的)

除了主动淘汰的频率外,Redis对每次淘汰任务执行的最大时长也有一个限定,这样保证了每次主动淘汰不会过多阻塞应用请求,以下是这个限定计算公式:


#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 /* CPU max % for keys collection */  

...  

timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;

6. 如果maxmemory ,怎么执行淘汰策略
当前已用内存超过maxmemory限定时,触发主动清理策略

  • volatile-lru:只对设置了过期时间的key进行LRU(默认值)
  • allkeys-lru : 删除lru算法的key
  • volatile-random:随机删除即将过期key
  • allkeys-random:随机删除
  • volatile-ttl : 删除即将过期的
  • noeviction : 永不过期,返回错误

LRU算法在leetcode上面也有提到~

当mem_used内存已经超过maxmemory的设定,对于所有的读写请求,都会触发redis.c/freeMemoryIfNeeded(void)函数以清理超出的内存。注意这个清理过程是阻塞的,直到清理出足够的内存空间。所以如果在达到maxmemory并且调用方还在不断写入的情况下,可能会反复触发主动清理策略,导致请求会有一定的延迟。

清理时会根据用户配置的maxmemory-policy来做适当的清理(一般是LRU或TTL),这里的LRU或TTL策略并不是针对redis的所有key,而是以配置文件中的maxmemory-samples个key作为样本池进行抽样清理。

maxmemory-samples在redis-3.0.0中的默认配置为5,如果增加,会提高LRU或TTL的精准度,redis作者测试的结果是当这个配置为10时已经非常接近全量LRU的精准度了(抽样池子越大越接近LRU但是更加消耗CPU时间),并且增加maxmemory-samples会导致在主动清理时消耗更多的CPU时间,建议:

  • 尽量不要触发maxmemory,最好在mem_used内存占用达到maxmemory的一定比例后,需要考虑调大hz以加快淘汰,或者进行集群扩容。
  • 如果能够控制住内存,则可以不用修改maxmemory-samples配置;如果Redis本身就作为LRU cache服务(这种服务一般长时间处于maxmemory状态,由Redis自动做LRU淘汰),可以适当调大maxmemory-samples。

这里提一句,实际上redis根本就不会准确的将整个数据库中最久未被使用的键删除,而是每次从数据库中随机取5个键并删除这5个键里最久未被使用的键。上面提到的所有的随机的操作实际上都是这样的,这个5可以用过redis的配置文件中的maxmemeory-samples参数配置。

Replication link和AOF文件中的过期处理

为了获得正确的行为而不至于导致一致性问题,当一个key过期时DEL操作将被记录在AOF文件并传递到所有相关的slave。也即过期删除操作统一在master实例中进行并向下传递,而不是各salve各自掌控。(不是有S传到S)这样一来便不会出现数据不一致的情形。当slave连接到master后并不能立即清理已过期的key(需要等待由master传递过来的DEL操作),slave仍需对数据集中的过期状态进行管理维护以便于在slave被提升为master会能像master一样独立的进行过期处理。

6.总结(重要)

Redis删除会引出LRU问题,需要手写LRU算法。

Redis是一种近似LRU做法,实际上是有样本池的,默认为5可以更改。为10就很接近LRU了。这个池子越大,LRU越慢,消耗CPU,可能会占用用户时间。

样本池中淘汰最不常用的一个,直到内存够用。

尽量不要触发LRU,当触发lru该考虑集群扩容,以及加快淘汰删除的时间。

定时删除是这样的:

典型的方式为,Redis每秒做10次如下的步骤:

  1. 随机测试100个设置了过期时间的key
  2. 删除所有发现的已过期的key
  3. 若删除的key超过25个则重复步骤1 (这个思想挺重要的)

对于持续运行的服务器来说, 服务器需要定期对自身的资源和状态进行必要的检查和整理, 从而让服务器维持在一个健康稳定的状态, 这类操作被统称为常规操作(cron job)

AOF对于过期的KEY同步的时候,会最后追加DEL命令。

懒惰删除策略由expireIfNeeded函数实现。

定时删除策略由activeExpireCycle算法决定。

 

 

 

 

转自: https://www.cnblogs.com/williamcai/p/9812190.html

            https://www.cnblogs.com/superchong/p/10482558.html

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值