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

news2024/10/9 8:30:05

 第 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.coloradmin.cn/o/1863367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于ESP8266串口WIFI模块ESP-01S在AP模式(即发射无线信号( WiFi))下实现STC单片机与手机端网路串口助手相互通信功能

基于ESP8266串口WIFI模块ESP-01S在AP模式(即发射无线信号( WiFi))下实现STC单片机与手机端网路串口助手相互通信功能 ESP8266_01S引脚功能图ESP8266_01S原理图ESP8266_01S尺寸图检验工作1、USB-TTL串口工具(推荐使用搭载CP2102芯片的安信可USB-T1串口)与ESP8266_01S WiFi…

Websocket在Java中的实践——最小可行案例

WebSocket是一种先进的网络通信协议,它允许在单个TCP连接上进行全双工通信,即数据可以在同一时间双向流动。WebSocket由IETF标准化为RFC 6455,并且已被W3C定义为JavaScript API的标准,成为现代浏览器的重要特性之一。 WebSocket的…

代码随想录——跳跃游戏(Leecode55)

题目链接 贪心 class Solution {public boolean canJump(int[] nums) {int cover 0;if(nums.length 1){return true;}// 只有一个元素可以达到for(int i 0; i < cover; i){// 在cover内选择跳跃步数cover Math.max(i nums[i],cover);if(cover > nums.length - 1)…

C++进修——C++核心编程

内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制编码&#xff0c;由操作系统进行管理全局区&#xff1a;存放全局变量和静态变量以及常量栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值&#xff…

如何在FastAPI服务器中添加黑名单和白名单实现IP访问控制

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 添加黑名单功能步骤1:安装依赖步骤2:创建FastAPI应用步骤3:添加黑名单📝 添加白名单功能步骤1:创建白名单列表步骤2:添加白名单检查⚓️ 相关链接 ⚓️📖 介绍 📖 在现代网络应用开发中,为了增强…

【推荐】Prometheus+Grafana企业级监控预警实战

新鲜出炉&#xff01;&#xff01;&#xff01;PrometheusGrafanaAlertmanager springboot 企业级监控预警实战课程&#xff0c;从0到1快速搭建企业监控预警平台&#xff0c;实现接口调用量统计&#xff0c;接口请求耗时统计…… 详情请戳 https://edu.csdn.net/course/detai…

深度挖掘数据资产,洞察业务先机:利用先进的数据分析技术,精准把握市场趋势,洞悉客户需求,为业务决策提供有力支持,实现持续增长与创新

在当今日益激烈的商业竞争环境中&#xff0c;企业想要实现持续增长与创新&#xff0c;必须深入挖掘和有效运用自身的数据资产。数据不仅是企业运营过程中的副产品&#xff0c;更是洞察市场趋势、理解客户需求、优化业务决策的重要资源。本文将探讨如何通过利用先进的数据分析技…

黑马苍穹外卖7 用户下单+订单支付(微信小程序支付流程图)

地址簿 数据库表设计 就是基本增删改查&#xff0c;与前面的类似。 用户下单 用户点餐业务流程&#xff1a; 购物车-订单提交-订单支付-下单成功 展示购物车数据&#xff0c;不需要提交到后端 数据库设计&#xff1a;两个表【订单表orders&#xff0c;订单明细表order_d…

智慧车库管理系统

摘 要 随着城市化进程的不断加快&#xff0c;私家车数量的快速增长给城市交通带来了巨大的挑战&#xff0c;停车问题成为城市交通管理中的一大难题。车辆停车时&#xff0c;在停车场寻找停车位耗时过久&#xff0c;不仅仅浪费用户的时间&#xff0c;还可能引起交通拥堵。城市停…

考研数学一有多难?130+背后的残酷真相

考研数学一很难 大家平时在网上上看到很多人说自己考了130&#xff0c;其实这些人只占参加考研数学人数的极少部分&#xff0c;有个数据可以展示出来考研数学到底有多难&#xff1a; 在几百万考研大军中&#xff0c;能考到120分以上的考生只有2%。绝大多数人的分数集中在30到…

构建实用的Flutter文件列表:从简到繁的完美演进

前言&#xff1a;为什么我们需要文件列表&#xff1f; 在现代科技发展迅速的时代&#xff0c;我们的电脑、手机、平板等设备里积累了大量的文件&#xff0c;这些文件可能是我们的照片、文档、音频、视频等等。然而&#xff0c;当文件数量增多时&#xff0c;我们如何快速地找到…

Arduino平台软硬件原理及使用——开源库的使用

文章目录&#xff1a; 一、库文件的下载及导入 二、库文件源代码说明 三、库文件应用举例 一、库文件的下载及导入 有关arduino开源库的导入有两种方案&#xff1a; 1.第一种方案需要借助arduino.cc网站来进行查询下载&#xff0c;然后在Arduino软件中进行导入。 2.第二种方案则…

判断对象是否为空的多种方式

判断对象是否为空 网上也有许多方法&#xff0c;这里来整理一下 一、Object.keys(obj) ES6 写法&#xff1a; const data {}; const arr Object.keys(data); console.log(arr.length); // 0二、JSON.stringify() const obj {}; const arr JSON.stringify(obj); console.…

【嵌入式DIY实例】-Nokia 5110显示BME280传感器数据

Nokia 5110显示BME280传感器数据 文章目录 Nokia 5110显示BME280传感器数据1、硬件准备与接线2、代码实现本文将介绍如何使用 ESP8266 NodeMCU 板(ESP12-E 模块)和 BME280 气压、温度和湿度传感器构建一个简单的本地气象站。 NodeMCU 从 BME280 传感器读取温度、湿度和压力值…

昂科烧录器支持KIOXIA铠侠的可编程只读存储器TH58NVG4S0HTAK0

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中KIOXIA铠侠的电可擦除可编程只读存储器TH58NVG4S0HTAK0已经被昂科的通用烧录平台AP8000所支持。 TH58NVG4S0HTAK0是一个单一的3.3V 16Gbit&#xff08;18253611008位&#xff…

【C语言】--常见类型和概念

❤️个人主页: 起名字真南 &#x1f495;个人专栏:【数据结构初阶】 【C语言】 目录 第一个C语言程序main函数printf函数库函数关键字字符和ASCII码字符串和\0转义字符 第一个C语言程序 #include<stdio.h> int main() {printf("Hello World\n");return 0; }ma…

Linux 磁盘挂载与分区

Linux 磁盘挂载与分区 vda1: 其中vd表示虚拟磁盘&#xff0c;a表示第一块磁盘&#xff0c;b表示第二块磁盘&#xff0c;1表示第一块磁盘的第一分区&#xff08;显然两块磁盘都只有一个分区&#xff09;图中可以看到&#xff0c;vda1磁盘只有一个分区&#xff0c;且全部挂载到根…

中医背诵笔记(黄帝内经、伤寒论等)

目录 黄帝内经上古天真论今人和古人之差异&#xff08;精神内守&#xff0c;病安从来&#xff1f;&#xff09;男女每个年龄阶段身体状态至人、圣人、贤人 宣明五气篇五脏所藏 与 五脏所主七情与情绪与气的关系 天干地支天干地支与脏腑经络的关系 黄帝内经 上古天真论 今人和…

vue uniapp MEQX JWT认证

1.下载依赖 npm install mqttimport * as mqtt from "mqtt/dist/mqtt.min" ​ 我是用的uniapp vue3 vite这里尝试了很多方式,都导入不进去后来我就采用的本地引入方式, 把mqtt.min.js下载到本地然后在index.html 中导入<script src"./MEQX/mqtt.js" typ…

外媒新闻发稿:2024年度国外主流新闻媒体和海外媒体软文分发平台有哪些?

2024年度主流海外媒体新闻发稿和海外媒体软文分发平台有很多&#xff0c;下面是一些常见的和广受认可的平台&#xff1a; 主流新闻媒体 CNN - 美国知名新闻网络&#xff0c;覆盖广泛的国际新闻。BBC - 英国广播公司&#xff0c;提供全球新闻和深入报道。纽约时报 - 美国主流报…