当前位置: 首页>編程日記>正文

Redis学习三:设计与实现之单机数据库的实现

Redis学习三:设计与实现之单机数据库的实现

Redis学习三:设计与实现之单机数据库

  • 前言
  • 数据库键空间
    • 键空间的结构
    • 读写键空间时的维护操作
  • RDB文件
    • RDB文件结构
    • RDB文件介绍
    • RDB触发规则
    • RDB优点
    • RDB缺点
  • AOF持久化的实现
    • AOF持久化操作
    • AOF文件同步的效率与安全性
    • AOF的还原数据过程
    • AOF优点
    • AOF缺点
  • Redis的文件事件
    • 文件事件处理器的组成部分
  • Redis命令请求的执行过程

前言

本文来源于《Redis的设计与实现》第二章节的学习,是这本书的简要读书笔记,仅作为记录所用,希望以后能常常温故知新~~~

数据库键空间

Redis 是一个键值对(key-value pair)数据库服务器, 服务器中的每个数据库都由一个 redis.h/redisDb 结构表示, 其中, redisDb 结构的dict 字典保存了数据库中的所有键值对, 我们将这个字典称为键空间(key space):

键空间的结构

typedef struct redisDb { // ... // 数据库键空间,保存着数据库中的所有键值对 dict *dict; // ... 
} redisDb;

键空间中的键:字符串对象
键空间中的值:字符串对象 / 列表对象 / 哈希表对象 / 集合对象 / 有序集合对象 中的任意一种

例如:

redis> SET message "hello world" 
OK 
redis> RPUSH alphabet "a" "b" "c" 
(integer) 3 
redis> HSET book name "Redis in Action" 
(integer) 1 
redis> HSET book author "Josiah L. Carlson" 
(integer) 1 
redis> HSET book publisher "Manning" 
(integer) 1

它所对应的键空间结构如下:
请添加图片描述

读写键空间时的维护操作

当使用Redis命令对数据库进行读写时,服务器不仅会对键空间执行指定的读写操作,还会执行一些额外的维护操作,其中包括:

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

RDB文件

RDB文件结构

REDIS | db_version | databases | EOF | check_sum
  • REDIS : 5字节,保存着 “REDIS” 五个字符,检查是否为RDB文件的标识;
  • db_version : 4字节,值是字符串表示的整数,表示RDB文件的版本号,例如“0006”;
  • databases 包含0或者多个数据库,以及各个数据库中的键值对数据;
  • EOF 常量的长度为 1 字节, 这个常量标志着 RDB 文件正文内容的结束;
  • check_sum 是一个 8 字节长的无符号整数, 保存着一个校验和,这个校验和是程序通过对 REDIS 、 db_version 、 databases 、 EOF 四个部分的内容进行计算得出的。

RDB文件介绍

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

RDB触发规则

  • save 规则满足的情况下,会自动触发RDB规则;
  • 执行 flushall 命令,也会触发RDB规则;
  • 退出redis,也会产生RDB文件;

备份的时候自动会生成一个dump.rdb;如果需要恢复rdb文件,只需要将rdb文件放在redis启动目录下面就可以了,redis启动的时候会自动恢复;

RDB优点

适合大规模的数据恢复!对数据的完整性要求不高!

RDB缺点

需要一定的时间间隔进程操作! 如果redis意外宕机了,最后一次修改数据就没有了!fork进程的时候,会占用一定的内存空间;

AOF持久化的实现

AOF持久化操作

AOF持久化功能的实现可以分为 : 命令追加 文件写入 文件同步 三个步骤:

struct redisServer { // ... // AOF 缓冲区 sds aof_buf; // ... 
};
  • 命令追加: 当 AOF 持久化功能处于打开状态时, 服务器在执行完一个写命令之后, 会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾;
  • 写入与同步:由于可能aof_buf缓冲区有内容追加,所以服务器每次结束一个事件循环前会调用 flushAppendOnlyFile 函数, 考虑是否需要将 aof_buf 缓冲区中的内容写入和保存到 AOF 文件里面;

为了提高文件的写入效率, 在现代操作系统中, 当用户调用 write 函数, 将一些数据写入到文件的时候, 操作系统通常会将写入数据暂时保存在一个内存缓冲区里面, 等到缓冲区的空间被填满、或者超过了指定的时限之后, 才真正地将缓冲区中的数据写入到磁盘里面,这里需要将 写入 同步 区分开来;

