Redis 内存回收

文章目录

  • 1. 过期key处理
    • 1.1 惰性删除
    • 1.2 周期删除
  • 2. 内存淘汰策略


在这里插入图片描述

Redis 中数据过期策略采用定期删除+惰性删除策略结合起来,以及采用淘汰策略来兜底。

定期删除策略:Redis 启用一个定时器定时监视所有的 key,判断key是否过期,过期的话就删除。这种策略可以保证过期的 key 最终都会被删除,但是也存在严重的缺点:每次都遍历内存中所有的数据,非常消耗 CPU 资源,并且当 key 已过期,但是定时器还处于未唤起状态,这段时间内 key 仍然可以用。

惰性删除策略:在获取 key 时,先判断 key 是否过期,如果过期则删除。这种方式存在一个缺点:如果这个 key 一直未被使用,那么它一直在内存中,其实它已经过期了,会浪费大量的空间。

这两种策略天然的互补,结合起来之后,定时删除策略就发生了一些改变,不在是每次扫描全部的 key 了,而是随机抽取一部分 key 进行检查,这样就降低了对 CPU 资源的损耗,惰性删除策略互补了为检查到的key,基本上满足了所有要求。但是有时候就是那么的巧,既没有被定时器抽取到,又没有被使用,这些数据又如何从内存中消失?没关系,还有内存淘汰机制,当内存不够用时,内存淘汰机制就会上场。

内存淘汰机制
内存淘汰机制就保证了在redis的内存占用过多的时候,去进行内存淘汰,也就是删除一部分key,保证redis的内存占用率不会过高。

redis 提供 6种数据淘汰策略:
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中随机移除key
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,无法写入新数据,一般不采用
4.0版本后增加以下两种:
volatile-lfu:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰
allkeys-lfu:当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的key


1. 过期key处理

Redis之所以性能强,最主要的原因就是基于内存存储。然而单节点的Redis其内存大小不宜过大,会影响持久化或主从同步性能。我们可以通过修改配置文件来设置Redis的最大内存:
1653983341150.png
当内存使用达到上限时,就无法存储更多数据了。为了解决这个问题,Redis提供了一些策略实现内存回收:
内存过期策略
在学习Redis缓存的时候我们说过,可以通过expire命令给Redis的key设置TTL(存活时间):
1653983366243.png

可以发现,当key的TTL到期以后,再次访问name返回的是nil,说明这个key已经不存在了,对应的内存也得到释放。从而起到内存回收的目的。
Redis本身是一个典型的key-value内存存储数据库,因此所有的key、value都保存在之前学习过的Dict结构中。不过在其database结构体中,有两个Dict:一个用来记录key-value;另一个用来记录key-TTL。

这里有两个问题需要我们思考:Redis是如何知道一个key是否过期呢?
利用两个Dict分别记录key-value对及key-ttl对
是不是TTL到期就立即删除了呢?

1.1 惰性删除

惰性删除:顾明思议并不是在TTL到期后就立刻删除,而是在访问一个key的时候,检查该key的存活时间,如果已经过期才执行删除。
1653983652865.png

1.2 周期删除

周期删除:顾明思议是通过一个定时任务,周期性的抽样部分过期的key,然后执行删除。执行周期有两种:
Redis服务初始化函数initServer()中设置定时任务,按照server.hz的频率来执行过期key清理,模式为SLOW
Redis的每个事件循环前会调用beforeSleep()函数,执行过期key清理,模式为FAST

周期删除:顾明思议是通过一个定时任务,周期性的抽样部分过期的key,然后执行删除。执行周期有两种:
Redis服务初始化函数initServer()中设置定时任务,按照server.hz的频率来执行过期key清理,模式为SLOW
Redis的每个事件循环前会调用beforeSleep()函数,执行过期key清理,模式为FAST

