《Redis设计与实现》阅读总结-2

 第 7 章 压缩列表

1. 概念:

  • 压缩列表是列表键和哈希键的底层实现之一。
  • 当一个列表键只包含少量列表项,并且每个列表项是小整数值或长度比较短的字符串,那么Redis就会使用压缩类别来做列表键的底层实现。
  • 哈希键里面包含的所有键和值都是最小整数值或短字符串。

2. 压缩列表的构成:

  • 压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的书序结构。

3. 压缩列表节点的构成:

4. 连锁更新:

每个节点的previous_entry_length属性记录了前一个节点的长度:如果前一个字节长度小于254字节,那么previous_entry_length属性需要用1字节空间保存这个值,如果前一个字节的长度大于或等于254字节,那么previous_entry_length属性需要5字节的空间保存这个值。

如果在压缩列表中新添加一个长度大于等于254字节的节点,导致后边所有节点多次空间拓展的操作称为“连锁更新”。

5. 其他:

  • 压缩列表是一种为了节约内存而开发的顺序型数据结构。
  • 压缩列表可以包含多个节点,每个节点可以保存一个字节数组或整数值。
  • 添加节点或者删除节点可能或引发连锁更新操作,但是这种操作出现的几率不高。

第 8 章 对象

1. 概念:

  • Redis没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统。
  • 我们可以针对不同的使用场景,为对象设置不同的数据结构,从而优化对象在不同场景下的使用效率。
  • Redis对象系统基于引用计数计数的内存回收机制,可以有效节约内存。‘
  • Redis的对象带有访问时间记录信息,该信息可用用于计算数据库键的空转时间,在服务器启用了maxmemory功能的情况下,空转时长较大的那些键可能优先被服务器删除。

2. 对象类型:

3. 对象结构:

不同类型值对象的 Type命令的输出:

不同类型和编码的对象:

Object encoding对不同编码的输出:

 4. 各种对象的编码:

  • 字符串对象:

编码可以是int、raw或者embstr。

如果字符串对象保存的是整数值,并且这个整数值可以用long类型来表示,象编码设置为int。

如果字符串对象保存是一个字符串值,并且这个字符串的长度大于32字节,使用SDS保存这个字符串,并且对象编码设置为raw。

如果字符串对象保存是一个字符串值,并且这个字符串的长度小于等于32字节,使用SDS保存这个字符串,并且对象编码设置为embstr。

long double 类型表示的浮点数,是转换成字符串保存的,对象编码为embstr。

int编码字符串对象不是整数值时,会int->raw

embstr编码字符串对象执行任何修改时,会embstr->raw。

 

  • 列表对象:

编码可以是ziplist或者linkedlist。

满足所有字符串元素的长度都是小于64字节,并且保存元素数量小于512个时使用ziplist,否则使用linkedlist。

  • 哈希对象:

编码可以是ziplist或者hashtable。

满足所有字符串元素的长度都是小于64字节,并且保存元素键值对数量小于512个时使用ziplist,否则使用hashtable。

 

  • 集合对象:

编码可以是intset(整数集合)或者hashtable。

满足对象保存的所有元素都是整数值,并且保存对象的元素数量不超过512个使用intset,否则使用hashtable。

  • 有序集合对象:

编码可以是ziplist或者skiplist。

满足所有字符串元素的长度都是小于64字节,并且保存元素数量小于128个时使用ziplist,否则使用skiplist。

5. 内存回收:

        C语言并不具备内存回收功能,所以Redis在对象系统中构建了一个引用计数技术来实现内存回收机制。

6. 对象共享:

        对象的引用计数属性还带有对象共享的作用。

        Redis只对包含整数值的字符串对象进行共享,即共享值为0到9999的字符串对象。

7. 对象的空转时长:

        redisObject结果包含最后一个属性lru属性,该属性记录了对象最后一次被命令程序访问的时间。空转时长=当前时间-lru的值。

第 9 章 数据库