AOF文件同步的效率与安全性

AOF文件同步的效率与安全性主要由服务器配置appendfsync来决定:

  • appendfsync = always
    服务器在每个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件, 并且同步 AOF 文件, 所以 always 的效率是 appendfsync 选项三个值当中最慢的一个,但也是最安全的;
  • appendfsync = everysec
    服务器在每个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件, 并且每隔超过一秒就要在子线程中对 AOF 文件进行一次同步;效率快,并且就算故障停机,数据库仅丢失1s的命令数据;
  • appendfsync = no
    服务器在每个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件, 至于何时对 AOF 文件进行同步, 则由操作系统控制。这个模式下AOF写入速度是最快的,但该模式会在系统缓存中积累一段时间的写入数据;

AOF的还原数据过程

AOF 模式默认是不开启的,默认是使用RDB方式持久化的,我们需要手动配置,只需要将appendonly由no 修改为 yes 就开启了 AOF,重启,redis就生效了,如果 AOF文件有错位,redis是无法启动的,这时候我们可以通过redis-check-aof --fix appendonly.aof 来修复AOF文件;

AOF 文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态,所有命令都以Redis命令请求协议的格式保存,服务器只要载入并重新执行保存在 AOF 文件中的命令, 就可以还原数据库本来的状态。

在执行 BGREWRITEAOF 命令时, Redis 服务器会维护一个 AOF 重写缓冲区, 该缓冲区会在子进程创建新 AOF 文件的期间, 记录服务器执行的所有写命令。 当子进程完成创建新 AOF 文件的工作之后, 服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾, 使得新旧两个 AOF 文件所保存的数据库状态一致。 最后, 服务器用新的 AOF 文件替换旧的 AOF 文件, 以此来完成 AOF 文件重写操作。

AOF优点

每一次修改都会同步,文件的完整性会更加好;

AOF缺点

相对于数据文件量而言,aof远远大于rdb,修复速度也会慢;aof运行效率慢,因此redis默认的配置是rdb;

Redis的文件事件

Redis基于Reactor模式开发了网络事件处理器——文件事件处理器,使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。虽然文件事件处理器以单线程方式运行, 但通过使用 I/O 多路复用程序来监听多个套接字, 文件事件处理器既实现了高性能的网络通信模型, 又可以很好地与 Redis 服务器中其他同样以单线程方式运行的模块进行对接, 这保持了 Redis 内部单线程设计的简单性。

文件事件处理器的组成部分

请添加图片描述
文件事件是对套接字操作的抽象, 每当一个套接字准备好执行连接应答(accept)、写入、读取、关闭等操作时, 就会产生一个文件事件。 因为一个服务器通常会连接多个套接字, 所以多个文件事件有可能会并发地出现。

I/O多路复用程序总是会将所有产生事件的套接字入队到一个队列中,通过这个队列,有序、同步、一次一个套接字的方式向文件事件分派器传送套接字;
请添加图片描述
Redis服务事件分为:文件事件 与 时间事件,其中,服务器一般仅执行 serverCron函数 这一个时间事件,而文件事件分为 读事件 与 写事件;

Redis命令请求的执行过程

例如 客户端发送set key value到获取回复OK的过程中:

  • 客户端向服务器发送命令请求 SET KEY VALUE 。
  • 服务器接收并处理客户端发来的命令请求 SET KEY VALUE , 在数据库中进行设置操作, 并产生命令回复 OK 。
  • 服务器将命令回复 OK 发送给客户端。
  • 客户端接收服务器返回的命令回复 OK , 并将这个回复打印给用户观看。

而服务器从启动到能够处理客户端的命令请求需要执行以下步骤:

  • 初始化服务器状态;
  • 载入服务器配置;
  • 初始化服务器数据结构;
  • 还原数据库状态;
  • 执行事件循环;

serverCron 函数默认每隔 100 毫秒执行一次, 它的工作主要包括更新服务器状态信息, 处理服务器接收的 SIGTERM 信号, 管理客户端资源和数据库状态, 检查并执行持久化操作, 等等。


https://www.fengoutiyan.com/post/15787.html

相关文章:

  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機