面试官问:Redis 缓存淘汰策略有哪些?

数据库 Redis
我们知道,redis一般会设置过期时间。那么这些键过期了是立刻从内存中删除吗?通常,键删除会有不同的策略。

我们知道:Redis是基于内存的,面试官问:

  • 生产环境Redis内存如何分配?
  • Redis键过期了如何删除?
  • ......

本小节不仅适用于工作,也是面试的高频问题。

文章导读

Redis内存分析

1.Redis默认内存是多少?

在 64bit 系统下,默认不限制内存大小,不设置内存大小和maxmemory = 0表示不限制 Redis 内存使用

2.如何查看Redis最大内存是多少?

命令行:

127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"

配置文件 redis.conf:

# maxmemory <bytes>

3.如何查看Redis内存使用情况?

127.0.0.1:6379> info memory

4.如何配置和修改?

临时方案,通过命令修改:

127.0.0.1:6379> config set maxmemory 104857600
OK
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "104857600"

永久方案,通过配置文件:

5.生产环境如何配置?

建议:一般取物理内存的3/4

Redis过期键删除?

我们知道,redis一般会设置过期时间。那么这些键过期了是立刻从内存中删除吗?

通常,键删除会有不同的策略。

1.立刻删除

立即删除能保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是删除操作会占用cpu的时间,造成CPU额外的压力。

redis.conf 中,通过调整过期键的检测频率:

# The range is between 1 and 500, however a value over 100 is usually not
# a good idea. Most users should use the default of 10 and raise this up to
# 100 only in environments where very low latency is required.
hz 10

但是这会产生大量的性能消耗,同时也会影响数据的读取操作。

2.惰性删除

数据到达过期时间,不做处理。等下次访问该数据时:

  • 如果未过期,返回数据 ;
  • 发现已过期,删除,返回不存在。

惰性删除策略的缺点是,它对内存是最不友好的。如果一个键已经过期,而这个键又仍然保留在redis中,那么只要这个过期键不被删除,它所占用的内存就不会释放。

#开启憜性淘汰
lazyfree-lazy-eviction=yes

3.定期删除

这种方案有效规避上述两种极端情况, 定期删除策略的难点是确定删除操作执行的时长和频率:

  • 如果删除操作执行得太频繁或者执行的时间太长,定期删除策略就会退化成立即删除策略。
  • 如果删除操作执行得太少,或者执行的时间太短,定期删除策略又会和惰性删除束略一样,出现浪费内存的情况。
  • 因此,如果采用定期删除策略的话,服务器必须根据情况,合理地设置删除操作的执行时长和执行频率。

Redis内存淘汰策略

基于上述的了解,假如:

  • 定期删除时,从来没有被抽查到
  • 惰性删除时,也从来没有被点中使用过

上述两个步骤,依然会有大量过期的key堆积在内存中,导致redis内存空间紧张或者很快耗尽。

因此,有没有一个更好的兜底方案......?这就是要讲的淘汰策略

1.LRU和LFU区别?

(1) LRU(Least Recently Used,最近最少使用页面置换算法)

假设我们有一个容量为3的LRU缓存,访问数据的顺序如下:

  • 访问数据1,缓存中现在有:[1]
  • 访问数据2,缓存中现在有:[1, 2]
  • 访问数据3,缓存中现在有:[1, 2, 3]
  • 再次访问数据1,缓存中现在有:[2, 3, 1](因为1被重新访问,它被移到了列表的末尾)
  • 访问数据4,由于缓存已满,最不常用的数据2将被淘汰,缓存中现在有:[3, 1, 4]

原理:如果数据最近被访问过,那么在不久的将来它很可能再次被访问。因此,LRU会淘汰最长时间未被访问的数据。

适用场景:适用于最近被访问的数据在未来某个时间点很可能再次被访问。

(2) LFU(Least Frequently Used,最近最不常用页面置换算法)

假设我们有一个容量为3的LFU缓存,访问数据的顺序如下:

  • 访问数据1,计数器:{1: 1}
  • 访问数据2,计数器:{1: 1, 2: 1}
  • 访问数据1,计数器:{1: 2, 2: 1}
  • 访问数据3,计数器:{1: 2, 2: 1, 3: 1}
  • 访问数据1,计数器:{1: 3, 2: 1, 3: 1}
  • 访问数据4,由于缓存已满,访问次数最少的数据2将被淘汰,计数器:{1: 3, 3: 1, 4: 1}

