Redis原理篇——内存回收

news2024/11/15 9:47:35

Redis是基于内存存储的,性能强。Redis的性能瓶颈也在于内存,但是单节点内存不宜过大,会影响持久化或主从同步性能。

通过配置文件来设置Redis的最大内存:
在这里插入图片描述

一、过期策略

Redis是键值类型的数据库,所有的key和value保存在 Dict 结构中,在Redis数据库结构体中,有两个Dict:一个用来记录key-value,另一个记录key-TTL

typedef struct redisDb {
    dict *dict;                 /* 存放所有key和value */
    dict *expires;              /* 存放key和对应的TTL存活时间 只包含设置了TTL的key */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS (事务) */
    int id;                     /* Database ID 使用的是几号库 0~15 */
    long long avg_ttl;          /* Average TTL, 平均TTL时间 */
    unsigned long expires_cursor; /* expire检查时在dict中抽取的索引位置 */
    list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */
} redisDb;

在这里插入图片描述
因此只需要查Redis中的key对应的TTL,就可以判断这个key是否过期

删除策略

TTL到期就立刻删除吗?

可以设置定时器,当一个key到期了就立刻删除,但是对于大量key来说,设置大量定时器对CPU的占用率高,影响Redis主线程的性能,因此Redis不会立刻删除到期的key

1.惰性删除:

在访问一个key的时候检查该key的存活时间,如果已经过期了才执行删除。

robj *lookupKeyWriteWithFlags(redisDb *db, robj *key, int flags) {
     // 检查key是否过期
    expireIfNeeded(db,key);
    return lookupKey(db,key,flags);
}

robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
    robj *val;
      // 检查key是否过期
    if (expireIfNeeded(db,key) == 1) {
    /*
        ......... 略
    */ 
    
    }
   /*
        ......... 略
    */
}

int expireIfNeeded(redisDb *db, robj *key) {
      // 判断是否过期,如果没过期就返回0
    if (!keyIsExpired(db,key)) return 0;

    /*
        ......... 略
    */
  

    /* 删除过期的key */
    deleteExpiredKeyAndPropagate(db,key);
    return 1;
}

惰性删除存在的问题:

惰性删除是在访问一个key的时候检查是否过期,如果一个key过期了但是客户端长时间没有操作,那么这个key就一直不能被删除,如果这样的key存在大量的,那么就会一直占据着内存,影响性能。

2.周期删除

周期性的抽样一部分过期的key,然后执行删除。
执行周期有两种:

  • SLOW模式: Redis会设置一个定时任务serverCron(),按照server.hz的频率来执行过期key清理
  1. 执行频率受server.hz影响,默认为10,即每秒执行10次,每个执行周期100ms
  2. 执行清理耗时不超过一次执行周期的25%
  3. 逐个遍历db,抽取20个key判断是否过期
  4. 如果没达到时间上限(25ms)并且过期key比例大于10%,再进行一次抽样,否则结束
  • FAST模式: Redis的每个事件循环前会调用beforeSleep()函数,执行过期key清理
  1. 执行频率受beforeSleep()调用频率影响,但两次FAST模式间隔不低于2ms
  2. 执行清理耗时不超过1ms
  3. 依次遍历db,抽取20个key判断是否过期
  4. 如果没达到时间上限(1ms)并且过期key比例大于10%,再进行一次抽样,否则结束

二、内存淘汰策略

内存淘汰: Redis内存使用达到设置的阈值时,Redis主动挑选部分key删除以释放内存。

Redis支持8种不同的策略:

  • noeviction: 不淘汰任何key,内存满时不允许写入新数据(默认策略)
  • volatile-ttl:对设置TTL的key,比较剩余的TTL值,先淘汰数值小的
  • allkeys-random: 对全体key,随机进行淘汰。
  • volatile-random:对设置了TTL的key,随机淘汰。
  • allkeys-lru:对全体key,基于LRU算法进行淘汰
  • volatile-lru:对设置了TTL的key,基于LRU算法进行淘汰
  • allkeys-lfu:对全体key,基于LFU算法进行淘汰
  • volatile-lfu:对设置了TTL的key,基于LFU算法进行淘汰
