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

每日一题:聊聊 Redis 过期键的删除策略

聊聊 Redis 过期键的删除策略

答案

  • 惰性删除 :只会在取出 key 的时候才对数据进行过期检查;这样对 CPU 最友好,但是可能会造成太多过期 key 没有被删除(占用内存)。

    • 通过定时器实现(时间事件),时间事件是通过无序链表实现的,查询复杂度为 O(N)

    • 数据到达过期时间,不做处理;每次访问该数据时,我们需要实时判断

    • 源码路径:db.c/expireIfNeeded(),本质上 expireIfNeeded 方法类似于过滤器

      • 7.2 版本只会返回 0/1 , 0: 有效 1: 过期
  • 定时删除 : 每隔一段时间抽取一批 key 执行删除过期 key 操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。

    • 默认情况下 Redis 定期检查的频率是每秒扫描 10 次,用于定期清除过期键。当然此值还可以通过配置文件进行设置,在 redis.conf 中修改配置 hz 即可,默认的值为 hz 10,官方注释范围为 1~500,但建议最大 100 即可

    • 定时删除的扫描并不是遍历所有的键值对,这样的话比较费时且太消耗系统资源。Redis 服务器采用的是随机抽取形式,每次从过期字典中,取出 20 个键进行过期检测,过期字典中存储的是所有设置了过期时间的键值对。如果这批随机检查的数据中有 25% 的比例过期,那么会再抽取 20 个随机键值进行检测和删除,并且会循环执行这个流程,直到抽取的这批数据中过期键值小于 25%,此次检测才算完成

    • Redis 服务器为了保证过期删除策略不会导致线程卡死,会给过期扫描增加了最大执行时间为 25ms

    • 定期删除对内存更加友好,惰性删除对 CPU 更加友好

  • 总结:所以 Redis 采用的是 定时删除+惰性删除 可以简称为 定期删除 源码路径:server.c/activeExpireCycle()

  • ps: 本文源码内容基于 7.2 版本

引申内容:源码解析

  • 内存数据库:redisDb
/* Redis database representation. There are multiple databases identified* by integers from 0 (the default database) up to the max configured* database. The database number is the 'id' field in the structure. */
typedef struct redisDb {dict *dict;                 /* The keyspace for this DB 所有数据的键值对 */dict *expires;              /* Timeout of keys with a timeout set 设置了超时时间的相关键值对数据 */dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)  阻塞的 dict */dict *blocking_keys_unblock_on_nokey;   /* Keys with clients waiting for* data, and should be unblocked if key is deleted (XREADEDGROUP).* This is a subset of blocking_keys 解除阻塞的dict */dict *ready_keys;           /* Blocked keys that received a PUSH */dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS  监控的dict (事务前可以加watch) */int id;                     /* Database ID */long long avg_ttl;          /* Average TTL, just for stats */unsigned long expires_cursor; /* Cursor of the active expire cycle. */list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */clusterSlotToKeyMapping *slots_to_keys; /* Array of slots to keys. Only used in cluster mode (db 0). */
} redisDb;
  • 键值对:dict
struct dict {dictType *type; /* 键值对的类型 */dictEntry **ht_table[2]; /* 两张哈希表,目的为了 rehash */unsigned long ht_used[2]; /* 上面两张哈希表中,分别使用了多少 *//* rehash 的目的是重新进行扩展或收缩 */long rehashidx; /* rehashing not in progress if rehashidx == -1,记录 rehash 进度的标志,每移动一个桶,rehashidx++ *//* Keep small vars at end for optimal (minimal) struct padding */int16_t pauserehash; /* If >0 rehashing is paused (<0 indicates coding error) rehash是否暂停 */signed char ht_size_exp[2]; /* exponent of size. (size = 1<<exp) 目的: 加快运算速度*/void *metadata[];           /* An arbitrary number of bytes (starting at a* pointer-aligned address) of size as defined* by dictType's dictEntryBytes. */
};
  • 键值对实体:dictEntry
  • 存放键值对
struct dictEntry {void *key;union {void *val;uint64_t u64;int64_t s64;double d;} v;struct dictEntry *next;     /* Next entry in the same hash bucket. 哈希值相同的key/val对出现哈希冲突时通过链表存储起来 */void *metadata[];           /* An arbitrary number of bytes (starting at a* pointer-aligned address) of size as returned* by dictType's dictEntryMetadataBytes(). */
};
  • 哈希数据类型 dictType

    • 存放函数的结构体,定义了一些函数指针
    • 目的: 通过设置自定义函数,使得 dict 的 key 和 value 能够存储任何类型的数据
