Redis缓存过期机制,内存淘汰机制

在Redis中有设置过期时间的键值对是如何实现过期删除的呢?
在使用redis的时候有没有想过Redis内存不够用的临界点是什么呢?
Redis内存不够用时会发生什么呢?

Redis缓存过期机制

Redis中缓存过期机制包括惰性删除定期删除:Redis使用的策略是惰性删除+定时删除并用。

  • 惰性删除
    很好理解,所谓的惰性删除其实就是Redis不主动删除过期的键值对,而是在客户端访问的时候去检查该键值对是否过期,若过期,Redis则会删除该键值对并返回null给客户端。
    惰性删除的情况下,Redis在清除Redis过期缓存上会节约不小的CPU开销,但是对于一些不被客户端访问的键值对来说,会留存在redis缓存中,若数据量大的话,会造成不小的资源浪费。

  • 定期删除
    定期删除的意思是定时去检查Redis中是否有过期键值对,检查到了就删除。这里的定时检查并不是全量检查,而是只检查固定数量的key,这个数量可以通过redis.conf中设置hz配置,默认是10,表示一次检查10个key,官方推荐 最好不要超过100,因为这个数值越大,占用CPU越大。

内存淘汰机制

  • 先贴出内存淘汰机制相关的配置项。
############################## MEMORY MANAGEMENT(内存管理) ################################
# redis配置的最大内存容量。当内存满了,需要配合maxmemory-policy策略进行处理。注意slave的输出缓冲区
# 是不计算在maxmemory内存的。所以为了防止主机内存使用完,建议设置的maxmemory需要比主机可用内存更小一些
# 默认单位为字节(B),也可以为KB,MB,GB,K,M,G等单位写法
maxmemory 1GB

# 内存容量超过maxmemory后的处理策略。
# volatile-lru -> 在具有过期集的key中使用LRU算法逐出。
# allkeys-lru -> 在所有的key中使用LRU算法逐出。
# volatile-lfu -> 在具有过期集的key中使用LFU算法逐出。
# allkeys-lfu -> 在所有的key中使用LFU算法逐出。
# volatile-random -> 从具有过期集的key中移除随机密钥。
# allkeys-random -> 从所有的key中移除随机密钥。
# volatile-ttl -> 删除过期时间最近的密钥(辅以TTL)
# noeviction -> 不逐出任何内容,只返回一个写操作错误。

# LRU表示最近最少使用
# LFU表示使用频率最低
# 注意:使用上述任何策略,Redis将在没有合适的密钥进行逐出时返回写入操作的错误。
# 默认策略为noeviction
maxmemory-policy volatile-lru

# LRU、LFU和minimal-TTL算法不是精确算法,而是近似算法(为了节省内存),因此您可以调整它的速度或精度。
# 对于默认Redis将检查五个键并选择最近使用较少的键,您可以使用以下配置指令更改样本大小。
# 默认值5会产生足够好的结果。10非常接近真实的LRU,但需要更多的CPU。3更快,但不是很准确
maxmemory-samples 5

# 是否开启salve的最大内存,默认为yes不开启,因为一般情况下写操作都是主服务器在操作,
# 所有从服务器无需有最大内存设置,但是需要监控从服务器的内存是否够用,以免出现从服务器内存溢出的情况
# replica-ignore-maxmemory yes
  • 在Redis中内存不足的临界点是什么?
    这个临界点是由maxmemory来触发的,相关介绍在上面配置详解中,此处再介绍下这个值在不设置时的默认值是多少?
    在64位系统中,默认值为0,如果 maxmemory == 0 ,那么不管用户存放多少数据到 Redis 中,Redis 也不会对可用内存进行检查,直到 Redis 实例因内存不足而崩溃也无作为。
    在32位系统中,默认值为3GB,为什么是3GB呢?
    因为 32 位的机器最大只支持 4GB 的内存,而系统本身就需要一定的内存资源来支持运行,所以 32 位机器限制最大 3 GB 的可用内存是非常合理的,这样可以避免因为内存不足而导致 Redis 实例崩溃。

  • 如果开启maxmemory,那么怎么设置才合理呢?
    当然是越大越好了,但是这个其实得根据具体服务器情况来定的。如果设置的最大可用内存过大了,就会导致 Redis 实例因为内存不足而崩溃了。若我们的服务器中装了一个redis,可以只留1GB来支撑系统的运行即可,如果还安装了其他服务,减去相应分配的内存即可。

  • 怎样选择内存淘汰策略呢?
    上述是Redis的8种淘汰策略,关于使用这8种策略,开发者还需要根据自身系统特征,正确选择或修改淘汰策略。

  1. 在Redis中,数据有一部分访问频率较高,其余部分访问频率较低,或者无法预测数据的使用频率时,设置allkeys-lru是比较合适的。

  2. 如果所有数据访问概率大致相等时,可以选择allkeys-random。

  3. 如果研发者需要通过设置不同的ttl来判断数据过期的先后顺序,此时可以选择volatile-ttl策略。

  4. 如果希望一些数据能长期被保存,而一些数据可以被淘汰掉时,选择volatile-lru,volatile-lfu或volatile-random都是比较不错的。

  5. 由于设置expire会消耗额外的内存,如果计划避免Redis内存在此项上的浪费,可以选用allkeys-lru或者allkeys-lfu 策略,这样就可以不再设置过期时间,高效利用内存了。

其实对于大部分系统来说,大概率需要保存一些长期内存(比如电商系统中的一些静态属性:商品品类等),也需要设置一些有过期时间的缓存(有时候过期时间会是数据一致性的一个兜底方案),所以大部分情况下会选择volatile-lru或者volatile-lfu策略,至于这两种策略的算法,根据开发者自我选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值