当前位置: 首页 > news >正文

Redis系列-Redis过期策略以及内存淘汰机制【6】

目录

  • Redis系列-Redis过期策略以及内存淘汰机制【6】
    • redis过期策略
    • 内存淘汰机制
    • 算法
      • LRU算法
      • LFU
    • 其他场景对过期key的处理
    • FAQ
      • 为什么不用定时删除策略?
    • Ref

个人主页: 【⭐️个人主页】
需要您的【💖 点赞+关注】支持 💯


Redis系列-Redis过期策略以及内存淘汰机制【6】

在这里插入图片描述

redis主要是基于内存来进行高性能、高并发的读写操作的。但既然内存是有限的,例如redis就只能使用10G,你写入了20G。这个时候就需要清理掉10G数据,保留10G数据。那应该保留哪些数据,清除哪些数据,为什么有些数据明明过期了,怎么还占用着内存?这都是由redis的过期策略来决定的。

在这里插入图片描述

redis过期策略

​ redis的过期策略就是:定期删除 + 惰性删除

定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查是否过期,如果过期就删除。

🅰️ 100ms怎么来的?
在Redis的配置文件redis.conf中有一个属性"hz",默认为10

表示1s执行10次定期删除,即每隔100ms执行一次,可以修改这个配置值。

在这里插入图片描述
🅱️ 随机抽取一些检测,一些是多少?

同样是由redis.conf文件中的maxmemory-samples属性决定的,默认为5。
在这里插入图片描述

在Redis的配置文件redis.conf中有一个属性"hz",默认为10,表示1s执行10次定期删除,即每隔100ms执行一次,可以修改这个配置值。

​ 假设redis里放了10W个key,都设置了过期时间,你每隔几百毫秒就检查全部的key,那redis很有可能就挂了,CPU负载会很高,都消耗在检查过期的key上。注意,这里不是每隔100ms就遍历所有设置过期时间的key,那样就是一场性能灾难。实际上redis是每隔100ms就随机抽取一些key来检查和删除的。

​ 定期删除可能会导致很多过期的key到了时间并没有被删除掉。这个时候就可以用到惰性删除了。

惰性删除 是指在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间并且已经过期了,此时就会删除,不会给你返回任何东西。

​ 但即使是这样,依旧有问题。如果定期删除漏掉了很多过期的key,然后你也没及时去查,也就没走惰性删除。此时依旧有可能大量过期的key堆积在内存里,导致内存耗尽。

​ 这个时候就需要内存淘汰机制了。

内存淘汰机制

redis.conf中有一行配置 ,该配置就是配内存淘汰策略

# maxmemory-policy volatile-lru

redis·内存淘汰机制有以下几个:

  1. noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。这个一般很少用。
  2. allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key,这个是最常用的。
  3. allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
  4. volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
  5. volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
  6. volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
  7. allkeys-lfu,淘汰整个键值中最少使用的键值,这也就是我们常说的LRU算法。 【Redis4.0】
  8. volatile-lfu,淘汰所有设置了过期时间的键值中最少使用的键值【Redis4.0】

而在Redis4.0版本中又新增了2种淘汰策略:

allkeys-lfu,淘汰整个键值中最少使用的键值,这也就是我们常说的LRU算法。
volatile-lfu,淘汰所有设置了过期时间的键值中最少使用的键值
通过上面的内存淘汰策略可以看出,以 allkeys- 开头的表示从所有key中进行数据淘汰,而以 volatile- 开头的会从设置了过期时间的key中进行数据淘汰。

算法

  • LRU(Least Recently Used,最近最少使用),根据最近被使用的时间,离当前最远的数据优先被淘汰;
  • LFU(Least Frequently Used,最不经常使用),在一段时间内,缓存数据被使用次数最少的会被淘汰。

LRU算法

​ 上面的内存淘汰机制中,用到的是LRU算法。什么是LRU算法?LRU算法其实就是上面说的最近最少使用策略。

实现LRU算法,大概的思路如下:

