Redis设计与实现(11-15章)
Redis设计与实现(11-15章)
第11章:AOF持久化
与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。其中,被写入AOF文件的所有命令都是以Redis的命令请求协议保存的。Redis的命令请求协议是纯文本格式。
AOF的持久化功能的实现可以分为命令追加、文件写入、文件同步三个步骤。
命令请求会先保存到AOF缓冲区里面,之后再定期写入并同步到AOF文件。
appendfsync选项的不同值对AOF持久化功能的安全性以及Redis服务器的性能有很大的影响。
服务器只要载入并重新执行保存在AOF文件中的命令,就可以还原数据库本来的状态。
AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小。
AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有AOF文件进行任何读入、分析或者写入操作。
在执行BGREWRITEAOF命令时,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作。
重点回顾
AOF文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态。
AOF文件中的所有命令都以Redis命令请求协议的格式保存。
命令请求会先保存AOF缓存区里面,之后在定期写入并同步到AOF文件。
服务器只要菜如并重新执行保存在AOF文件中的命令,就可以还原数据库本来的状态。
AOF重写可以产生一个新的AOF文件中的命令,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小。
AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有AOF文件进行任何读入、分析或者写入操作。
第12章:事件
Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:
1)文件事件:
Redis服务器通过套接字与客户端(或者其他Redis服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或者其他服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作。
1)文件事件:
Redis服务器通过套接字与客户端(或者其他Redis服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或者其他服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作。
文件事件处理器是基于Reactor模式实现的网络通信程序,其以单线程方式运行,但通过使用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
当被监听的套接字准备好执行连接应答、读取、写入、关闭等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
文件处理器分为AE_READABLE事件(读事件)和AE_WRITABLE事件(写事件)两类。
文件处理器的四个组成部分:套接字、I/O多路复用程序、文件事件分派器,以及事件处理器。
Redis的I/O多路复用程序的所有功能都是通过包装常见的select、epoll、evport和kqueue这些I/O多路复用函数库来实现,每个I/O多路复用函数库在Redis源码中都对应一个单独的文件,比如ae_select.c、ae_epoll.c、ae_kqueue.c,诸如此类。
2)时间事件:
Redis服务器中的一些操作(比如serverCron函数)需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。
Redis的时间时间分为两类:定时事件让一段程序在指定的时间之后执行一次。.周期性事件则让一段程序每隔指定时间就执行一次。
一个时间事件主要由以下三个属性组成:
id:服务器为时间时间创建的全局唯一ID(标识号)。ID号按从小到大的顺序递增,新事件的ID号比旧事件的ID号要大。
Redis的时间时间分为两类:定时事件让一段程序在指定的时间之后执行一次。.周期性事件则让一段程序每隔指定时间就执行一次。
一个时间事件主要由以下三个属性组成:
id:服务器为时间时间创建的全局唯一ID(标识号)。ID号按从小到大的顺序递增,新事件的ID号比旧事件的ID号要大。
when:毫秒精度的UNIX时间戳,记录了时间事件处理器的返回值。
timeProc:时间事件处理器,一个函数。当时间事件到达时,服务器就会调用相应的处理器来处理事件。
文件事件和时间事件之间是合作关系,服务器会轮流处理这两种事件,并且处理事件的过程中也不会进行抢占。
时间事件的实际处理时间通常会比设定的到达时间晚一些。
文件事件和时间事件之间是合作关系,服务器会轮流处理这两种事件,并且处理事件的过程中也不会进行抢占。
时间事件的实际处理时间通常会比设定的到达时间晚一些。
重点回顾
Redis服务器是一个事件驱动程序,服务器处理的事件分为时间事件和文件事件两类。
文件事件处理器是基于Reactor模式实现的网络通信程序。
文件事件和时间事件之间是合作关系,服务器会轮流处理这两种时间,冰球处理时间的过程中也不会进行抢占。
时间时间的实际处理时间通常会比设定的到达时间晚一些。
第13章:客户端
Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。
服务器状态结构使用clients链表连接起多个客户端状态,新添加的客户端状态会被放到链表的末尾。
客户端状态的flags属性使用不同标志来表示客户端的角色,以及客户端当前所处的状态。
输入缓冲区记录了客户端发送的命令请求,这个缓冲区的大小不能超过1GB。
命令的参数和参数个数会被记录在客户端状态的argv和argc属性里面,而cmd属性则记录了客户端要执行命令的实现函数。
客户端有固定大小缓冲区和可变大小缓冲区两种缓冲区可用,其中固定大小缓冲区的最大大小为16KB,而可变大小缓冲区的最大大小不能超过服务器设置的硬性限制值。
输出缓冲区限制值有两种,如果输出缓冲区的大小超过了服务器设置的硬性限制,那么客户端会被立即关闭;除此之外,如果客户端在一定时间内,一直超过服务器设置的软性限制,那么客户端也会被关闭。
当一个客户端通过网络连接连上服务器时,服务器会为这个客户端创建相应的客户端状态。网络连接关闭、发送了不合协议格式的命令请求、称为CLIENT KILL命令的目标、空转时间超时、输出缓冲区的大小超出限制,以上这些原因都会造成客户端被关闭。
Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。
服务器状态结构使用clients链表连接起多个客户端状态,新添加的客户端状态会被放到链表的末尾。
客户端状态的flags属性使用不同标志来表示客户端的角色,以及客户端当前所处的状态。
输入缓冲区记录了客户端发送的命令请求,这个缓冲区的大小不能超过1GB。
命令的参数和参数个数会被记录在客户端状态的argv和argc属性里面,而cmd属性则记录了客户端要执行命令的实现函数。
客户端有固定大小缓冲区和可变大小缓冲区两种缓冲区可用,其中固定大小缓冲区的最大大小为16KB,而可变大小缓冲区的最大大小不能超过服务器设置的硬性限制值。
输出缓冲区限制值有两种,如果输出缓冲区的大小超过了服务器设置的硬性限制,那么客户端会被立即关闭;除此之外,如果客户端在一定时间内,一直超过服务器设置的软性限制,那么客户端也会被关闭。
当一个客户端通过网络连接连上服务器时,服务器会为这个客户端创建相应的客户端状态。网络连接关闭、发送了不合协议格式的命令请求、称为CLIENT KILL命令的目标、空转时间超时、输出缓冲区的大小超出限制,以上这些原因都会造成客户端被关闭。
处理Lua脚本的伪客户端在服务器初始化时创建,这个客户端会一直存在,直到服务器关闭。
载入AOF文件时使用的伪客户端在载入工作开始时动态创建,载入工作完毕之后关闭。
第14章:服务器
Redis服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。
一个命令请求从发送到完成主要包括以下步骤:
1)客户端将命令请求发送给服务器;2)服务器读取命令请求,并分析出命令参数;3)命令执行器根据参数查找命令的实现函数,然后执行实现函数并得出命令回复;4)服务器将命令回复返回给客户端。
serverCron函数默认每隔100毫秒执行一次,它的工作主要包括更新服务器状态信息,处理服务器接收的SIGTERM信号,管理客户端资源和数据库状态,检查并执行持久化操作等等。
服务器从启动到能够处理客户端的命令请求需要执行以下步骤:
服务器从启动到能够处理客户端的命令请求需要执行以下步骤:
1)初始化服务器状态;2)载入服务器配置;3)初始化服务器数据结构;4)还原数据库状态;5)执行事件循环。
重点回顾
一个命令请求从发送到完成主要包括以下步骤:1)客户端将命令请求发送到服务器;2)服务器读取命令请求,并分析出命令参数;3)命令执行器根据参数查找命令的实现函数,然后执行实现函数并得出命令回复;4)服务器将命令回复返回给客户端。
服务器从启动到能够处理客户端的命令请求需要执行以下步骤:1)初始化服务器状态;2)载入服务器配置;3)初始化服务器数据结构;4)还原数据库状态;5)执行事件循环。
第15章:复制
在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制另一个服务器,我们称呼被复制的服务器为主服务器,而对主服务器进行复制的服务器则被称为从服务器。
在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制另一个服务器,我们称呼被复制的服务器为主服务器,而对主服务器进行复制的服务器则被称为从服务器。
Redis的复制功能分为同步和命令传播两个操作:
1)同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态。 2)命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。
在Redis2.8以前,从服务器对主服务器的复制可以分为以下两种情况:
1)初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。
2)断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但服务器通过自动重连接重新连上了主服务器,并继续复制主服务器。
为解决旧版复制功能在处理断线重复制情况时的低效问题,Redis从2.8版本开始,使用PSYNC命令代替SYNC命令来执行复制时的同步操作。PSYNC命令具有完整重同步和部分重同步两种模式:
1)完整重同步用于处理初次复制情况:完整重同步的执行步骤和SYNC命令的执行步骤基本一样,它们都是通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步。
2)部分重同步则用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。部分重同步通过复制偏移量、复制积压缓冲区、服务器运行ID三个部分来实现。
在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向主服务器发送命令请求来执行复制步骤,而在复制操作的后期,主从服务器会互相成为对方的客户端。
主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一致,而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。
1)同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态。 2)命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。
在Redis2.8以前,从服务器对主服务器的复制可以分为以下两种情况:
1)初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。
2)断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但服务器通过自动重连接重新连上了主服务器,并继续复制主服务器。
为解决旧版复制功能在处理断线重复制情况时的低效问题,Redis从2.8版本开始,使用PSYNC命令代替SYNC命令来执行复制时的同步操作。PSYNC命令具有完整重同步和部分重同步两种模式:
1)完整重同步用于处理初次复制情况:完整重同步的执行步骤和SYNC命令的执行步骤基本一样,它们都是通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步。
2)部分重同步则用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。部分重同步通过复制偏移量、复制积压缓冲区、服务器运行ID三个部分来实现。
在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向主服务器发送命令请求来执行复制步骤,而在复制操作的后期,主从服务器会互相成为对方的客户端。
主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一致,而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。
重点回顾
部分重同步通过复制偏移量、复制积压缓冲区、服务器运行ID三个部分来实现。
在复制操作刚开始的时候,从服务器会成为主服务器的客户端,并通过向朱服务器发送命令请求来执行服务步骤,而在复制操作的后期,主服务器会互相成为对方的客户端。
主服务器通过向从服务器传播命令来更新从服务器的状态,保持主从服务器一直,而从服务器则通过向主服务器发送命令来进行心跳检测,以及命令丢失检测。