原理:LFU算法会跟踪每个页面在特定时间段内被访问的频率。当需要淘汰页面时,LFU算法会淘汰在该时间段内访问次数最少的页面。

适用场景:LFU算法适用于那些访问模式可能随时间变化的场景,或者访问频率能够较好地反映页面重要性的情况。

(3) 小结

  • LRU关注数据的最近访问时间,淘汰最长时间未被访问的数据。
  • LFU关注数据的访问频率,淘汰访问次数最少的数据。

2.Redis有哪些淘汰策略?

redis.config 配置文件中,

# volatile-lru -> Evict using approximated LRU, only keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key having an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.

解释下:

  • volatile-lru:使用近似的最近最少使用(LRU)算法淘汰键。但是,只有那些设置了过期时间的键(即“volatile”键)才会被考虑淘汰。
  • allkeys-lru:使用近似的LRU算法淘汰任何键,无论它们是否设置了过期时间。
  • volatile-lfu:使用近似的最少频率使用(LFU)算法淘汰键。同样,只有设置了过期时间的键会被考虑。
  • allkeys-lfu:使用近似的LFU算法淘汰任何键,不考虑它们是否设置了过期时间。
  • volatile-random:随机淘汰一个设置了过期时间的键。
  • allkeys-random:随机淘汰任何键,不论它们是否设置了过期时间。
  • volatile-ttl:淘汰具有最短剩余生存时间(TTL)的键,即那些最接近过期时间的键。
  • noeviction:不淘汰任何键。当内存达到最大容量时,Redis将不会进行任何淘汰操作,而是在写入新数据时返回错误。

3.生产如何选择淘汰策略?

在生产环境中选择缓存淘汰策略时,通常需要根据应用的具体需求和数据特性来定。这里给出常见案例:

(1) 电商平台的商品推荐

电商平台需要为用户展示个性化的商品推荐,其中热门商品的访问频率较高。可选择:LFU(Least Frequently Used)

redis-cli config set maxmemory-policy allkeys-lfu

因为LFU策略可以保留访问频率高的商品,确保推荐列表中展示用户最可能感兴趣的商品。

(2) 金融交易平台的实时数据

金融交易平台需要提供实时的股票价格和交易数据,数据的实时性至关重要。过期的时价被淘汰。

可选择:TTL(Time To Live)结合LRU(Least Recently Used)

redis-cli config set maxmemory-policy volatile-lru

TTL确保数据在一定时间后自动过期,而LRU保证最近访问的数据被优先保留。

(3) 电信运营商的用户数据管理

电信运营商需要处理和缓存大量用户的通话记录、短信记录等,用户通常更关心最近的通信记录。

可选择:LRU(Least Recently Used)

redis-cli config set maxmemory-policy allkeys-lru

因为LRU策略可以确保最近生成的通话记录和短信记录被优先缓存。

(4) 社交媒体平台的用户动态

社交媒体平台需要为用户展示好友的最新动态和帖子,用户通常对最新动态感兴趣。

可选择:LRU

redis-cli config set maxmemory-policy allkeys-lru

因为LRU可以保证最新的帖子被优先展示。

好了,今天就聊到这里,读者可依据实际情况择优选择策略。

责任编辑:赵宁宁 来源: 码易有道
相关推荐

2024-06-04 07:38:10

2018-10-24 14:30:30

缓存服务更新

2021-09-10 18:47:22

Redis淘汰策略

2023-12-06 13:38:00

Redis缓存穿透缓存击穿

2023-08-15 15:33:29

线程池线程数

2021-03-01 18:42:02

缓存LRU算法

2024-07-26 08:47:07

2021-12-25 22:31:10

MarkWord面试synchronize

2021-11-08 09:18:01

CAS面试场景

2024-02-20 14:10:55

系统缓存冗余

2023-02-20 08:08:48

限流算法计数器算法令牌桶算法

2021-12-16 18:38:13

面试Synchronize

2010-08-23 15:06:52

发问

2021-01-06 05:36:25

拉链表数仓数据

2024-01-19 14:03:59

Redis缓存系统Spring

2022-01-05 09:55:26

asynawait前端

2022-06-29 16:59:21

Vue3Vue2面试

2024-04-03 00:00:00

Redis集群代码

2021-11-02 09:05:25

Redis

2024-03-12 10:44:42

点赞
收藏

51CTO技术栈公众号