聊一聊redis的持久化

165 阅读2分钟
redis作为一个内存键值数据库,所有的数据都保存在内存中,但是当服务器意外中断后,内存中的数据该怎么办?

当然redis提供了两种持久化功能:
    RDB
    AOF
那么就让我们来聊一聊它们是如何工作的吧!
先说RDB,这种形式的持久化会生成一个经过压缩的二进制文件(dump.rdb),
那么问题来了?这个文件是怎么生成的呢?
    同样也有两个命令,一个是save,是会阻塞服务器进程的
    另一个是bgsave,派生出一个子进程
    当然实际的工作是由rdb.c/rdbSave函数完成
然后,有了rdb文件怎么来恢复数据呢?
    这个是在服务器启动时自动执行的。这个过程也是阻塞的
问题又来了,由谁什么时候去执行bgsave命令呢?
    可以通过配置save选项,由serverCron函数自动执行bgsave
RDB文件中内容是什么?
    保存数据库中的键值对
    
接下来在聊聊AOF,这种形式的持久化会生成一个appendonly.aof文件,里面保存的是服务器所执行的写命令。
如何实现的?
    服务器执行完一个写命令,会以协议格式追加到AOF缓冲区
    将AOF缓冲区中的内容写入AOF文件
    最后进行一次AOF文件的同步
如何恢复数据?
    创建一个伪客户端;
    从AOF文件中分析并读取出一条写命令
    执行读出的写命令
    重复执行直到读出所有的命令
此时有一个问题,随着时间的流逝,AOF文件会越来越大,如何瘦身呢?
    bgrewriteaof命令
aof重写期间,服务器还会继续处理命令,如何解决这种不一致呢?
    执行client的命令
    追加到aof缓冲区
    追加到aof重写缓冲区
    bgrewriteaof完成之后,将aof重写缓冲区的内容写入到新的AOF文件中,完成替换,此步骤是阻塞的
    
两种方式的优先级如何呢?
    原因:AOF文件的更新频率比RDB文件的更新频率高
    所以如果开启了aof功能,服务器会优先使用AOF文件还原数据库,其次才会使用RDB文件还原数据库。
    
有关这两种的具体配置,请大家自行查询相关文档,这里就不多讲了。