redis 笔记03 RDB 持久化、AOF持久化、事件、客户端

RDB 持久化

1. RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据。

2. SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器。

3. BGSAVE由子进程执行保存操作,所以该命令不会阻塞服务器。(BG:background)

4. 服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器就自动执行BGSAVE命令。(多个设置条件,处理不同的情况,思想)

5. RDB文件是一个经过压缩的二进制文件,由多个部分组成。

6. 对于不同类型的键值对,RDB文件会使用不同的方式来保存它们。

7. Redis是内存数据库,它将自己的数据库状态存储在内存里面。RDB持久化功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。

8. Redis没有专门用于载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件,它就会自动载入RDB文件。

9. 通常情况下,AOF文件的更新频率比RDB文件的更新频率高,所以如果服务器开启了AOF持久化功能,那么服务器就会优先使用AOF文件来还原数据库状态。只有在AOF持久化功能

    处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。

10. 在执行BGSAVE命令期间,新的SAVE,BGSAVE 命令会被拒绝执行,BGREWRITEAOF命令会被延迟执行。如果在执行BGREWRITEAOF,那么BGSAVE命令会被拒绝。

11. 服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止

12. 用于可以通过save选项设置多个保存条件,但只要其中任意一个条件被满足,服务器就会执行BGSAVE命令。举个例子,如果我们向服务器提供一下配置:      

save 900 1     // 服务器在900秒以内,对数据库进行至少1次修改时,执行BGSAVE命令
save 300 10    // 服务器在300秒以内,对数据库进行至少10次修改时,执行BGSAVE命令
save 60 10000  // 服务器在60秒以内,对数据库进行至少10000次修改

      修改频率低时,保证修改会被保存。修改频率高时,及时保存。(思想)

13. Redis的服务器周期性操作函数serverCron默认每隔100毫秒就会执行一次,该函数用以对正在执行的服务器进行维护,它的其中一项工作就是检查save选项所设置的保存条件

      是否以满足,如果满足的话,就执行BGSAVE命令。

14. RDB文件由 "REDIS"字符串,db_version(数据库版本),databases(数据库内容),EOF(结束标志),check_sum(校验和,判断文件是否完整)

15. Redis本身带有RDB文件检索工具redis-check-dump,网上也能找到很多处理RDB文件的工具。

AOF持久化

1. AOF文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态。

2. AOF文件中的所有命令都以Redis命令请求协议的格式保存。

3. 命令请求会先保存到AOF缓冲区里面,之后再定期写入并同步到AOF文件。(思想:避免多次寻址和多次写入?还是内存写入更快,后续再逐步写入到磁盘?)

4. appendfsync(持久化设置条件)选项的不同值对AOF持久化功能的安全性以及Redis服务器的性能有很大影响。

5. 服务器只要载入并重新执行保存在AOF文件中的命令,就可以还原数据库本来的状态。

6. AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文案所保存的数据库状态一样,但体积更小。

7. AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无需对现有的AOF文件进行任何读入、分析或者写入操作。

8. 在执行BGREWRITEAOF命令时,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作以后,

    服务器将会重写缓冲区中的所有内容追加到新AOF文件末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作。(思想)

9. RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态。

10. 服务器在启动时,可以通过载入和执行AOF文件中的保存命令来还原服务器关闭之前的数据库状态。

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

12. appendfysync 选项的值,默认值为everysec :

      always : 将aof_buf缓冲区中的所有内容写入并同步到AOF文件。

      everysec : 将aof_buf缓冲区中的所有内容写入到AOF文件,如果上次同步AOF文件的时间距离现在超过了一秒钟,那么在此对AOF文件进行同步,并且这个同步操作是由一个线程专门负责执行的。

      no : 将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统来决定。

13. Redis读取AOF文件还原数据库状态的详细步骤如下:

      1). 创建一个不带网络连接的伪客户端。

      2). 从AOF文件中分析并读取出一条写命令。

      3). 使用伪客户端执行被读出的写命令。

      4). 一直执行步骤2和步骤3,直到AOF文件中的所有命令都被处理完毕。

14. Redis 将AOF重写放入到子进程中执行,这样做可以同时达到两个目的(思想):

     1). 子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求

     2). 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。

15. 在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞。

RDB与AOF比较

RDB:

优点:

1).RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。这种文件非常适合用于进行备份。

2).RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

缺点:

1). RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。

2). 每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端;如果

     数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。

AOF:

优点:

1). 使用AOF持久化会 Redis变得非常耐久(much more durable),更新频率更高:你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync。AOF 文件

     是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,

     等等), redis-check-aof 工具也可以轻易地修复这种问题。

2). Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的。

缺点:

1). 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

2). AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。

RDB和AOF选择:

RDB 和 AOF 共同备份,RDB作为灾难备份。

参考地址:http://my.oschina.net/davehe/blog/174662

事件

1. Redis服务器是一个事件驱动程序,服务器处理的事件分为时间事件(定时事件)和文件事件(与客户端交互)两类。