1.​ 维护一个有序单链表,越靠近链表尾部的节点是越早之前访问的。当有一个新的数据被访问时,我们从链表头开始顺序遍历链表:
2. 如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的节点,并将其从原来的位置删除,然后再插入到链表的头部。
3. 如果此数据没有在缓存链表中,又可以分为两种情况:
- 如果此时缓存未满,则将此节点直接插入到链表的头部;
- 如果此时缓存已满,则链表尾节点删除,将新的数据节点插入链表的头部。

​ 这就就实现了LRU算法。

​ 当然我们也可以基于Java现有的数据结构LinkedHashMap手撸一个。LinkHashMap本质上是一个Map与双向链表的结合,比起上述的单链表,效率更高。代码如下:

class LRUCache<K, V> extends LinkedHashMap<K, V> {private final int CACHE_SIZE;/*** 传递进来最多能缓存多少数据** @param cacheSize 缓存大小*/public LRUCache(int cacheSize) {// true 表示让 linkedHashMap 按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾部。super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);CACHE_SIZE = cacheSize;}@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {// 当 map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。return size() > CACHE_SIZE;}
}

LFU

在Redis LFU算法中,为每个key维护了一个计数器,每次key被访问的时候,计数器增大,计数器越大,则认为访问越频繁。但其实这样会有问题,

1、因为访问频率是动态变化的,前段时间频繁访问的key,之后也可能很少再访问(如微博热搜)。为了解决这个问题,Redis记录了每个key最后一次被访问的时间,随着时间的推移,如果某个key再没有被访问过,计数器的值也会逐渐降低。

2、新生key问题,对于新加入缓存的key,因为还没有被访问过,计数器的值如果为0,就算这个key是热点key,因为计数器值太小,也会被淘汰机制淘汰掉。为了解决这个问题,Redis会为新生key的计数器设置一个初始值。

上面说过在Redis LRU算法中,会给每个key维护一个大小为24bit的属性字段,代表最后一次被访问的时间戳。在LFU中也维护了这个24bit的字段,不过被分成了16 bits与8 bits两部分:

16 bits 8 bits
±-------------------±-----------+