typedef struct dictType {uint64_t (*hashFunction)(const void *key);void *(*keyDup)(dict *d, const void *key);void *(*valDup)(dict *d, const void *obj);int (*keyCompare)(dict *d, const void *key1, const void *key2);void (*keyDestructor)(dict *d, void *key);void (*valDestructor)(dict *d, void *obj);int (*expandAllowed)(size_t moreMem, double usedRatio);/* Flags *//* The 'no_value' flag, if set, indicates that values are not used, i.e. the* dict is a set. When this flag is set, it's not possible to access the* value of a dictEntry and it's also impossible to use dictSetKey(). Entry* metadata can also not be used. */unsigned int no_value:1;/* If no_value = 1 and all keys are odd (LSB=1), setting keys_are_odd = 1* enables one more optimization: to store a key without an allocated* dictEntry. */unsigned int keys_are_odd:1;/* TODO: Add a 'keys_are_even' flag and use a similar optimization if that* flag is set. *//* Allow each dict and dictEntry to carry extra caller-defined metadata. The* extra memory is initialized to 0 when allocated. */size_t (*dictEntryMetadataBytes)(dict *d);size_t (*dictMetadataBytes)(void);/* Optional callback called after an entry has been reallocated (due to* active defrag). Only called if the entry has metadata. */void (*afterReplaceEntry)(dict *d, dictEntry *entry);
} dictType;

相关文章:

每日一题:聊聊 Redis 过期键的删除策略

聊聊 Redis 过期键的删除策略 答案 惰性删除 &#xff1a;只会在取出 key 的时候才对数据进行过期检查&#xff1b;这样对 CPU 最友好&#xff0c;但是可能会造成太多过期 key 没有被删除&#xff08;占用内存&#xff09;。 通过定时器实现&#xff08;时间事件&#xff09;&…...

边缘计算的AI小板——OrangePi AI Pro

简介 OrangePi AI Pro是一款基于Allwinner H6处理器的嵌入式AI计算设备&#xff0c;适用于物联网和边缘计算。它具有强大的性能、低功耗、多接口和小尺寸。 本文分为三个部分&#xff1a; 一、对该板进行简单的开箱介绍。 二、 将SD卡中的系统迁移到由于该板支持SD卡、SSD…...

RDMA (2)

iWARP(RDMA)怎么工作的 招式1:bypass内核 非iWARP时,当应用向网络适配器发出读或者写命令时,命令穿过用户空间以及内核空间,因此需要在用户空间和内核空间间进行切换。 iWARP使用RDMA,让应用直接将命令送达到网络适配器。这规避了对内核的调用,减少了开销和延迟。 招式2…...

vue.config.js中,devServer对象用于配置开发服务器的行为

devServer: {hot: true, // 启用模块热替换&#xff08;Hot Module Replacement&#xff0c;HMR&#xff09;。liveReload: true, // 启用页面自动刷新。当热更新失败时&#xff0c;将回退到页面自动刷新。open: true, // 启动服务器后自动打开浏览器。port: 8080, // 设置开发…...

JVM 运行流程

JVM 是 Java 运行的基础&#xff0c;也是实现一次编译到处执行的关键&#xff0c;那么 JVM 是如何执行的呢&#xff1f; JVM 执行流程 程序在执行之前先要把java代码转换成字节码&#xff08;class 文件&#xff09;&#xff0c; JVM 首先需要把字节码通过一定的 方式 类加…...

android-JNI

1.2【静态库】的特点&#xff1a; &#xff08;.a&#xff09; ①静态库对函数库的链接是在编译期完成的。执行期间代码装载速度快。 ②使可执行文件变大&#xff0c;浪费空间和资源&#xff08;占空间&#xff09;。 ③对程序的更新、部署与发布不方便&#xff0c;需要全量更新…...

Go_unsafe包

是什么&#xff1f;为什么&#xff1f; 如何利用unsafe包修改私有成员&#xff1f; 结构体会被分配到一块连续的内存&#xff0c;结构体的地址也代表第一个成员的地址。 如何利用unsafe包获取slice和map的长度&#xff1f; // 利用unsafe包修改私有成员 type S struct {name …...

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十三)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 20 - 21节&#xff09; P20《19.ArkUI-属性动画和显式动画》 本节先来学习属性动画和显式动画&#xff1a; 在代码中定义动画&am…...

企业建站响应式网站建设平台版源码系统 海量模版可选择 带完整的安装代码以及搭建教程