SLOW模式规则:

  • 执行频率受server.hz影响,默认为10,即每秒执行10次,每个执行周期100ms。
  • 执行清理耗时不超过一次执行周期的25%.默认slow模式耗时不超过25ms
  • 逐个遍历db,逐个遍历db中的bucket,抽取20个key判断是否过期
  • 如果没达到时间上限(25ms)并且过期key比例大于10%,再进行一次抽样,否则结束
  • FAST模式规则(过期key比例小于10%不执行 ):
  • 执行频率受beforeSleep()调用频率影响,但两次FAST模式间隔不低于2ms
  • 执行清理耗时不超过1ms
  • 逐个遍历db,逐个遍历db中的bucket,抽取20个key判断是否过期
    如果没达到时间上限(1ms)并且过期key比例大于10%,再进行一次抽样,否则结束

小总结:
RedisKey的TTL记录方式:
在RedisDB中通过一个Dict记录每个Key的TTL时间
过期key的删除策略:
惰性清理:每次查找key时判断是否过期,如果过期则删除
定期清理:定期抽样部分key,判断是否过期,如果过期则删除。
定期清理的两种模式:
SLOW模式执行频率默认为10,每次不超过25ms
FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

2. 内存淘汰策略

内存淘汰:就是当Redis内存使用达到设置的上限时,主动挑选部分key删除以释放更多内存的流程。Redis会在处理客户端命令的方法processCommand()中尝试做内存淘汰:1653983978671.png

淘汰策略
Redis支持8种不同策略来选择要删除的key:

  • noeviction: 不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略(不推荐使用)
  • volatile-ttl: 对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰
  • allkeys-random:对全体key ,随机进行淘汰。也就是直接从db->dict中随机挑选
  • volatile-random:对设置了TTL的key ,随机进行淘汰。也就是从db->expires中随机挑选。
  • allkeys-lru: 对全体key,基于LRU算法进行淘汰
  • volatile-lru: 对设置了TTL的key,基于LRU算法进行淘汰
  • allkeys-lfu: 对全体key,基于LFU算法进行淘汰
  • volatile-lfu: 对设置了TTL的key,基于LFI算法进行淘汰比较容易混淆的有两个:
    • LRU(Least Recently Used),最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
    • LFU(Least Frequently Used),最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。

可以通过在Redis的配置文件中设置maxmemory-policy选项来选择合适的内存淘汰策略。

例如,将其设置为allkeys-lru:

maxmemory-policy allkeys-lru


在这里插入图片描述

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

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

相关文章

深入理解Java多态:灵活性与可扩展性的完美结合

多态(Polymorphism)是面向对象编程(Object-Oriented Programming, OOP)的核心概念之一。多态性允许一个接口或方法适用于不同的对象类型,从而实现代码的重用性和灵活性。本文将深入探讨Java中的多态性,包含…

【JavaScript脚本宇宙】探索JavaScript拖放库世界:特性、示例与应用场景

解锁JavaScript拖放神器:库特性对比及最佳实践分享 前言 JavaScript拖放库在现代Web开发中扮演着重要角色,为用户提供了直观的交互体验。从基本的拖拽功能到复杂的多点触控手势,这些库使开发人员能够轻松地实现各种拖放效果,为网…

如何使用Python中的os模块进行文件和目录操作

Python中的os模块提供了许多与操作系统交互的函数,包括文件和目录操作。以下是一些使用os模块进行文件和目录操作的基本示例: 1. 获取当前工作目录 python复制代码 import os current_dir os.getcwd() print(current_dir) 2. 改变当前工作目录 pytho…

Linux安装Qt5.14.2

下载 qt 5.14.2下载网址 下载qt-opensource-linux-x64-5.14.2.run Linux系统下载.run文件(runfile文件),windows系统下载.exe文件,mac系统下载.dmg文件。 md5sums.txt中是各个文件对应的MD5校验码。 验证MD5校验码 md5sum是li…

简单使用phpqrcode 生成二维码图片

$path ROOT_PATH; //tp项目根路径 require_once $path.vendor/phpqrcode/phpqrcode.php; //加载phpqrcode库 $url http://.$_SERVER[HTTP_HOST]./home/index/detail?id.$param[id]; $value $url; //二维码内容 $errorCorrectionLevel L; //容错级别 $mat…

Elasticsearch之深入聚合查询

