redis-内存回收机制

news/2024/10/19 14:34:32/

在 Redis 的源码中,redisDb 结构体用于表示一个 Redis 数据库实例。结构体大致如下

typedef struct redisDb {dict *dict;                 // 存储键值对的字典dict *expires;              // 存储键的过期时间的字典dict *blocking_keys;        // 阻塞键的字典dict *ready_keys;           // 准备就绪键的字典dict *watched_keys;         // 被 WATCH 命令监视的键的字典int id;                     // 数据库的编号long long avg_ttl;          // 平均过期时间unsigned long expires_cursor; // 过期字典的迭代器游标
} redisDb;
  1. dict: 这是一个指向字典的指针,字典用来存储数据库中的所有键值对。这是数据库的主数据结构。(字典是一个用哈希表实现的数据结构用于保存key和value)

  2. expires: 这也是一个指向字典的指针,用于存储具有过期时间的键。键是数据库中的键,而值是过期时间(UNIX 时间戳)。(不存储内容,存储key和其过期时间)

  3. blocking_keys: 这个字典存储那些正在阻塞某些命令(如 BLPOP)的键。键为阻塞的键,值为阻塞这些键的客户端列表。(某些对数据执行的命令会有阻塞效果,这些数据被保存在这里)

  4. ready_keys: 存储那些已准备就绪以供阻塞命令处理的键。(命令条件达成,不需要阻塞了)

  5. watched_keys: 当使用事务和 WATCH 命令时,这个字典会存储被监视的键。如果这些键在事务执行之前被修改,事务将被中断。(使用watch监听某一数据,该数据会被保存在这,比如执行事务时可以先监听一个数据,当这个数据发生更改,则事务作废)

  6. id: 数据库的索引编号,Redis 配置中可以设置多个数据库,这个编号就是用来标识每个数据库的。

  7. avg_ttl: 这表示数据库中所有设置了过期时间的键的平均过期时间。

  8. expires_cursor: 这是用于渐进式地清理过期键的内部迭代器的游标。(redis在进行周期性删除时,该值则记录了清理任务的当前执行位置,因为redis数据庞大,无法一次清理完成,需要记录上一次的清理位置,再次清理时,在这个位置以后继续清理,这个位置的记录就叫游标)

过期key的淘汰有两种方式

1.惰性删除:这种删除方式是当我们使用这个数据时才回去检查过期时间,如果过期,则删除该缓存

2.周期删除:周期删除是指redis按一定频率抽查设置了过期时间的key是否过期,并且由expiers_cursor配合记录清理位置,它包括两种模式

slow模式:这种模式下按照server.hz配置的参数的频率执行清理任务,假如说将其设置为10,那么该模式下,redis将每秒执行十次清理,并且每次执行时间不能超过25ms

fast模式:该模式下将在一个循环中不断执行清理操作,并且保证两次清理任务之间间隔不低于2ms,并且每次清理操作执行不能超过1ms

redis内存爆满时,他将依据既定的内存淘汰策略来清理内存,包括如下:

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 算法进行淘汰

ttl表示过期时间

其中allkeys表示对全体key,volatile表示设置了过期时间的key,lru和lfu分别是两种算法,random表示随机

LRU ( Least Recently Used ),最近最少使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
LFU ( Least Frequently Used ),最少频率使用。会统计每个 key 的访问频率,值越小淘汰优先级越高。

无论是LRU还是LFU,在进行淘汰key的比较时都是比较redisobject结构体中的lru属性的值,而lru属性在LRU相关模式下会记录最近访问时间戳,在LFU模式化会用一个简单的算法记录访问频率。


http://www.ppmy.cn/news/1455281.html

相关文章

Redis探索之旅(基础)

目录 今日良言:满怀憧憬,阔步向前 一、基础命令 1.1 通用命令 1.2 五大基本类型的命令 1.2.1 String 1.2.2 Hash 1.2.3 List 1.2.4 Set 1.2.5 Zset 二、过期策略以及单线程模型 2.1 过期策略 2.2 单线程模型 2.3 Redis 效率为什么这么高 三…

嵌入式系统应用-拓展-FLASH之操作 SFUD (Serial Flash Universal Driver)之KEIL移植

1 SFUD介绍 1.1 初步介绍 SFUD 是一个开源的串行 SPI 闪存通用驱动库。由于市面上有各种类型的串行闪存设备,每种设备都具有不同的规格和指令,因此 SFUD 的设计目的是解决这些差异。这使得我们的产品可以支持不同品牌和规格的闪存,增强了软…

flask 前后台文件多张图片api;AIGC streamlit、gradio多图片页面展示

1、flask 前后台文件多张图片api send_file 传递zip: send_file(zip_data, mimetype=‘application/zip’, as_attachment=True, download_name=‘images.zip’) from flask import Flask, Response, request,send_file from PIL import Image import torch import io from …

自定义类型②③——联合体和枚举

自定义类型②③——联合体和枚举 1.联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员结构体和联合体的对比1.4 联合体大小的计算1.5 联合体的应用①1.5 联合体的应用② 2. 枚举2.1 枚举类型的声明2.2 枚举类型的特点2.3 枚举的优点 1.联合体 1.1 联合体类型的声明 关…

项目总结(一)docker总结

目录 一、引言 二、docker ------>2.1、docker介绍 ------>2.2、与虚拟机的区别 ------>2.3、Docke基本概念 ------>2.4、Docker内部结构 ------>2.5、Windows上使用docker ------>2.6、Linux上使用Docker ------>2.7、Docker常用命令 ------&g…

JS基础:8个算数运算符详解

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃 大专生,一枚程序媛,感谢关注。回复 “前端基础题”,可免费获得前端基础 100 题汇总,回复 “前端基础路线”,可获取完整web基础…

DS二叉搜索树

前言 我们在数据结构初阶专栏已经对二叉树进行了介绍并用C语言做了实现,但是当时没有对二叉搜树进行介绍,而是把他放到数据结构进阶构专栏的第一期来介绍,原因是后面的map和set(红黑树)是基于搜索树的,这里…

力扣:931. 下降路径最小和

931. 下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即…