系统概述 企业建站响应式网站建设平台版源码系统是一款集创新性、实用性和便捷性于一体的建站解决方案。它旨在为用户提供一站式的网站建设服务&#xff0c;无论你是新手还是经验丰富的开发者&#xff0c;都能通过该系统轻松实现网站的构建与部署。 该系统采用先进的技术架构…...

在 VSCode 中搭建 Flutter 开发环境并运行项目

要在 Visual Studio Code (VSCode) 中运行 Flutter 项目并启动虚拟机&#xff08;例如 Android Emulator&#xff09;&#xff0c;可以按照以下步骤进行设置和操作&#xff1a; 一、安装 Flutter 和 Dart 插件 安装 Flutter SDK&#xff1a; 前往 Flutter 官网 下载并安装 Flu…...

如何执行VMware P2V迁移|VMware Converter和替代方案

VMware中的P2V是什么&#xff1f; 我们常说的VMware P2V其实指的就是“物理到虚拟”&#xff0c;将工作负载从物理机器转换或迁移到虚拟机&#xff08;VM&#xff09;的过程&#xff0c;能够使您无需从头开始费力地创建和配置新虚拟机。 就像您可以使用Disk2vhd执行Hyper-V物理…...

03-3.2.3 队列的链式存储的实现

&#x1f44b; Hi, I’m Beast Cheng&#x1f440; I’m interested in photography, hiking, landscape…&#x1f331; I’m currently learning python, javascript, kotlin…&#x1f4eb; How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以订…...

Spring AI 第二讲 之 Chat Model API 第八节Anthropic 3 Chat

Anthropic Claude 是一系列基础人工智能模型&#xff0c;可用于各种应用。对于开发人员和企业来说&#xff0c;您可以利用 API 访问&#xff0c;直接在 Anthropic 的人工智能基础架构之上进行构建。 Spring AI 支持用于同步和流式文本生成的 Anthropic 消息 API。 Anthropic …...

【ARM 常见汇编指令学习 6.2 -- ARMv8 汇编指令 SDIV 详细介绍】

文章目录 SDIV指令格式使用示例注意事项总结 SDIV ARMv8 架构中的 SDIV 指令用于执行带符号整数除法操作。这意味着它可以处理负数除法&#xff0c;与 UDIV&#xff08;执行无符号整数除法&#xff09;形成对比。SDIV 将两个寄存器中的带符号整数相除&#xff0c;将除法结果存…...

【ArcGIS微课1000例】0113:大地测量要素概述与构建