  • Last decr time | LOG_C |

±-------------------±----------+

其中高16 bits用来记录计数器的上次缩减时间,时间戳,单位精确到分钟。低8 bits用来记录计数器的当前数值。

在redis.conf配置文件中还有2个属性可以调整LFU算法的执行参数:lfu-log-factor、lfu-decay-time。其中lfu-log-factor用来调整计数器counter的增长速度,lfu-log-factor越大,counter增长的越慢。lfu-decay-time是一个以分钟为单位的数值,用来调整counter的缩减速度。

其他场景对过期key的处理

1、快照生成RDB文件时

过期的key不会被保存在RDB文件中。

2、服务重启载入RDB文件时

Master载入RDB时,文件中的未过期的键会被正常载入,过期键则会被忽略。Slave 载入RDB 时,文件中的所有键都会被载入,当主从同步时,再和Master保持一致。

3、AOF 文件写入时

因为AOF保存的是执行过的Redis命令,所以如果redis还没有执行del,AOF文件中也不会保存del操作,当过期key被删除时,DEL 命令也会被同步到 AOF 文件中去。

4、重写AOF文件时

执行 BGREWRITEAOF 时 ,过期的key不会被记录到 AOF 文件中。

5、主从同步时

Master 删除 过期 Key 之后,会向所有 Slave 服务器发送一个 DEL命令,Slave 收到通知之后,会删除这些 Key。Slave 在读取过期键时,不会做判断删除操作,而是继续返回该键对应的值,只有当Master 发送 DEL 通知,Slave才会删除过期键,这是统一、中心化的键删除策略,保证主从服务器的数据一致性。

FAQ

为什么不用定时删除策略?

定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.

Ref

https://blog.csdn.net/yuanlong122716/article/details/104420880

相关文章:

Redis系列-Redis过期策略以及内存淘汰机制【6】

目录 Redis系列-Redis过期策略以及内存淘汰机制【6】redis过期策略内存淘汰机制算法LRU算法LFU 其他场景对过期key的处理FAQ为什么不用定时删除策略? Ref 个人主页: 【⭐️个人主页】 需要您的【&#x1f496; 点赞关注】支持 &#x1f4af; Redis系列-Redis过期策略以及内存淘…...

多语言翻译软件 Mate Translate mac中文版特色功能

Mate Translate for Mac是一款多语言翻译软件&#xff0c;Mate Translate mac可以帮你翻译超过100种语言的单词和短语&#xff0c;使用文本到语音转换&#xff0c;并浏览历史上已经完成的翻译。你还可以使用Control S在弹出窗口中快速交换语言。 Mate Translate Mac版特色功能…...

Python GUI标准库tkinter实现与记事本相同菜单的文本编辑器(一)

介绍&#xff1a; Windows操作系统中自带了一款记事本应用程序&#xff0c;通常用于记录文字信息&#xff0c;具有简单文本编辑功能。Windows的记事本可以新建、打开、保存文件&#xff0c;有复制、粘贴、删除等功能&#xff0c;还可以设置字体类型、格式和查看日期时间等。 …...

Decimal.ToString()堆栈溢出异常

Decimal.ToString() 堆栈溢出异常 导致以下报错: A process serving application pool XXX suffered a fatal communication error with the Windows Process Activation Service. The process id was 7132. The data field contains the error number. Application pool …...

com.genuitec.eclipse.springframework.springnature

Your IDE is missing natures to properly support your projects. Some extensions on the eclipse marketplace can be installed to support those natures. com.genuitec.eclipse.springframework.springnature 移除 <nature>om.genuitec.eclipse.springframework.…...

wangeditor富文本编辑器的使用(vue)

官网 官方demo 参考 安装 yarn add wangeditor/editor yarn add wangeditor/editor-for-vue 封装的富文本组件 <template><div style"border: 1px solid #ccc"><Toolbarstyle"border-bottom: 1px solid #ccc":editor"editorRef"…...

物联网水表有什么弊端吗?

物联网水表作为新一代智能水表&#xff0c;虽然在很大程度上提高了水资源的管理效率&#xff0c;但也存在一定的弊端。在这篇文章中&#xff0c;我们将详细讨论物联网水表的弊端&#xff0c;以帮助大家更全面地了解这一技术。 一、安全隐患 1.数据泄露&#xff1a;物联网水表通…...

安卓 车轮视图 WheelView kotlin

安卓 车轮视图 WheelView kotlin 前言一、代码解析1.初始化2.初始化数据3.onMeasure4.onDraw5.onTouchEvent6.其他 6.ItemObject二、完整代码总结 前言 有个需求涉及到类似这个视图&#xff0c;于是在网上找了个轮子&#xff0c;自己改吧改吧用&#xff0c;拿来主义当然后&…...

升级Redisson版本兼容问题

升级版本&#xff1a;从 3.10.6 升级到3.18.0 报错: java.io.IOException: Unsupported protocol version 252 java.io.IOException: Unsupported protocol version 252at org.jboss.marshalling.river.RiverUnmarshaller.start(RiverUnmarshaller.java:1375)at org.redisson…...

前端框架Bootstrap

前端框架Bootstrap 该框架已经帮我们写好了很多页面样式&#xff0c;如果需要使用&#xff0c;只需要下载对应文件 直接CV拷贝即可 在使用Bootstrap的时候&#xff0c;所有的页面样式只需要通过修改class属性来调节即可 什么是Bootstrap Bootstrap是一个开源的前端框架…...

Flink SQL TopN语句详解

TopN 定义&#xff08;⽀持 Batch\Streaming&#xff09;&#xff1a; TopN 对应离线数仓的 row_number()&#xff0c;使⽤ row_number() 对某⼀个分组的数据进⾏排序。 应⽤场景&#xff1a; 根据 某个排序 条件&#xff0c;计算 某个分组 下的排⾏榜数据。 SQL 语法标准&am…...

k8s之数据卷

一&#xff0c;存储卷 容器磁盘上的文件的生命周期是短暂的&#xff0c;这就使得在容器中运行重要应用时会出现一些问题。首先&#xff0c;当容器崩溃时&#xff0c;kubelet 会重启它&#xff0c;但是容器中的文件将丢失——容器以干净的状态&#xff08;镜像最初的状态&#…...

服务器网络

配置 通常使用ping查看网络 如果能ping通&#xff0c;不能ssh登陆&#xff0c;安装 sudo apt update sudo apt install openssh-server如果已经安装&#xff0c;查看防火墙状态&#xff0c;inactive(不活跃) sudo ufw status sudo ufw allow ssh sudo ufw reload查看ssh状态 s…...

YOLOv8-seg 分割代码详解(一)Predict

前言 本文从 U-Net 入手熟悉分割的简单方法&#xff0c;再看 YOLOv8 的方法。主要梳理 YOLOv8 的网络结构&#xff0c;以及 Predict 过程的后处理方法。 U-Net 代码地址&#xff1a;https://github.com/milesial/Pytorch-UNet YOLOv8 代码地址&#xff1a;https://github.com/…...

Docker学习——④

文章目录 1、Docker Image&#xff08;镜像&#xff09;2、镜像命令详解2.1 docker rmi2.2 docker save2.3 docker load2.4 docker image inspect2.5 docker history2.6 docker image prune 3、镜像综合实战3.1 离线镜像迁移3.2 镜像存储的压缩与共享 1、Docker Image&#xff…...

Android选项卡TabHost

选项卡主要由TabHost(标签&#xff0c;主人)&#xff0c;TabWidget(微件)和FrameLayout3个组件组成&#xff0c;用于实现一个多标签页的用户界面。 1. TabHost在XML文件中添加&#xff1a; XML布局文件中添加选项卡时必须使用系统id来为各组件指定id属性。 <TabHostandro…...

qml添加滚动条

import QtQuick.Controls 2.15ScrollBar.vertical: ScrollBar {visible: flick1.contentHeight > flick1.heightanchors.right: parent.rightanchors.rightMargin: 40width: 10active: truecontentItem: Rectangle {radius: 6opacity: 0.5color: "#7882A0"} }...

elementui-plus el-tree组件数据不显示问题解决

当前情况: 显示: 注意看右侧的树是没有文字的,数据已经渲染,个数是对的,但就是没有文字, 解决: 对比以后发现是template中的#default{data}没有写大括号导致的 所以写上大括号后: 正常显示...

EMR 磁盘挂载解读与磁盘扩容操作

云上的计算实例挂载的存储盘通常可以在线实现磁盘扩容。本文以 AWS EMR 节点的磁盘扩容为例,记录一下具体的操作步骤。在详细介绍前,先将重要的总结发在前面,便于以后查阅: EMR 磁盘分配规则是: 第一磁盘(/dev/nvme0n1),必备,大小由控制台的"EBS root volume&qu…...

小程序day04

目标 自定义组件 创建组件 引用组件 局部引用 全局引用 组件的函数定义到metods节点中&#xff0c;梦回vue2. 样式 数据&#xff0c;方法&#xff0c;属性 下划线开头的称为自定义方法&#xff0c;非下划线开头的都是事件处理函数。 神特么&#xff0c;this.datathis.pro…...

Python零基础入门AI绘画:FLUX.1-Krea-Extracted-LoRA快速上手教程

Python零基础入门AI绘画&#xff1a;FLUX.1-Krea-Extracted-LoRA快速上手教程 1. 前言&#xff1a;为什么选择这个教程&#xff1f; 如果你对AI绘画感兴趣但被复杂的代码吓退&#xff0c;这个教程就是为你准备的。不需要任何编程基础&#xff0c;我们将从最基础的Python安装开…...

Linux源码神级编辑器vim+cscope插件

安装cscope插件(ubuntu) sudo apt-get install cscope 创建工程 cscope-indexer -r -> 递归生成索引信息文件(在工程源码首目录中执行) 进入vim,通过:cs show命令查看当前工程的数据库文件cscope.out是否被加载进来,如下表示OK: 一般会自动加载进来,如果没有加载…...

云服务器部署Hermes Agent(爱马仕龙虾)的详细教程

云服务器部署Hermes Agent&#xff08;爱马仕龙虾&#xff09;的详细教程 关键词&#xff1a;Hermes Agent部署、AI Agent部署教程、腾讯云Lighthouse、微信接入AI助手、Hermes Agent安装、AI助手云端运行 最近一直在研究「AI Agent长期运行」的方案。 本地跑 Agent 最大的问…...

【Java 25 FFI终极指南】:20年JVM专家亲授外部函数接口增强的5大生产级落地陷阱与避坑清单

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Java 25 FFI增强的演进脉络与核心定位 Java 25 引入的 Foreign Function & Memory API&#xff08;FFI&#xff09;正式版标志着 JVM 与原生世界交互范式的根本性跃迁。它不再依赖 JNI 的脆弱桥接与…...

**WebSocket实战进阶:从基础通信到实时推送的全流程架构设计与代码实现**在现代Web应用中,**实

WebSocket实战进阶&#xff1a;从基础通信到实时推送的全流程架构设计与代码实现 在现代Web应用中&#xff0c;实时性已成为用户体验的核心竞争力之一。传统HTTP轮询方式已无法满足高并发、低延迟的业务场景需求&#xff0c;而 WebSocket 技术凭借其全双工通信能力&#xff0c;…...

OpenClaw执行奇点——因果链折叠与责任悬置的时间哲学(第十九篇)

OpenClaw执行奇点——因果链折叠与责任悬置的时间哲学&#xff08;第十九篇&#xff09;导言&#xff1a;当思想失去重量&#xff0c;行动将滑向何方&#xff1f;在第一篇中&#xff0c;我们凝视了OpenClaw吞噬算力以构建反熵岛屿的热力学本质&#xff1b;在第二篇中&#xff0…...

Firefox兼容性深度解析:GM_addElement底层机制揭秘

Firefox兼容性深度解析&#xff1a;GM_addElement底层机制揭秘 【免费下载链接】scriptcat ScriptCat, a browser extension that can execute userscript; 脚本猫&#xff0c;一个可以执行用户脚本的浏览器扩展 项目地址: https://gitcode.com/gh_mirrors/sc/scriptcat …...

告别信号衰减!PCIe 5.0硬件设计实战:从板材选择到玻纤效应的完整避坑指南

PCIe 5.0硬件设计实战&#xff1a;从板材选择到玻纤效应的完整避坑指南 当32GT/s的高速信号在PCB走线上疾驰时&#xff0c;每一个设计细节都可能成为性能的绊脚石。作为经历过三代PCIe标准迭代的硬件工程师&#xff0c;我至今记得第一次看到PCIe 5.0眼图崩溃时的震撼——那些理…...

NewTab Redirect! 终极指南:如何彻底掌控你的浏览器新标签页

NewTab Redirect! 终极指南&#xff1a;如何彻底掌控你的浏览器新标签页 【免费下载链接】NewTab-Redirect NewTab Redirect! is an extension for Google Chrome which allows the user to replace the page displayed when creating a new tab. 项目地址: https://gitcode.…...

FPGA工程师的JESD204B通关指南:从Subclass1链路建立到调试避坑(附Xilinx/Intel IP核使用心得)

FPGA工程师的JESD204B实战指南&#xff1a;从参数配置到链路调试全解析 在高速数据采集与处理系统中&#xff0c;JESD204B接口已成为连接FPGA与高速ADC/DAC的事实标准。这个看似简单的串行接口背后&#xff0c;却隐藏着复杂的配置参数和严格的时序要求。作为FPGA工程师&#xf…...