对线面试官-Redis(内存消耗的问题)

147 阅读7分钟

面试官 :Hi,上次我们聊到了Redis作为缓存的数据一致性问题,这次我们继续聊一聊Redis作为缓存的问题之内存消耗问题?

其实这里问到内存消耗的问题其实无非是想要了解Redis的内存回收机制,或者说更侧重于是Redis的淘汰策略,只要不偏离这方面去回答,我认为问题是不大的。

派大星:好的,没问题。内存消耗问题,就涉及到关于Redis的内存回收机制。说到Redis的内存回收机制,其实主要分为两个方面。

  1. Redis过期策略:删除过期时间的key值
  2. Redis淘汰策略:内存使用达到了Max Memory上限时会触发内存淘汰数据

派大星:其实我们在开发过程种一定要注意:Redis的过期策略和内存淘汰策略不是一件事,千万不要混淆

面试官 :不错,你能详细聊一聊关于这两个回收机制吗?

派大星:可以的,首先先说一下Redis过期策略, 过期策略通常有以下3种:

  • 定时过期: 内存来说是友好的

每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量

  • 惰性过期: cpu来说是友好的

只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

  • 定期过期

每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

派大星:Redis中同时使用了惰性过期和定期过期两种过期策略。具体可参考官方文档:

官方文档:redis.io/commands/ex…

面试官 :不错不错,那能再聊一聊Redis淘汰策略吗?

派大星:好的,关于Redis淘汰策略的基本概念就是:是指当内存使用达到Max Memory上限时,需要使用淘汰算法来决定清理掉哪些数据,以保证新数据的存入。Redis默认情况下就是使用LRU策略算法。

面试官 :很好,Redis数据淘汰策略规则具体有哪些,能简单说一说吗?

派大星:可以,具体的数据淘汰策略如下:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
  • allkeys-lfu:根据键的访问频率来判断哪些键使用得最少,然后将访问频率较低的键进行淘汰

在使用 allkeys-lfu 策略时,Redis 会记录每个键的访问频率,并根据访问频率来判断哪些键应该被淘汰。访问频率低的键会更容易被淘汰,而访问频率高的键则更有可能被保留在内存中。

要注意的是,使用 allkeys-lfu 策略会带来一些额外的计算开销,因为 Redis 需要跟踪键的访问频率。因此,在选择淘汰策略时,需要根据实际需求权衡淘汰的准确性和计算开销之间的关系

  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
  • volatile-lfu:Redis 会根据键的访问频率和过期时间来判断哪些设置了过期时间的键应该被淘汰。访问频率低且过期时间较早的键会更容易被淘汰,而访问频率高或过期时间较晚的键则更有可能被保留在内存中
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

也可参考官网:redis.io/docs/refere…

面试官:那你能说说Redis过期策略和Redis淘汰策略具体什么区别吗?

派大星:Redis的内存淘汰策略用于处理内存不足时的需要申请额外空间的数据,内存淘汰策略的选取并不会影响过期的key的处理。过期策略用于处理过期的缓存数据


面试官 :非常好,那你能说下 Redis数据淘汰策略如何进行配置吗?

派大星:可以通过maxmemory-policy进行配置,设置内存达到最大闲置后,采取什么策略来处理。maxmemory用来设置redis存放数据的最大的内存大小,一旦超出这个内存大小之后,就会立即使用LRU算法清理掉部分数据。对于64 bit的机器,如果maxmemory设置为0,那么就默认不限制内存的使用,直到耗尽机器中所有的内存为止;,但是对于32 bit的机器,有一个隐式的闲置就是3GB。

派大星: 随着业务的增多,缓存数据必然会越来越多,所占用的内存也随之增多,系统的压力也会变大,这时一种方式是给key设置过期时间,但是过期时间长短不太好把握,这时我们可以通过设置redis最大内存来实现,并让redis按照一定的规则淘汰不需要的缓存键,通过这种方式可以去缓解内存消耗的问题。

面试官 :很好,那你知道 RDB和AOF 的淘汰处理吗?

派大星:了解一些

  • 在RDB中是以快照的形式获取内存中某一时间点的数据副本,在创建RDB文件的时候可以通过save和bgsave命令执行创建RDB文件。这两个命令都不会把过期的key保存到RDB文件中,这样也能达到删除过期key的效果。当在启动Redis载入RDB文件的时候,Master不会把过期的key载入,而Slave会把过期的key载入。
  • 在AOF模式下,Redis提供了Rewite的优化措施,执行的命令分别是REWRITEAOF和BGREWRITEAOF,这两个命令都不会把过期的key写入到AOF文件中,也能删除过期key。

面试官 :非常好。你对Redis的了解还是比较透彻的,那么我们下一次再聊一聊,关于Redis作为缓存更新延迟的问题吧。

派大星:好的,没问题。

如有问题,欢迎加微信交流:w714771310,或关注微信公众号【码上遇见你】。