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任务。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C++] 由C语言过渡到C++的敲门砖

命名空间 在C/C中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染 。 在同一个工程中…

Python基础-成年人判断(if条件语句联系)

注意输入的年龄需要转化为字符串 代码: print("欢迎来到游乐场:儿童免费,成人收费") age int(input("请输入你的年龄:")) if age>18:print("你已经成年,需要补票10元") # 四个空格缩进print…

使用ssh服务器管理远程主机

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、配置网卡服务 1、配置网卡参数 2、创建网络会话 3、绑定两块网卡 二、远程控制服务 1、配置sshd服务 2、在Windows连接 3、安全密钥…

代码随想录算法训练营第12天|150. 逆波兰表达式求值、239. 滑动窗口最大值、347. 前 K 个高频元素

在补在补了 打卡Day12 1.150. 逆波兰表达式求值2.239. 滑动窗口最大值3.347. 前 K 个高频元素总结 1.150. 逆波兰表达式求值 题目链接:逆波兰表达式求值 文档讲解: 代码随想录 class Solution(object):def evalRPN(self, tokens):""":t…

数据仓库哈哈

数据仓库 基本概念数据库(database)和数据仓库(Data Warehouse)的异同 整体架构分层架构方法论ER模型(建模理论)维度模型 何为分层第一层:数据源(ODS ER模型)设计要点日志…

华为机考真题 -- 小明找位置

题目描述: 小朋友出操,按学号从小到大排成一列;小明来迟了,请你给小明出个主意,让他尽快找到他应该排的位置。算法复杂度要求不高于nLog(n);学号为整数类型,队列规模<=10000; 输入描述: 1、第一行:输入已排成队列的小朋友的学号(正整数),以”,”隔开;例如:…

Studying-代码随想录训练营day34| 62.不同路径、63.不同路径II、343.整数拆分、96.不同的二叉搜索树

第34天&#xff0c;动态规划part02&#xff0c;牢记五部曲步骤&#xff0c;编程语言&#xff1a;C 目录 62.不同路径 63.不同路径II 343.整数拆分 96.不同的二叉搜索树 总结 62.不同路径 文档讲解&#xff1a;代码随想录不同路径 视频讲解&#xff1a;手撕不同路径 题目…

CPU/内存/综合性能评估工具汇总-2:stream

目录 一、概括二、stream 一、概括 嵌入式开发中对要设计的产品、立项的项目进行设计时&#xff0c;往往需要对关键芯片进行性能评估&#xff0c;本文主要总结基于linux系统的产品在性能评估时的工具使用总结&#xff0c;在aarch64(arm64平台下测试)&#xff0c;板卡根文件系统…

源码编译构建LAMP(企业网站架构部署与优化)

部署LAMP平台 LAMV架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c;能够提供动态Web站点服务及其应用开发环境。LAMP是一个缩写词&#xff0c;具体包 括 Linux操作系统&#xff0c;Apache网站服务器、MySQL数据库服务器、P…

【Python】基础语法体系:两种常用语句

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言条件语句动态实例if语句if-else 语句if-elif-else 语句嵌套条件语句 循环语句for循环while循环 动态实例嵌套循环 前言 Python语句是构成Python程序的基本单元&#xff0c;用…

优化VOI(Virtual Operating System Infrastructure,虚拟操作系统基础架构)架构的性能

优化VOI&#xff08;Virtual Operating System Infrastructure&#xff0c;虚拟操作系统基础架构&#xff09;架构的性能&#xff0c;可以从多个方面入手&#xff0c;以确保系统能够更高效、更稳定地运行。以下是一些优化建议&#xff1a; 1. 优化硬件资源利用 本地硬件资源最…

JavaScript 基础:掌握JavaScript基础语法(一)

一、JavaScript 字面量 在编程语言中&#xff0c;一般固定值称为字面量&#xff0c;如 3.14。 1&#xff09;数字&#xff08;Number&#xff09;字面量 可以是整数或者是小数&#xff0c;或者是科学计数(e)。 3.14 1001 123e5 2&#xff09;字符串&#xff08;String&…

磁力猫官网cilimao,获取磁力链接的操作步骤

磁力猫磁力链接是一种特殊的下载链接&#xff0c;磁力猫磁力链接可以理解为一个文件识别码&#xff0c;而并非具体的资源地址&#xff0c;下载软件需要拿着这个识别码去整个互联网(DHT网络)去寻找持有该资源的用户(节点)&#xff0c;如果找到则可以进行传输下载。一般年代越久远…

Innodisk宣布启用第二期研发与生产中心,发力扩展边缘AI解决方案产能

Innodisk 公司于2024年7月9日在台湾宜兰揭幕了其研发与生产中心第二阶段&#xff0c;旨在扩大边缘人工智能&#xff08;Edge AI&#xff09;解决方案的生产能力。此举是对边缘AI浪潮所带动的庞大市场需求的直接响应&#xff0c;标志着公司将制造工厂转变为集团AI核心基地的重要…

C++之goto陈述

关键字 goto用于控制程式执行的顺序&#xff0c;使程式直接跳到指定标签(lable) 的地方继续执行。 形式如下 标签可以是任意的识别字&#xff0c;后面接一个冒号。 举例如下 #include <iostream>int main() {goto label_one;label_one: {std::cout << "Lab…

Taro自定义实现本地路径转换为文件

在用Taro写头像上传功能时&#xff0c;因为需要对获得的图片进行剪切成圆形或方形。使用组件剪切完之后返回的是一个本地图片的相对路径。这个时候我们就需要自己实现将本地路径重新转换为二进制文件。 引入两个js文件 mimeMap.js module.exports {"0.001": &quo…

vue3 插件

富文本插件 wangeditor https://www.wangeditor.com/v5/for-frame.html 官网地址 安装 yarn add wangeditor/editor # 或者 npm install wangeditor/editor --saveyarn add wangeditor/editor-for-vuenext # 或者 npm install wangeditor/editor-for-vuenext --save使用impor…

凸包——G - Highest Ratio

G - Highest Ratio 来源&#xff1a;AtCoder Beginner Contest 341-G 题目描述&#xff1a; 给定长度为 N N N 的序列 A ( A 1 , A 2 , … , A N ) A (A_1, A_2, \ldots, A_N) A(A1​,A2​,…,AN​)。 对于每个 k 1 , 2 , … , N k 1, 2, \ldots, N k1,2,…,N&#…

看懂什么是Halo2

目录 Halo2(零知识证明框架)是什么 Halo2概述 Halo2的原理 电路开发 斐波那契数列举例说明 Halo2的应用 结论 PLONK算法是什么 PLONK算法概述 PLONK算法原理 1. 电路描述与约束 2. 多项式表达与验证 3. 初始设置与随机性 PLONK举例说明 PLONK例子:验证简单的…

【漏洞复现】29网课交单平台 SQL注入

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 29网课交单平台是一个在线学习平台&#xff0c;用于帮助学生完成网络课程的学习任务。这个平台提供了包括…