typedef struct redisObject {
    unsigned type:4; // 对象类型,分别为五种基本数据类型  占4个bit位
    unsigned encoding:4; // 编码方式 11 中 占4个bit位
    unsigned lru:LRU_BITS; /*LRU以秒为单位记录最近一次访问时间,长度为24bit  LFU:高16位以分钟为单位记录最近一次访问时间,低8位记录逻辑访问次数*/
    int refcount;  // 引用计数器 0表示对象无人引用 可以被回收
    void *ptr;  // 指针,指向存放实际数据的空间
} robj;

LFU的访问次数之所以叫逻辑访问次数,是因为并不是每次key被访问都计数。而是通过运算:

  1. 生成0~1之间的随机数R
  2. 计算1/(旧次数*lfu_log_factor+1),记录为P,lfu_log_factor默认为10
  3. 如果R<P,计数器+1,最大不超过255
  4. 访问次数会随时间衰减,距离上一次访问时间每隔lfu_decay_time分钟(默认1),计数器-1

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

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

相关文章

MySQL高级语句(二)

一、VIEW&#xff08;视图&#xff09; 1、 概念 可以被当作是虚拟表或存储查询 视图跟表格的不同是&#xff0c;表格中有实际储存资料&#xff0c;而视图是建立在表格之上的一个架构&#xff0c;它本身并不实际储存资料。 临时表在用户退出或同数据库的连接断开后就自动消…

数据结构—链表

文章目录链表&#xff08;头插法、尾插法、单链表反转&#xff09;二分查找算法&#xff1a;哈夫曼编码构建链表insert()创建链表&#x1f447;【1】尾插法【2】头插法【3】遍历输出链表【4】输出链表的长度【5】查找链表上是否有该元素【6】指定位置插入数据链表经典面试题【1…

一文进阶什么是负载均衡,通俗易懂的全文解析

文章目录1 写在前面2 引言3 概念4 分类4.1 根据载体类型分类4.3 根据地域范围分类4.4 根据 OSI 网络模型分类4.5 对比(四层和七层)5 算法与实现5.1 随机法(Random)5.2 轮询法(Round Robin)5.3 加权轮询法(Weighted Round Robin)5.4 加权随机法(Weighted Random)5.5 最快响应速度…

从JDK8到JDK18,Java垃圾回收的详细解答

经历了数千次改进&#xff0c;Java 的垃圾回收在吞吐量、延迟和内存大小方面有了巨大的进步。 2014 年3 月 JDK 8 发布&#xff0c;自那以来 JDK 又连续发布了许多版本&#xff0c;直到今日的 JDK 18 是 Java 的第十个版本。借此机会&#xff0c;我们来回顾一下 HotSpot JVM 的…

python隶属关系图模型:基于模型的网络中密集重叠社区检测方法

隶属关系图模型 是一种生成模型&#xff0c;可通过社区联系产生网络。下图描述了一个社区隶属关系图和网络的示例&#xff08;图1&#xff09;。最近我们被客户要求撰写关于社区检测的研究报告&#xff0c;包括一些图形和统计输出。 图1.左&#xff1a;社区关系图&#xff08;圆…

ARM 汇编写启动代码之开 iCache

一、什么是 cache&#xff0c;有什么用 cache是一种内存&#xff0c;叫高速缓存。 从容量来说&#xff1a;CPU < 寄存器 < cache < DDR 从速度来说&#xff1a;CPU > 寄存器 > cache > DDRcache 的存在&#xff0c;是因为寄存器和 ddr 之间速度差异太大&a…

亚马逊云科技——云原生主题容器入门笔记

嗨&#xff0c;大家好&#xff0c;我是异星球的小怪同志 一个想法有点乱七八糟的小怪 如果觉得对你有帮助&#xff0c;请支持一波。 希望未来可以一起学习交流。 目录 一、容器入门课程 二、容器入门课堂笔记 1.容器背后的发展历史 2.区分容器与逻辑服务器的虚拟机 3.容…

号称 Java 圣经,Github 上爆火的 1058 页 JVM 全栈小册到底有什么魅力?

对于 JVM&#xff0c;我想大部分小伙伴都是要面试了才会去学&#xff0c;其余时间基本不会去看&#xff08;掐指一算&#xff0c;你们书架上面的深入理解 Java 虚拟机第三版应该都一层灰了吧【手动狗头】&#xff09;。但值得一说的是&#xff0c;当你工作多年之后&#xff0c;…

谷歌要完,百度也危了

