首页 > 数据库 >谈谈 Redis 的过期策略

谈谈 Redis 的过期策略

时间:2023-03-16 16:35:31浏览次数:43  
标签:删除 过期 maxmemory Redis 谈谈 内存 key

在日常开发中,我们使用 Redis 存储 key 时通常会设置一个过期时间,但是 Redis 是怎么删除过期的 key,而且 Redis 是单线程的,删除 key 会不会造成阻塞。要搞清楚这些,就要了解 Redis 的过期策略和内存淘汰机制。

Redis采用的是定期删除 + 懒惰删除策略。

定期删除策略

Redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,默认每 100ms 进行一次过期扫描:

  1. 随机抽取 20 个 key
  2. 删除这 20 个key中过期的key
  3. 如果过期的 key 比例超过 1/4,就重复步骤 1,继续删除。

为什么不扫描所有的 key?

Redis 是单线程,为了防止每次扫描过期的 key 比例都超过 1/4,导致不停循环卡死线程,Redis 为每次扫描添加了上限时间,默认是 25ms。

如果在同一时间出现大面积 key 过期,Redis 循环多次扫描过期词典,直到过期的 key 比例小于 1/4。这会导致卡顿,而且在高并发的情况下,可能会导致缓存雪崩。

为什么 Redis 为每次扫描添的上限时间是 25ms,还会出现上面的情况?

因为 Redis 是单线程,每个请求处理都需要排队,而且由于 Redis 每次扫描都是 25ms,也就是每个请求最多 25ms,100 个请求就是 2500ms。

如果有大批量的 key 过期,要给过期时间设置一个随机范围,而不宜全部在同一时间过期,分散过期处理的压力。

从库的过期策略

从库不会进行过期扫描,从库对过期的处理是被动的。主库在 key 到期时,会在 AOF 文件里增加一条 del 指令,同步到所有的从库,从库通过执行这条 del 指令来删除过期的 key。

因为指令同步是异步进行的,所以主库过期的 key 的 del 指令没有及时同步到从库的话,会出现主从数据的不一致,主库没有的数据在从库里还存在。

懒惰删除策略

Redis 为什么要懒惰删除(lazy free)?

删除指令 del 会直接释放对象的内存,大部分情况下,这个指令非常快,没有明显延迟。不过如果删除的 key 是一个非常大的对象,比如一个包含了千万元素的 hash,又或者在使用 FLUSHDB 和 FLUSHALL 删除包含大量键的数据库时,那么删除操作就会导致单线程卡顿。

redis 4.0 引入了 lazyfree 的机制,它可以将删除键或数据库的操作放在后台线程里执行, 从而尽可能地避免服务器阻塞。

内存淘汰机制

Redis 的内存占用会越来越高。Redis 为了限制最大使用内存,提供了 redis.conf 中的配置参数 maxmemory。

当内存超出 maxmemory,Redis 提供了几种内存淘汰机制让用户选择,配置 maxmemory-policy:

  • noeviction:当内存超出 maxmemory,写入请求会报错,但是删除和读请求可以继续。(使用这个策略,疯了吧)
  • allkeys-lru:当内存超出 maxmemory,在所有的 key 中,移除最少使用的key。只把 Redis 既当缓存是使用这种策略。(推荐)。
  • allkeys-random:当内存超出 maxmemory,在所有的 key 中,随机移除某个 key。(应该没人用吧)
  • volatile-lru:当内存超出 maxmemory,在设置了过期时间 key 的字典中,移除最少使用的 key。把 Redis 既当缓存,又做持久化的时候使用这种策略。
  • volatile-random:当内存超出 maxmemory,在设置了过期时间 key 的字典中,随机移除某个key。
  • volatile-ttl:当内存超出 maxmemory,在设置了过期时间 key 的字典中,优先移除 ttl 小的。

 

参考:

 

标签:删除,过期,maxmemory,Redis,谈谈,内存,key
From: https://www.cnblogs.com/xfeiyun/p/17222814.html

相关文章

  • redis线程模型-IO多路复用单线程通俗理解
     Redis单线程redis是以socket方式通信,socket服务端可同时接受多个客户端请求连接,也就是说,redis服务同时面对多个redis客户端连接请求,而redis服务本身是单线程运行。 ......
  • Redis之I/O多路复用模型实现原理
    本文内容基于Redis6.0以前的版本编写,因为6.0之后Redis在网络处理这一块采用了多线程模式,但是I/O多路复用的模型还在,变化不大。本文有不当之处,大家轻喷!Redis之I/O......
  • Redis常用命令
    redis数据库一、概述:redis数据库是一个内存数据库,基于内存进行数据存储的,redis数据库访问速度特别快。因此,redis通常被用于缓存系统、存储大量活跃数据,可以极大地提......
  • 谈谈项目中单点登录的实现原理?
    单点登录在现在的系统架构中广泛存在,它将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登......
  • Redis中是如何实现分布式锁的?
    分布式锁常见的三种实现方式:数据库乐观锁;基于Redis的分布式锁;基于ZooKeeper的分布式锁。Redis要实现分布式锁,以下条件应该得到满足:互斥性:在任意时刻,只有一个客户端......
  • 安装redis
    redis安装brewsearchredis  brewinstallredis (这里安装的是redis的最新版本,因为没有@)执行完毕之后,就完成了redis的安装。redis服务默认是安装在`/usr/local/Ce......
  • Redis查询大key
    原文安装wget"https://pypi.python.org/packages/68/44/5efe9e98ad83ef5b742ce62a15bea609ed5a0d1caf35b79257ddb324031a/redis-2.10.5.tar.gz#md5=3b26c2b9703b4b56b30......
  • #认识Redis
    Redis(全称:RemoteDictionaryServer远程字典服务)是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它是......
  • Redis基础知识
    IO多路复用IO:I/O是Input输入/Output输出的简称,通常指数据在内部存储器(内存)和外部存储器(硬盘、优盘)或其他周边设备之间的输入和输出。  输入/输出是信息处理系统(计算机)......
  • 狂神--Redis-Docker启动脚本
    1.docker版本20dockerinfoClient:Context:defaultDebugMode:falsePlugins:app:DockerApp(DockerInc.,v0.9.1-beta3)buildx:BuildwithBuil......