redis当然也提供了类似于快照的功能,主要包括RDB持久化和AOF持久化。两种方法各有各的特点。
RDB持久化
所谓RDB持久化,就是将服务器中某个时刻的数据库状态全部保存为rdb文件,用以备份,并在需要的时候,利用rdb文件对状态进行恢复。学习RDB持久化,就是学习rdb文件保存的是哪些内容,以及是以怎样的方式去保存这些内容。
内容-->状态
内容也就是其状态,所谓状态,就是在特定时刻,服务器中的哪些数据库是有数据的,以及存储了哪些数据。rdb文件需要记录的就是数据的存放地点(对应的数据库标号),数据的格式类型,以及最终的值。当然,rdb有其自身的文件结构,因此,除了数据库数据,还存在一些其他的字符数据,用以构成标准的rdb文件结构。
典型的rdb组织结构如图所示:
RDB持久化.png
对于图中所示的9种Value_Type, 详细类型如下所示。可以看出,程序可以根据Value_Type指示字符得到后续数据的所属对象,并且其底层编码数据结构也可以直接得知,比如对于REDIS_RDB_TYPE_LIST而言,程序知道其是列表对象(REDIS_LIST),并且编码为双向链表(linkedlist);REDIS_RDB_TYPE_LIST_ZIPLIST则指示数据是编码为压缩列表数据结构(ziplist)的列表对象(REDIS_LIST)。
Value_Type |
---|
REDIS_RDB_TYPE_STRING |
REDIS_RDB_TYPE_LIST |
REDIS_RDB_TYPE_SET |
REDIS_RDB_TYPE_ZSET |
REDIS_RDB_TYPE_HASH |
REDIS_RDB_TYPE_LIST_ZIPLIST |
REDIS_RDB_TYPE_ZSET_ZIPLIST |
REDIS_RDB_TYPE_HASH_ZIPLIST |
REDIS_RDB_TYPE_SET_INTSET |
AOF持久化
AOF持久化的思路是,将数据库的所有执行过的写命令,比如SET, SADD这类命令记录下来,而不是去记录具体的键值对数值。具体的概述如下图所示。特别需要注意的是去除冗余的AOF重写操作。比如说连续的执行SET msg "hello"
和DEL msg
一万次,那么数据库之中显然是没有数据,但却要在AOF文件中存储过多的写入命令,冗余太高。AOF重写并不是去分析旧AOF文件的内容,而是分析当前数据库的状态。对,还是状态二字。通过状态的分析,系统得到最简化的写入命令,再重新构建AOF文件,并覆盖之前的旧文件。新的AOF文件照样能够还原数据库的状态,但文件不会再有冗余数据。
阻塞<==>非阻塞
在保存状态的时候,会有阻塞和非阻塞两种形式。阻塞会拒绝新的请求命令,直至完成状态保存;非阻塞方法让子进程来执行状态保存任务,虽然父进程可以去处理请求命令了,但这可能会引起保存下来的状态和系统目前的状态不一致。
AOF给出的解决方案是,父进程在执行请求命令的同时,将这些新的写命令写入到一个缓冲区中,并在子进程完成任务之后,将缓冲区的内容附加到新的AOF文件中。这样就在效率和稳定性上达到了一个很好的平衡。
网友评论