2. 文件事件处理器是基于Reactor模式实现的网络通信程序。文件事件处理器会同时监听多个套接字。保持了Redis内部单线程设计的简单性。

3. 文件事件是对套接字操作的抽象:每次套接字变成可应答(acceptable)、可写入(writable)或者可读(readable)时,相应的文件事件就会产生。

4. 文件事件分为AE_READABLE事件(读事件)和AE_WRITABLE事件(写事件)两类。

5. 时间事件分为定时事件和周期性事件:定时事件只在指定的时间到达一次,而周期性事件则每隔一段时间到达一次。

6. 服务器在一般情况下只执行serverCron函数一个时间事件,并且这个事件是周期性事件。

7. 文件事件和时间事件之间是合作关系,服务器会轮流处理这两种事件,并且处理时间的过程也不会进行抢占。

8. 因为时间事件在文件事件之后执行,并且事件之间不会出现抢占,所以时间事件的实际处理时间,通常会比时间事件设定的到达时间稍晚一些。

9. 时间事件应用实例:serverCron函数,主要包括以下工作:

    1). 更新服务器的各类统计信息,比如时间,内存占用,数据库占用情况等。

    2). 清理数据库中的键值对。

    3). 关闭和清理连接失效的客户端。

    4). 尝试进行AOF和RDB持久化操作

    5). 如果服务器是主服务器,那么对从服务器进行定期同步。

    6). 如果处于集群模式,对集群进行定期同步和连接测试。

10. Redis服务器以周期性事件的方式来运行serverCron函数,在服务运行期间,每隔一段时间,serverCron就会执行一次,直到服务器关闭为止。

11. 从Redis2.8开始,用户可以通过修改hz选项来调整serverCron的每秒执行次数。2.6版本中默认规定serverCron每秒执行10次。

12. Redis在遍历时间事件链表的时候,会取出最快执行的事件,以此来避免每次轮询。(思想)

13. Redis为文件事件编写了多个处理器,这些事件处理器分别用于实现不用的网络通信需求。

14. 服务器将所有时间事件放在一个无序链表中,每当时间事件执行器运行时,他就遍历整个链表,查找所有已到达的时间事件,并调用相应的事件处理器。(将同类型时间,放到一个集合中,方便处理。思想)

客户端:

1. 服务器状态结构使用clients链表连接起多个客户端状态,新添加的客户单状态会被放到链表的末尾。

2. 客户端状态的flags属性使用不同标志来表示客户端的角色,以及客户端当前所处的状态。

3. 输入缓冲区记录了客户端发送的命令请求,这个缓冲区的大小不能超过1G。

4. 命令参数和参数个数会被记录在客户端状态的argv和argc属性里面,而cmd属性则记录了客户端要执行命令的实现函数。

5. 客户端由固定大小缓冲区和可变大小缓冲区两种缓冲区可用(思想),其中固定大小缓冲区的最大大小为16KB,而可变大小缓冲区的最大大小不能超过服务器设置的硬性限制。

6. 输入缓冲区限制有两种,如果输出缓冲区的大小超过了服务器设置的硬性限制,那么客户端会被立即关闭;除此之外,如果客户端在一定时间内,一直超过服务器设置的软性限制,那么客户端也会被关闭。

7. 当一个客户端通过网络连接上服务器时,服务器会为这个客户端创建相应的客户端状态。网络连接关闭、发送了不合协议格式的命令请求、成为CLIENT KILL命令的目标、

   空转时间超时、输出缓冲区的大小超出限制,以上这些原因就会造成客户端被关闭。

8. 处理Lua脚本的伪客户端在服务器初始化时创建,这个客户端会一直存在,直到服务器关闭。

9. 载入AOF文件时使用的伪客户端在载入工作开始时动态创建,载入工作完毕之后关闭。

10. 在默认情况下,一个连接到服务器的客户端是没有名字的。使用CLIENT setname命令可以为客户端设置一个名字,让客户端身份变得更清晰。

11. PUBSUB命令和SCRIPTLOAD命令没有修改数据库,但修改了服务器状态,所以需要强制将这个命令写入到AOF文件中。另外,为了让主服务器和从服务器都可以正确地载入SCRIPT LOAD命令

      指定的脚本,服务器需要使用REDIS_FORCE_REPL标志,强制将SCRIPT LOAD命令复制给所有从服务器。

12. 可以使用client-output-buffer-limit选项可以为普通客户端、从服务器端客户端、执行发布与订阅功能的客户端分别设置不同的软性限制和硬性限制。格式为:

      client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

13. Redis服务器使用单线程单进程的方式来处理命令请求,并与多个客户端进行网络通信。 

14. 在主从服务器进行复制操作时,主服务器会成为从服务器的客户端,而从服务器也会成为主服务器的客户端。

15. 客户端authenticated属性用于记录客户端是否通过了身份验证。仅在服务器启用了身份验证功能时使用。

原文地址:https://www.cnblogs.com/Jtianlin/p/5107935.html