Redis过期策略

过期的key集合

Redis会将每个设置了过期时间的key放入到一个独立的字典中,以后会定时遍历这个字典来删除到期的key。除了定时遍历之外,他还会使用惰性策略来删除过期的key,所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除。定时删除是集中处理,惰性删除是零散处理。

定时扫描策略

Redis默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的key,而是采用了一种简单的贪心策略。

  • 从过期字典中随机20个key。
  • 删除这20个key中已经过期的key。
  • 如果过期key的比率超过1/4,那就重复步骤1。

同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上线,默认不会超过25ms。

设想一个大型的Redis实例中所有key在同一时间过期了,会出现怎样的结果。

毫无疑问,Redis会持续扫描过期字典(循环多次),直到过期字典中过期的key变得稀疏,才会停止(循环次数明显下降)。这就会导致线上读写请求出现明显的卡顿现象。导致这种卡顿的另一种原因是内存管理器需要频繁回收内存页,这也会产生一定的CPU消耗。

为什么设置了25ms超时时间,仍然会卡顿

假设有101个客户端同时将请求发过来,每一个请求都需要经过25ms的超时时间,那么第101个指令需要等待2500ms后才能得到执行,这个就是客户端的卡顿时间,是由服务器不间断的小卡顿积少成多导致的。

所以开发人员一定要注意过期时间,如果有大批量的key过期,要给过期时间设置一个随机范围,而不能全部在同一时间过期。

从库的过期策略

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

因为指令同步是异步进行的,所以从库过期的key的del指令没有及时同步到从库的话,会出现主从数据的不一致,主库没有的数据从库里还存在,比如集群环境分布式锁的算法漏洞就是因为这个同步延迟产生的。

LRU淘汰算法

当Redis内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换,交换会让Redis的性能急剧下降,对于访问量比较频繁的Redis来说,这样龟速的存取效率基本上等于不可用。

在生产环境中是不允许Redis出现交换行为的,为了限制最大使用内存,Redis提供了配置参数maxmemory来限制内存超出期望大小。

当实际内存超出maxmemory时,Redis提供了几种可选策略来让用户决定如何腾出新的空间以继续提供读写服务。

  • noeviction: 不会继续服务写请求(del请求除外),读请求可以继续进行,这样可以保证不会丢失数据,但是会让线上的业务不能持续进行,这是默认的淘汰策略。
  • volatile-lru: 尝试淘汰了设置过期时间的key,最少使用的key优先被淘汰。没有设置过期时间的key不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。
  • volatile-ttl: 跟上面一样,除了淘汰策略不是lru,而是key的剩余寿命ttl的值,ttl越小越优先被淘汰。
  • volatile-random:跟上面一样,淘汰的key是设置了过期时间的key集合中随机的key。
  • allkeys-lru:区别于volatile-lru,这个策略要淘汰的key对象是全体的key集合,而不是只是过期的key集合,这意味着没有设置过期时间的key也会被淘汰。
  • allkeys-random:所有的key中随机淘汰。

总结: volatile-xxx:该策略只会针对带过期时间的key进行淘汰,allkeys-xxx策略会针对所有的key进行淘汰。如果只是使用Redis做缓存,应该使用allkeys-xxx,客户端写缓存时不必携带过期时间。如果同时使用Redis的持久化功能,那就使用volatile-xxx策略,这样可以保留没有设置过期时间的key。

Redis的近似LRU算法

Redis使用的是一种近似LRU算法,他跟LRU算法不太一样,之所以不使用LRU算法,是因为需要消耗大量的额外内存,需要对现有的数据结构进行较大的改造。近似LRU算法则很简单,在现有数据结构的基础上采用随机采样法来淘汰元素,能达到和LRU算法非常近似的效果。

Redis为实现近似LRU算法,他给每个key增加了一个额外的小字段,这个字段的长度是24个bit,也就是最后一次被访问的时间戳。

上一节提到处理key过期方式分为集中处理和懒惰处理,LRU淘汰不一样,他的处理方式只有懒惰处理。当Redis执行写操作时,发现内存超出maxmemory,就会执行一次LRU淘汰算法,随机采样出5(可以配置)个key,然后淘汰掉最旧的key,如果淘汰后内存还是超出maxmemory,那就继续随机采样淘汰,直到内存低于maxmemory为止。

如何采样就是看maxmemory-policy的配置,如果是allkeys就是从所有的key字典中随机,如果是volatile就从带过期时间的key字典中随机。每次采样多少个key看的是maxmemory_samples的配置,默认是5.