文章目录 一、大地测量要素描述1. 大地要素的概念2. 大地要素的类型二、创建大地测量要素1. 创建要素类2. 创建大地要素一、大地测量要素描述 1. 大地要素的概念 大地测量要素的测量值考虑了投影空间的固有变形。如果要创建一个空间跨度较大的要素(例如一条横跨大洋的飞行路…...

【记录】LangChain+本地模型的文档问答(webUI)

已在notebook测试无误。 包安装 pip install langchain langchain_community transformers InstructorEmbedding sentence_transformers2.2.2 faiss-gpu PyPDF2 streamlit pyngrok gradio fitz frontend 环境变量设置 huggingface连不上无法下载模型&#xff0c;需要设置镜像。…...

Winddow系统下关于Golang使用Cgo的配置

1.配置CGO_ENABLED为1 go env -w CGO_ENABLED1 2.安装gcc环境&#xff0c;否则出现cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%错误 安装包&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1sgF9lijqGeP…...

python面向过程与初始面向对象编程

让我们穿越到《龙珠》世界&#xff0c;一起揭开 面向对象编程 的神秘面纱吧。 面向过程编程与面向对象编程 天下第一武道会 选手登记 第 22 届天下第一武道会即将召开&#xff0c;各路武术高手齐聚一堂&#xff0c;其中最受瞩目的&#xff0c;当属卡卡罗特&#xff08;孙悟…...

vue3 实现自定义指令封装 --- 通俗易懂

1、局部自定义指令 1.1 在<script setup>定义组件内的指令&#xff0c;任何以v开头的驼峰式命名的变量都可以被用作一个自定义指令 <template><div><h3>使用自定义指令</h3><div>########################## start 局部自定义指令</d…...

5.31.15 使用图像到图像转换和 YOLO 技术对先前的乳房 X 光检查结果中的异常进行早期检测和分类

在本研究中&#xff0c;我们研究了基于 You-Only-Look-Once (YOLO) 架构的端到端融合模型的有效性&#xff0c;该模型可同时检测和分类数字乳房 X 光检查中的可疑乳腺病变。包括四类病例&#xff1a;肿块、钙化、结构扭曲和正常&#xff0c;这些病例来自包含 413 个病例的私人数…...

智能车竞赛备赛:用3块钱的HIP6601驱动无线信标线圈,实测避坑指南

智能车竞赛备赛&#xff1a;3元HIP6601驱动无线信标线圈的实战避坑手册 全国大学生智能车竞赛中&#xff0c;无线能量传输组别的信标线圈驱动一直是技术难点。如何在有限预算内实现稳定高效的半桥驱动&#xff1f;本文将带你深入解析3元级HIP6601芯片的实战应用&#xff0c;从电…...

2026校招技术岗薪资大盘点:AI方向白菜价40w起,这个方向却跌破20w

上周帮学弟看offer&#xff0c;吓了一跳。某大厂给AI对齐岗的校招白菜价&#xff0c;总包42w。同一个公司&#xff0c;传统测试开发岗&#xff0c;开出了18w。差了不止一倍。这不是个例。我翻了牛客网五月最新的offer帖&#xff0c;又问了几个在阿里、字节、美团的朋友&#xf…...

从串行到以太网:SEMI E37 HSMS协议如何重塑半导体设备通信

1. 半导体设备通信的进化史&#xff1a;从串口到以太网 十年前我第一次接触半导体设备通信时&#xff0c;车间里密密麻麻的串口线让我印象深刻。每条产线上十几台设备&#xff0c;每台设备背后都拖着几根九针串口线&#xff0c;像蜘蛛网一样缠绕在一起。当时最头疼的就是排查通…...

Claude流水线资源开销暴增300%?用eBPF+Prometheus精准追踪LLM训练/推理任务混部下的CI资源泄漏链(附Grafana看板模板)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Claude流水线资源开销暴增300%&#xff1f;用eBPFPrometheus精准追踪LLM训练/推理任务混部下的CI资源泄漏链&#xff08;附Grafana看板模板&#xff09; 当Claude模型在Kubernetes集群中与CI流水线共享…...

如何优雅处理系统过载:SRE服务降级的10个终极策略

如何优雅处理系统过载&#xff1a;SRE服务降级的10个终极策略 【免费下载链接】awesome-sre A curated list of Site Reliability and Production Engineering resources. 项目地址: https://gitcode.com/gh_mirrors/awe/awesome-sre 在现代分布式系统中&#xff0c;服务…...

Spring Framework(DI)

1.依赖注入思考&#xff1a;向一个类中传递数据的方式有几种&#xff1f;普通方法(set方法)构造方法思考&#xff1a;依赖注入描述了在容器中建立bean与bean之间依赖关系的过程&#xff0c;如果bean运行需要的是数字或字符串呢&#xff1f;引用类型简单类型&#xff08;基本数据…...

深入理解C语言指针(三)

点击表格内对应链接跳转对应内容⬇️⬇️⬇️ 作者主页吃透C语言专栏Gitee仓库文章目录一&#xff0c;字符指针变量1.与字符的搭配2.与字符串的搭配(1)字符串详解(2)字符数组或者常量字符串的使用(1)字符数组的使用(2)常量字符串的使用二&#xff0c;数组指针变量1.概念2.使用…...

基于MCP协议构建AI图像生成服务器:连接Claude与Stable Diffusion的实践指南

1. 项目概述&#xff1a;一个连接AI与创意生产的MCP服务器最近在GitHub上看到一个挺有意思的项目&#xff0c;alexandrali0506/ai-image-generator-mcp。光看名字&#xff0c;你可能觉得这又是一个普通的AI画图工具&#xff0c;但它的核心价值远不止于此。这是一个基于模型上下…...

低成本私域起盘:2+1 轻量化增长模型,实体商家可直接复制落地

有人靠这套玩法&#xff0c;仅靠两个初始客户&#xff0c;就盘活了整个平台。不少做实体、做品牌的老板都有同一个困惑&#xff1a;活动做了一场又一场&#xff0c;流量拉了一波又一波&#xff0c;可平台始终起不来&#xff0c;用户留不住&#xff0c;复购做不起来。我问过很多…...

【c++面向对象编程】第18篇:多继承与菱形继承(一):二义性问题与虚拟继承

目录 一、多继承的基本语法 二、二义性问题&#xff1a;两个基类有同名成员 解决方案1&#xff1a;用作用域运算符明确指定 解决方案2&#xff1a;在派生类中重写&#xff08;覆盖&#xff09; 三、菱形继承&#xff08;钻石问题&#xff09; 菱形继承带来的两个问题 查看…...