文 | 天于刀刀当我们在抱怨搜索引擎的时候我们具体在说些什么&#xff1f;也许是饱受诟病的广告&#xff1f;或者是不合理的网页排序&#xff1f;又或是一种最直观的感觉——不好使。但是从来没有人抱怨过搜索引擎这一个模式。尽管这些年&#xff0c;也诞生一些诸如Magi这样让人…

Nginx配置实例-负载均衡

随着互联网信息的爆炸性增长&#xff0c;负载均衡&#xff08;load balance&#xff09;已经不再是一个很陌生的话题&#xff0c; 顾名思义&#xff0c;负载均衡即是将负载分摊到不同的服务单元&#xff0c;既保证服务的可用性&#xff0c;又保证响应 足够快&#xff0c;给用户…

Nginx安装搭建和环境准备教程(Ubantu)

本文以Ubantu18.08为例&#xff1a; 首先进入虚拟机中升级apt-get&#xff1a; apt-get update nginx进行安装&#xff1a; apt install nginx 使用命令查看nginx是否启动&#xff1a; systemctl status nginx nginx已经启动&#xff0c;可以到前端页面去访问是否真的已经启…

Vue项目中使用AntV G6绘制自适应图谱

Vue项目中使用AntV G6绘制自适应图谱 一、需求 需求1&#xff1a;Vue3.x项目下使用AntV G6绘制图谱 需求2&#xff1a;图谱节点为两个IP地址&#xff0c;节点间存在多条连线情况 需求3&#xff1a;鼠标悬浮到节点上方时&#xff0c;高亮当前节点并出现tooltip气泡提示&#…

Blackmagic黑魔法摄像机braw视频文件修复方法

Blackmagic是全球知名的影视级产品供应商&#xff0c;其高清摄像机是国内外各种剧组的最爱。Blackmagic的新产品目前使用braw格式&#xff0c;其编码采用自定义的raw编码&#xff0c;视频的效果和阿莱不相上下。近期我们处理了一例braw损坏无法播放的问题&#xff0c;我们来看看…

网络编程入门

什 么 是 网 络 编 程 网络编程的本质是多台计算机之间的数据交换。 数据传递本身没有多大的难度&#xff0c;不就是把一个设备中的数据发送给其他设备&#xff0c;然后接受另外一个设备反馈的数据。 现在的网络编程基本上都是基于请求/响应方式的&#xff0c;也就是一个设备发…

[附源码]计算机毕业设计基于springboot的小区宠物管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

css样式引入方式及优缺点

这篇文章主要介绍了css样式引入及优缺点&#xff0c;本文给大家分享三种css的引入方式&#xff0c;通过代码给大家介绍的非常详细&#xff0c;对大家的学习或工作具有一定的参考借鉴价值&#xff0c;需要的朋友参考下吧 三种css的引入方式 1.行内样式 优点&#xff1a;书写方…

【Python自然语言处理】文本向量化处理用户对不同类型服装评论问题(超详细 附源码)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 下面以文本向量化为目标&#xff0c;举例说明基于不同模型的实现过程&#xff0c;使用的数据集的主题是用户对不同类型的女性服装的评论&#xff0c;总共有23485条记录 实现步骤如下 一、导入库文件 首先导入需要的库文件…

MySQL数据库日志、备份与恢复

目录 前言 一.MySQL 日志管理 数据的重要性 造成数据丢失的原因 1、错误日志 2、通用查询日志 3、二进制日志 4、慢查询日志 5、查看日志 6.中继日志&#xff08;relay log&#xff09; 7、普通日志&#xff08;general log&#xff09; 配置文件 二、数据库备份的…

Metabase学习教程:系统管理-4

序列化&#xff1a;在Metabase实例间迁移 如何使用Metabase的序列化功能将问题、仪表板、集合、设置等从一个Metabase实例复制到新的Metabase实例。 Metabase序列化 序列化仅在商业版上可用&#xff08;仅在自托管计划上&#xff09;。 许多客户在迁移到本地部署的商业版时…

二叉树OJ题详解

第一题&#xff1a;单值二叉树 力扣链接&#xff1a;力扣 单值二叉树就是每一个节点存放的数据都相同&#xff0c;那么如何判断一棵树为单值二叉树呢&#xff1f;我们就拿最简单的一棵树为例子&#xff0c;比如根节点为1它的左子树和右子树也为1的一棵树&#xff0c;我们只需要…