1. 读写键空间时的维护操作:

  • 在取读一个键之后(读操作和写操作都要对键进行取读),服务器会根据键是否存在来更新服务器的键空间命中(hit)次数或键空间不命中(miss)次数;
  • 在读取一个键之后,服务器会更新键的LRU(最后一次使用)时间,这个值可以用于计算键的闲置时间;
  • 如果服务器在读取一个键时发现该键已经过期,那么服务器会先刑除这个过期键,然后在执行余下其他操作;
  • 如果有客户端使用 WATCH命令监视了某个键,那么服务器在对被监视的键进行修改之后,会将这个键标记为脏( dirty),从而让事务程序注意到这个键已经被修改;
  • 服务器每次修改一个键之后,都会对脏( dirty)键计数器的值增1,这个计数器会触发服务器的持久化以及复制操作;
  • 如果服务器开启了数据库通知功能,那么在对键进行修改之后,服务器将按配置发送相应的数据库通知。

2. 过期键删除策略:

  • 定时删除:在设置键的过期时间的同时,创建一个定时器( timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。
  • 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检査取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
  • 定期删除:每隔一段时间,程序就对数据库进行一次检査,删除里面的过期键。至于要删除多少过期键,以及要检査多少个数据库,则由算法决定。

        在这三种策略中,第一种和第三种为主动删除策略,而第二种则为被动刑除策略。

3. Redis的过期键删除策略:

        redis使用惰性删除和定期删除策略:通过配合使用这两种策略,服务器可以很好地合理使用CPU时间和避免浪费内存空间之间确定平衡。

4. AOF、RDB和复制功能对过期键的处理:

  • RDB

        生成RDB文件时(使用save或bgsave命令),不会将过期键存入RDB文件中;

        载入RDB文件时,如果服务器以主服务器运行,忽略过期键,如果服务器以从服务器运行,过期键会正常载入,但主从同步时候过期键会被清空。

  • AOF

        AOF写入时,如果键过期,但还没有被惰性删除或者定期删除,那么AOF文件不会因为这个过期键而产生影响,当过期键被惰性删除或者定期删除后,程序会向AOF文件追加一条DEL命令。

        AOF重写,过期的键不会被保存重写到AOF的文件中。

  • 复制

        当服务器运行在复制模式下时,从服务器的过期键删除动作是由主服务器控制:

        i. 主服务器在删除一个过期键之后,会显式地向所有从服务器发送一个DEL命令,告诉从服务器删除这个过期键。

        ii. 从服务器在执行客户端发送的读命令时,即使碰到过期键也不会将过期键删除,而是继续想处理未过期键一样处理过期键

        iii. 从服务器只有在接到主服务器发来的DEL命令之后,才会删除过期键。

5. 重点回顾:

  • Redis服务器的所有数据库都保存在 redisServer.db数组中,而数据库的数量则由 redisServer. dbnum属性保存;
  • 客户端通过修改目标数据库指针,让它指向 redisServer.db数组中的不同元素来切换不同的数据库;
  • 数据库主要由dict和expires两个字典构成,其中dict字典负责保存键值对,而expires字典则负责保存键的过期时间。
  • 因为数据库由字典构成,所以对数据库的操作都是建立在字典操作之上的。
  • 数据库的键总是一个字符串对象,而值则可以是任意一种 Redis对象类型,包括字符串对象、哈希表对象、集合对象、列表对象和有序集合对象,分别对应字符串键、哈希表键、集合键、列表键和有序集合键。
  • expires字典的键指向数据库中的某个键,而值则记录了数据库键的过期时间,过期时间是一个以毫秒为单位的UNIX时间。
  • Redis使用惰性删除和定期删除两种策略来删除过期的键:惰性删除策略只在碰到过期键时才进行删除操作,定期删除策略则每隔一段时间主动查找并删除过期键。
  • 执行SAVE命令或者BGSAVE命令所产生的新RDB文件不会包含已经过期的键。
  • 执行BGREWRITEAOF命令所产生的重写AOF文件不会包含已经过期的键。
  • 当一个过期键被删除之后,服务器会追加一条DEL命令到现有AOF文件的末尾,显式地删除过期键。
  • 从服务器即使发现过期键也不会自作主张地删除它,而是等待主节点发来DEL命令,这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性。
  • 当 Redis命令对数据库进行修改之后,服务器会根据配置向客户端发送数据库通知。

第 10 章 RDB持久化

1. RDB文件的创建:

        Save和Bgsave命令可以用于生成RDB文件。

2. Save和Bgsave命令的区别:

  • Save命令会阻塞Redis服务器进程,知道RDB文件创建完毕为止,在服务器进程阻塞期间,服务器器不能处理任何命令请求。
  • Bgsave命令会派生出一个子进程,然后由子进程负责创建RDB文件,父进程继续处理命令。

3. RDB文件的载入:

  • RDB文件的载入是在服务器启动时自动执行的,所有Redis并没有专门用于载入RDB文件的命令。
  • 如果服务器开启了AOF持久化功能,服务器会优先使用AOF文件来还原数据库状态(AOF文件的更新频率比RDB文件更新频率高)。
  • 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。
  • 载入RDB文件的实际工作由rdb.c/rdbLoad函数完成。
  • RDB文件的载入时服务器状态是阻塞状态。

4. 在Bgsave命令执行期间,服务器处理Save、Bgsave、Bgrewriteaof三个命令的方式会有所不同:

  • BGSAVE命令执行期间,客户端发送的SAVE命令会被服务器拒绝,为了避免父进程(服务器进程)和子进程同时执行两个rdb Save调用,防止产生竟争条件。
  • BGSAVE命令执行期间,客户端发送BGSAVE命令会被服务器拒绝,因为同时执行两个BGSAVE命令也会产生竟争条件。
  • BGREWRITEAOF和BGSAVE两个命令不能同时执行(避免两个子进程执行大量的磁盘写入):如果BGSAVE命令正在执行,客户端发送的 BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行;如果BGREWRITEAOF命令正在执行,客户端发送的BGSAVE命令会被服务器拒绝。

5. Bgsave支持自动间隔性保存:

6. dirty计数器和lastsave属性:

  • dirty计数器记录距离上一次成功执行SAVE命令或者BGSAVE命令之后,服务器对数据库状态(服务器中的所有数据库)进行了多少次修改(包括写入、刑除、更新等操作)。
  • lastsave属性是一个UNIX时间戳,记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。

7. RDB文件结构:

  • RBD文件的最开头是REDIS部分,这个部分长度为5字节,保存这个“REDIS”五个字符。
  • db_version长度为4字节,它的值是一个字符串表示的整数,这个整数记录了RDB的版本号("0006"代表RDB文件版本为第六版本)。
  • datebase部分包含多个数据库,以及各个数据库中的键值对数据。如果所有数据库的状态为空,那么这部分长度为0字节。
  • EOF常量为1字节,这个常量标志着RDB文件正文内容结束。
  • check_sum是一个8字节长的无符号整数,保存着一个校验和,这个校验和是通过对REDIS、db_version、database、EOF四个部分内容进行计算得出来的。

带有两个非空数据库的结构:

每个非空数据库都保存SELECTDB、db_number、key_value_pairs三个字段:

  • SELECTDB常量的长度为1字节,用来告诉程序接下来要读入数据库号码。
  • db_number保存着一个数据库号码。
  • key_value_pairs部分:不同类型type,又对应不同数据结构的value

8. 分析RDB文件:

        参考教材P133

9. 重点回顾:

  • RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据。
  • SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器。
  • BGSAVE令由子进程执行保存操作,所以该命令不会阻塞服务器。
  • 服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行 BGSAVE命令。
  • RDB文件是一个经过压缩的二进制文件,由多个部分组成。
  • 对于不同类型的键值对,RDB文件会使用不同的方式来保存它们。

第 11 章 AOF持久化

1. 流程:

2. AOF持久化的实现:

  • AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤。
  • 追加-->将客户端请求命令追加的缓冲区,写入与同步-->将客户端请求命令从缓存区持久化到AOF文件中。

3. AOF文件的写入与同步:

  • Redis的服务器进程就是一个事件循环(loop),这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复,而时间事件则负责执行像serverCron函数这样需求的定时运行函数。
  • 服务器配置的appendfsync选项值(always、everysec、no)来决定AOF写入与同步的方式,它决定了AOF持久化的效率和安全性。
  • appendfsync选项带来的数据丢失问题:always不会丢失,但是效率低;everysec默认使用,会丢失1秒钟数据;no丢失数据量缓存中的数据,同步时间由操作系统决定。

4. AOF文件的载入与数据还原:

5. AOF重写:

  • 作用:解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写(rewrite)功能。
  • 命令:Bgrewriteaof,后台重写
  • 实现:直接取读服务器当前数据库的状态来实现的,不是通过对现有的AOF文件进行任何读取、分析或者写入操作。
  • Tips:为了避免执行命令时,造成客户端输入缓冲区溢出,重写程序处理列表、哈希表、集合、有序集合这四种类型带有多个值事,先会检查元素数量,如果超过REDIS_AOF_REWRITE_ITEMS_PER_CMD(默认64个)常量的值,就会使用多条命令

6. 重点回顾:

  • AOF文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态。
  • AOF文件中的所有命令都以Redis命令请求协议的格式保存。
  • 命令请求会先保存到AOF缓冲区里面,之后再定期写入并同步到AOF文件。
  • appendfsync选项的不同值对AOF持久化功能的安全性以及Redis服务器的性能有很大的影响。
  • 服务器只要载入并重新执行保存在AOF文件中的命令,就可以还原数据库本来的状态。
  • AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小。
  • AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有AOF文件进行任何读入、分析或者写人操作。
  • 在执行BGREWRITEAOF命令时,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TEC相关专利研究

每天一篇行业发展资讯,让大家更及时了解外面的世界。 更多资讯,请关注B站/公众号【莱歌数字】,有视频教程~~ 关于TEC在电子行业的部署有很多讨论,这些专利显示了不同发明者关注的一些显著特征。下面的表1列出了本期将审查的专利…

【动态内存】详解

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

AI实战案例!如何运用SD完成运营设计海报?玩转Stable Diffusion必知的3大绝技

大家好我是安琪! Satble Diffusion 给视觉设计带来了前所未有的可能性和机会,它为设计师提供了更多选择和工具的同时,也改变了设计师的角色和设计流程。然而,设计师与人工智能软件的协作和创新能力仍然是不可或缺的。接下来我将从…

Java 中 String 类

目录 1 常用方法 1.1 字符串构造 1.2 字符串包含的成员 1.3 String 对象的比较 1.4 字符串查找 1.5 转化 1.5.1 数值和字符串转化 1.5.2 大小写转化 1.5.3 字符串转数组 1.5.4 格式化 1.6 字符串替换 1.7 字符串拆分 1.8 字符串截取 1.9 其他操作方法 1.10 字符…

DDR3控制器(一)DDR3 IP调用

目录 一、DDR3 IP核简介 二、DDR3 IP核调用 在千兆以太网通信中用到了DDR3控制器,但是并没有对其做相关介绍。这次准备重新整理一下DDR3控制相关知识,复习巩固一下。 一、DDR3 IP核简介 MIG IP核(Memory Interface Generator)是…

SiLM585x系列SiLM5851NHCG-DG一款具有分离的管脚输出 单通道隔离驱动器 拥有强劲的驱动能力

SiLM585x系列SiLM5851NHCG-DG是一款单通道隔离驱动器,具有分离的管脚输出,提供3.0A源电流和6.0A灌电流。主动保护功能包括退饱和过流检测、UVLO、隔离故障报警和 2.5A 米勒钳位。输入侧电源的工作电压为3V至5.5V,输出侧电源的工作电压范围为1…

计算机毕业设计Thinkphp/Laravel学生考勤管理系统zyoqy

管理员登录学生考勤管理系统后,可以对首页、个人中心、公告信息管理、年级管理、专业管理、班级管理、学生管理、教师管理、课程信息管理、学生选课管理、课程签到管理、请假申请管理、销假申请管理等功能进行相应操作,如图5-2所示。学生登录进入学生考勤…

一天跌20%,近500只下跌,低价可转债为何不香了?

6月以来,Wind可转债低价指数累计下跌7.3%,大幅跑输中价、高价转债。分析认为,市场调整的底层逻辑在于投资者对风险的重新评估和流动性的紧缩,宏观经济的波动和政策环境的不确定性、市场结构性的变化均对低价可转债市场产生了冲击。…

ai智能写作助手有哪些?3款AI工具推荐

ai智能写作助手有哪些?在数字化时代的浪潮中,AI智能写作助手如同智慧的灯塔,照亮了创作者们的道路。它们不仅极大地提升了写作效率,让文字流淌更加顺畅,更能够深入挖掘和激发创作者的内在灵感,将创意的火花…

RK3568平台开发系列讲解(I2C篇)利用逻辑分析仪进行I2C总线的全面分析

🚀返回专栏总目录 文章目录 1. 基础协议1.1. 协议简介1.2. 物理信号1.3. 总线连接沉淀、分享、成长,让自己和他人都能有所收获!😄 1. 基础协议 1.1. 协议简介 IIC-BUS(Inter-IntegratedCircuit Bus)最早是由PHilip半导体(现在被NXP收购)于1982年开发。 主要是用来方…

MYSQL 将某个字段赋值当前时间

如 我们需要将use_time 赋值为当前时间: 准备三条数据 : 执行sql ,2种当前时间赋值函数,1种关键字赋值 : update test_info SET use_timeNOW() WHERE id 1; update test_info SET use_timeCURRENT_TIMESTAMP() …

C++并发之阻塞队列(block,queue)

目录 1 概述2 实现3 测试3 运行 1 概述 最近研究了C11的并发编程的线程/互斥/锁/条件变量,利用互斥/锁/条件变量实现一个支持多线程并发的阻塞队列,队列大小没有限制。 阻塞队列是一个模板类,有两个模块参数,参数1是元素类型&…

【芯片】MCU的分类

MCU又称单片微型计算机(Single Chip Microcomputer )或者单片机,是把中央处理器(Central Process Unit;CPU)的频率与规格做适当缩减,并将内存(memory)、计数器(Timer)、USB、A/D转换、UART、PLC、DMA等周边接口,甚至LCD驱动电路都…

MySQL报错Duplicate entry ‘0‘ for key ‘PRIMARY‘

报错现场 现象解释 因为你在插入时没有给 Customer.Id 赋值,MySQL 会倾向于赋值为 NULL。但是主键不能为 NULL,所以 MySQL 帮了你一个忙,将值转换为 0。这样,在第二次插入时就会出现冲突(如果已经有一条记录为 0&…

第二证券:什么是破净股票?破净股票好还是不好?

一家公司手上掌握的财物包含实物财物、公司注册资金、未分配利润、各种公积金及品牌价值等等,一家公司的负债包含贷款、应付款、其他公司给的预付款等等。公司的总财物减去总负债后得到的净财物,再除以股票总数,就是公司的每股净财物&#xf…

【LM-Debugger】让研究人员与开发者能够深入洞察并干预模型的预测过程,开启了模型透明度和可解释性的一扇新门

背景 基于 Transformer 的语言模型 (LM) 是现代 NLP 模型的支柱,但其内部预测构建过程不透明。这对于不了解模型为何做出特定预测的最终用户以及希望调试或修复模型行为的开发人员来说都是个问题用于检查和干预基于转换器的语言模型的交互式工具项目地址&#xff1…

React的Redux的状态管理

步骤 1.创建新项目 npx create-react-app react-redux 2.安装配套工具 npm i reduxjs/toolkit react-redux 3.启动项目 npm run start 4.在src目录下创建store文件夹 5.在store文件夹下创建modules文件夹 6.在store文件夹里创建index.js文件 7.在counterStore.js文件…

【扩散模型(二)】IP-Adapter 从条件分支的视角,快速理解相关的可控生成研究

系列文章目录 【扩散模型(一)】中介绍了 Stable Diffusion 可以被理解为重建分支(reconstruction branch)和条件分支(condition branch)本文将从该视角快速理解 IP-Adapter 以及相关可控生成研究。 文章目…

Open3D 删除点云中重复的点

目录 一、算法原理1、重叠点2、主要函数二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、重叠点 原始点云克隆一份   构造重叠区域   合并点云获得重叠点 2、主要…

第二期书生·浦语大模型实战营优秀项目一览

书生浦语社区于 2023 年年底正式推出了书生浦语大模型实战营系列活动,至今已有两期五批次同学参加大模型学习、实战,线上课程累计学习超过 10 万人次。 实战营特设项目实践环节,提供 A100 算力支持,鼓励学员动手开发。第 2 期实战…