在Redis3.0中算法增加了淘汰池,进一步提升了近似LRU算法的效果。淘汰池是一个数组,他的大小是maxmemory_samples,在每次淘汰循环中,新随机出来的key列表会和淘汰池中的key列表进行融合,淘汰掉最旧的一个key之后,保留剩余较旧的key列表放入淘汰池中等待下一个循环。

惰性删除

一直以来,我们认为Redis是单线程的,不过Redis内部实际上并不是只有一个主线程,他还有几个异步线程专门用来处理一些耗时操作。

Redis为什么要惰性删除

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

Redis为了解决这个卡顿问题,在4.0版本中引入了unlink指令,他能对删除操作进行惰性处理,丢给后台线程来异步回收内存。

使用多线程进行内存回收是否存在线程安全问题

不会,当unlink指令发出后,被unlink的key就再也无法被主线程中的其他指令访问到了。

flush

Redis提供了flushdb和flushall指令,用来清空数据库,这也是极其缓慢的操作。Redis4.0 同样给这两个指令也带来了异步化,在指令后面增加async参数就可以让后台线程慢慢处理,同时不会再被主线程访问到其中的key。

异步队列

主线程将对象的引用删除后,会将这个key的内存回收操作包装成一个任务,塞进异步任务队列,后台线程会从这个异步队列中取任务。任务队列被主线程和异步线程同时操作,所以必须是一个线程安全的队列。
在这里插入图片描述
不是所有的unlink操作都会延后处理,如果对应key所占用的内存很小,延后处理就没有必要了,这时候Redis会将对应的key内存立即回收,跟del指令一样。

AOF sync也很慢

Redis需要每秒一次同步AOF日志到磁盘,确保消息尽量不丢失,需要调用sync函数,这个操作会比较耗时,会导致主线程的效率下降,所以Redis也将这个操作移到异步线程来完成。执行AOF sync操作的线程是一个独立的异步线程,和前面的惰性删除线程不是一个线程,同样他也有一个属于自己的任务队列,队列里只用来存放AOF Sync任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/787951.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

生成随机密码

生成8位无重复的密码(可以包含数字、大小写字母) import random import string character string.digits string.ascii_letters password .join(random.sample(character, 8)) print(f"生成的随机密码为:{password}")

品牌策划秘籍:掌握这些技巧,让你的品牌一炮而红!

作为一名文案策划老司机,这么多年了,总会有一些经验的,这里分享出来,希望能够帮助后来人少走弯路吧。 想要做好品牌和文案策划,首先得做好“侦查”工作。 深入市场,了解行业动态,研究竞争对手…

智能遥测终端机RTU-精确监控 智能运维

智能遥测终端机RTU是物联网领域中一种重要的设备,它的出现无疑为远程监控和数据采集提供了强大的支持。计讯物联智能遥测终端机RTU具备数据采集、处理、通信和控制功能的设备,可以实现对远程设备的监控与控制。它在物联网系统中扮演着桥梁的角色&#xf…

【从零开始实现stm32无刷电机FOC】【理论】【3/6 位置、速度、电流控制】

目录 PID控制滤波单独位置控制单独速度控制单独电流控制位置-速度-电流串级控制 上一节,通过对SVPWM的推导,我们获得了控制电机转子任意受力的能力。本节,我们选用上节得到的转子dq轴解耦的SVPWM形式,对转子受力进行合理控制&…

AE-关键帧

目录 关键帧操作步骤(以位置变化为例) 1.确定动画起点 2.设置起点的位置属性 3.为起点打上关键帧 4.确定动画终点 5.设置终点的位置属性 改变动画速度 1.选中所有关键帧 2.拖拽 时间反向关键帧 1.选中要反向的关键帧 2.使用时间反向关键帧 …

Websocket 替代方案:如何使用 Firestore 监听实时事件

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 ​在现代 Web 开发中,实时更新功能对于许多应用程序(如聊天应用、协作工具和在线游戏)都是必不可少的。虽然 WebSocket 是一种常用的实时通信技术,但 Google 的 Firestore 也提供了一种强大的替代方案,使得实时监听变得…

数字信号处理教程(3)——z变换

在连续时间域中的每一种分析方法,在离散时间域中想必也能得到对应一种分析方法。连续傅里叶变换对应着离散傅里叶变换(DFT),而在拉普拉斯变换则是对应着z变换。z变换能够将信号表示成离散复指数函数的线性组合。连续傅里叶变换可以…

