0

0

详解Redis内部运作机制

WBOY

WBOY

发布时间:2024-03-10 09:13:09

|

518人浏览过

|

来源于Linux就该这么学

转载

详解redis内部运作机制

Redis数据库(Redis 如何表示一个数据库,数据库操作是如何实现的)

当Redis服务器初始化的时候会创建 redis.h/REDIS_DEFAULT_DBNUM(后面简写 N ) 个数据库,且数据库的id是从 0 到  N-1 , 所有的数据库保存到 redis.h/redisServer.db 数组中 。

在客户端可以通过 “SELECT” 命令进行切换,其中程序是直接用 redis.h/redisServer.db[number] 进行切换。 但是,一些内部程序,比如 AOF 程序、复制程序和 RDB 程序,需要知道当前数据库的号码, 如果没有 id 域的话,程序就只能在当前使用的数据库的指针,和 redisServer.db 数组中所 有数据库的指针进行对比,以此来弄清楚自己正在使用的是那个数据库。

Redis数据库的结构:
typeof  struct   redisDb{
int id ;   // 数据库的id

dict *dict ; // 保存着该数据库的所有键值对 也被称为键空间

dict *expires ; // 保存着键的过期时间

…..

} redisDb ;
 Redis 是一个键值对 字典表,同样Redis数据库存储形式也是键值对 字典表
 键是字符串
 值可以是字符型、list 列表、 hash、集合以及 有序集合其中之一
Redis 数据库增、删、改、查等操作的键空间操作:

新增:
Redis会在键空间字典中增加一个键-值对,其中键为一个字符串,值为任意一个值类型。
删除:
Redis会在键空间字典中删去对应键的键-值对
更新:
Redis会在键空间字典中释放之前对应键的值对象,并让键指向新的值对象
查询:
Redis会在键空间字典中查询对应键的值对象:
键不存在,返回NULL
键存在,且类型正确,返回正确的值
键存在,但类型不正确,返回类型错误
其他操作:
除了上面展示的键值操作之外,还有很多针对数据库本身的命令,也是通过对键空间进行处理 来完成的:
FLUSHDB              删除键空间中的所有键值对
RANDOMKEY        从键空间中随机返回一个键
DBSIZE                  返回键空间中键值对的数量
EXISTS                  检查给定键是否存在于键空间中
RENAME               在键空间中,对给定键进行改名

键的过期时间

在Redis数据库中,所有键的过期时间都保存在RedisDb结构体的expires字典中,其中键为一个指向dict 字典(键空间)里某个键的指针,值为改建的过期时间,用long long型表示。

Redis 有四个命令可以设置键的生存时间(可以存活多久)和过期时间(什么时候到期):
EXPIRE 以秒为单位设置键的生存时间;
PEXPIRE 以毫秒为单位设置键的生存时间;
EXPIREAT 以秒为单位,设置键的过期 UNIX 时间戳;
PEXPIREAT 以毫秒为单位,设置键的过期 UNIX 时间戳。

虽然有那么多种不同单位和不同形式的设置方式,但是 expires 字典的值只保存“以毫秒为单 位的过期 UNIX 时间戳” ,这就是说,通过进行转换,所有命令的效果最后都和 PEXPIREAT 命令的效果一样。

PLC编程入门基础知识 中文doc版
PLC编程入门基础知识 中文doc版

可编程序控制器,英文称Programmable Controller,简称PC。但由于PC容易和个人计算机(Personal Computer)混淆,故人们仍习惯地用PLC作为可编程序控制器的缩写。它是一个以微处理器为核心的数字运算操作的电子系统装置,专为在工业现场应用而设计,它采用可编程序的存储器,用以在其内部存储执行逻辑运算、顺序控制、定时/计数和算术运算等操作指令,并通过数字式或模拟式的输入、输出接口,控制各种类型的机械或生产过程。本平台提供PLC编程入门基础知识下载,需要的朋友们下载看看吧!

下载
过期键的清除

定时清除:
在创建KEY的时候创建一个定时任务,在KEY到期时定时任务会被触发,第一时间清除过期KEY。
此种操作对内存最友好,不会有垃圾数据占用内存情况存在
缺点是会造成很大的服务器负载,特别是CPU负载高的时候,CPU很大一部分负载用在了删除不必要的KEY上了

惰性清除:
放任键空间的键不管,每次查询KEY的时候先去校验KEY是否过期,过期则删除,不过期则正常返回相应的VALUE。
此种操作对CPU最友好,这种策略仅限于当前KEY,相关不必要的KEY不会造成CPU负载
缺点是:容易造成内存空间浪费,特别是当系统中存在大量过期KEY且很少被用到,这十分影响非常依赖于内存大小Redis的性能

定期删除:
由定时脚本cron定时对expires的键扫描判断是否有过期的KEY存在,如存在,将其删除掉。
这是一种折中方案,既不会过多消耗CPU,又可以定时清楚惰性删除忽略到的不必要的内存消耗

Redis采用的“惰性清除”和“定期清楚”相结合的方式,其中定期删除模式是在规定的时间限制内,尽 可能地遍历各个数据库的 expires 字典,随机地检查一部分键的过期时间,并删除其中的过期键。

伪代码如下:

def activeExpireCycle():
# 遍历数据库(不一定能全部都遍历完,看时间是否足够)
for db in server.db:
# MAX_KEY_PER_DB 是一个 DB 最大能处理的 key 个数 # 它保证时间不会全部用在个别的 DB 上(避免饥饿) i=0                                    while (i < MAX_KEY_PER_DB):
# 数据库为空,跳出 while ,处理下个 DB if db.is_empty(): break
# 随机取出一个带 TTL 的键 
              key_with_ttl = db.expires.get_random_key()
# 检查键是否过期,如果是的话,将它删除 if is_expired(key_with_ttl):
            db.deleteExpiredKey(key_with_ttl)
# 当执行时间到达上限,函数就返回,不再继续 # 这确保删除操作不会占用太多的 CPU 时间
if reach_time_limit(): return
i += 1

Redis 过期键删除的主从同步问题(Redis的机制是由主节点统一控制)

如果服务器是主节点,当它删除一个过期键之后,会显式的向所有附属节点发送一条DEL命令
如果服务器是附属节点,当它判断到当前KEY已经过期,会将该键过期的消息发送给主服务器,主服务器删除后向所有的从服务器节点发送DEL命令。

从服务器节点不自主的对键进行删除是为了保持和主服务器数据的绝对一致性,即当一个过期键还存在主服务器上,这个键在所有的从服务器上也不会被删除。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

436

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

257

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1465

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

619

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

550

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

545

2024.04.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.3万人学习

Git 教程
Git 教程

共21课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号