1、正排索引 1.1 正排索引(doc values )和倒排索引 概念:从广义来说,doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP 和不分词( no…

指针(初阶1)

一.指针是什么 通俗的讲,指针就是地址,其存在的意义就像宾馆房间的序号一样是为了更好的管理空间。 如下图: 如上图所示,指针就是指向内存中的一块空间,也就相当于地址 二.一个指针的大小是多少 之前我们学习过&#x…

面试专区|【43道Java多线程高频题整理(附答案背诵版)】

请说一下进程和线程的区别? 进程和线程都是操作系统进行任务管理的基本单位,但它们之间存在一些关键的区别。 独立性:进程是操作系统分配资源(如CPU时间、内存空间等)的基本单位,它是相互独立的,一个进程…

数据结构之ArrayList与顺序表(下)

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:数据结构(Java版) 目录 ArrayList的具体使用 118. 杨辉三角 扑克洗牌算法 接上篇:数据结构之ArrayLis…

【环境搭建】2.阿里云ECS服务器 安装MySQL

在阿里云的 Alibaba Cloud Linux 3.2104 LTS 64位系统上安装 MySQL 8,可以按照以下步骤进行: 1.更新系统软件包: 首先,更新系统软件包以确保所有软件包都是最新的: sudo yum update -y2.下载 MySQL 8 官方 Yum 仓库…

【Python列表解锁】:掌握序列精髓,驾驭动态数据集合

文章目录 🚀一、列表🌈二、常规操作💥增💥删💥改💥查 ⭐三、补充操作 🚀一、列表 列表是一个能够存储多个同一或不同元素的序列 列表:list ---- [] 列表属于序列类型(容器…

【Java面试】十二、Kafka相关

文章目录 1、Kafka如何保证消息不丢失1.1 生产者发消息到Brocker丢失:设置异步发送1.2 消息在Broker存储时丢失:发送确认机制1.3 消费者从Brocker接收消息丢失1.4 同步 异步组合提交偏移量 2、Kafka如何保证消费的顺序性3、Kafka高可用机制3.1 集群模式…

深度搜索算法2(c++)

红与黑 题目描述 有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑 色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。 输入 包括多组数据。每组数据的第一行是两个…

Vue.js ECharts使用

一、介绍 ECharts 是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,满足各种需求。ECharts 提供了丰富的图表类型和交互能力,使用户能够通过简单的配置生成各种各样的图表,包括但不限于折线图、柱状图、散点图、饼图、雷…

02Linux文件,目录,过滤,管道常用命令

Linux基础概述 Linux基础目录 Linux没有盘符这个概念, 只有一个顶级根目录 /, 所有文件都在它下面 在Windows系统中路径之间的层级关系使用/来表示在Linux系统中路径之间的层级关系使用/来表示,出现在开头的/表示根目录, /home/a.txt表示根目录下的home文件夹内有a.txt文件 …

2024年6月8日_第十五周_周六_分享技术:麻将技术

四人下午打麻将大纲 一、背景设定 时间:一个悠闲的下午地点:某人家中的麻将室或客厅人物: A先生:一个经验丰富的麻将老手,喜欢沉稳地分析牌局B女士:麻将新手,但好学不倦,喜欢尝试新…

微服务开发与实战Day03

一、导入黑马商城项目 资料文档:Docs 1. 安装MySQL ①删除root目录下的mysql rm -rf mysql/ ②把课前资料里的mysql目录上传到root目录下 ③创建一个通用网络 docker network create hm-net ④使用下面的命令安装MySQL docker run -d \--name mysql \-p 330…

自然资源-国土空间规划术语集合

自然资源-国土空间规划术语集合 国土空间: 国家主权与主权权利管辖下的地域空间,是人类生产生活的载体和场所,包括陆地国土空间和海洋国土空间。 国土空间规划: 对一定区域国土空间开发保护在空间和时间上作出的安排&#xff…

C++ OpenCV 图像分类魔法:探索神奇的模型与代码

⭐️我叫忆_恒心,一名喜欢书写博客的研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支…

TensorFlow2.x基础与mnist手写数字识别示例

文章目录 Github官网文档Playground安装声明张量常量变量 张量计算张量数据类型转换张量数据维度转换ReLU 函数Softmax 函数卷积神经网络训练模型测试模型数据集保存目录显示每层网络的结果 TensorFlow 是一个开源的深度学习框架,由 Google Brain 团队开发和维护。它…