运维系列.Nginx配置文件结构功能总结

运维系列 Nginx配置文件结构功能总结 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_285…

泛微E-Cology getFileViewUrl SSRF漏洞复现

0x01 产品简介 泛微协同管理应用平台e-cology是一套兼具企业信息门户、知识文档管理、工作流程管理、人力资源管理、客户关系管理、项目管理、财务管理、资产管理、供应链管理、数据中心功能的企业大型协同管理平台。 0x02 漏洞概述 泛微E-Cology getFileViewUrl 接口处存在…

Java如何自定义注解及在SpringBoot中的应用

注解 注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说…

灵活多变的对象创建——工厂方法模式(Python实现)

1. 引言 大家好,又见面了!在上一篇文章中,我们聊了聊简单工厂模式,今天,我们要进一步探讨一种更加灵活的工厂设计模式——工厂方法模式。如果说简单工厂模式是“万能钥匙”,那工厂方法模式就是“变形金刚”…

Sorted Set 类型命令(命令语法、操作演示、命令返回值、时间复杂度、注意事项)

Sorted Set 类型 文章目录 Sorted Set 类型zadd 命令zrange 命令zcard 命令zcount 命令zrevrange 命令zrangebyscore 命令zpopmax 命令bzpopmax 命令zpopmin 命令bzpopmin 命令zrank 命令zscore 命令zrem 命令zremrangebyrank 命令zremrangebyscore 命令zincrby 命令zinterstor…

干货:高水平论文写作思路与方法

前言:Hello大家好,我是小哥谈。高水平论文的写作需要扎实的研究基础和严谨的思维方式。同时,良好的写作技巧和时间管理也是成功的关键。本篇文章转载自行业领域专家所写的一篇文章,希望大家阅读后可以能够有所收获。🌈 目录 🚀1.依托事实/证据,通过合理的逻辑,…

【MindSpore学习打卡】应用实践-热门LLM及其他AI应用-使用MindSpore实现K近邻算法对红酒数据集进行聚类分析

在机器学习领域,K近邻算法(K-Nearest Neighbor, KNN)是最基础且常用的算法之一。无论是分类任务还是回归任务,KNN都能通过简单直观的方式实现高效的预测。在这篇博客中,我们将基于MindSpore框架,使用KNN算法…

for nested data item, row-key is required.报错解决

今天差点被一个不起眼的bug搞到吐,就是在给表格设置row-key的时候,一直设置不成功,一直报错缺少row-key,一共就那两行代码 实在是找不到还存在什么问题... 先看下报错截图... 看下代码 我在展开行里面用到了一个表格 并且存放表格…

【算法】代码随想录之数组(更新中)

文章目录 前言 一、二分查找法(LeetCode--704) 二、移除元素(LeetCode--27) 前言 跟随代码随想录,学习数组相关的算法题目,记录学习过程中的tips。 一、二分查找法(LeetCode--704&#xff0…

WEB安全基础:网络安全常用术语

一、攻击类别 漏洞:硬件、软件、协议,代码层次的缺陷。 后⻔:方便后续进行系统留下的隐蔽后⻔程序。 病毒:一种可以自我复制并传播,感染计算机和网络系统的恶意软件(Malware),它能损害数据、系统功能或拦…

实战 | YOLOv8使用TensorRT加速推理教程(步骤 + 代码)

导 读 本文主要介绍如何使用TensorRT加速YOLOv8模型推理的详细步骤与演示。 YOLOv8推理加速的方法有哪些? YOLOv8模型推理加速可以通过多种技术和方法实现,下面是一些主要的策略: 1. 模型结构优化 网络剪枝:移除模型中不重要的神经元或连接,减少模型复杂度。 模型精…

大模型lora微调中,rank参数代表什么,怎么选择合适的rank参数

在大模型的LoRA(Low-Rank Adaptation)微调中,rank参数(秩)是一个关键的超参数,它决定了微调过程中引入的低秩矩阵的维度。具体来说,rank参数r表示将原始权重矩阵分解成两个低秩矩阵的维度&#…

突破传统,实时语音技术的革命。Livekit 开源代理框架来袭

🚀 突破传统,实时语音技术的革命!Livekit 开源代理框架来袭! 在数字化时代,实时通信已成为我们日常生活的一部分。但你是否曾想象过,一个能够轻松处理音视频流的代理框架,会如何改变我们的沟通方式?今天,我们就来一探究竟! 🌟 什么是 Livekit 代理框架? Live…