Redis的持久化

  • Post author:
  • Post category:其他




前言

redis是内存数据库,不持久化数据就会丢失,两种持久化方式RDB与AOF



RDB

RDB是经过压缩的二进制文件,重点:SAVE命令和BGSAVE命令

在这里插入图片描述



SAVE和BGSAVE

  • 两个命令都是执行rdbSave()函数,但是BGSAVE会fork一个子进程执行
  • Redis服务器启动会自动加载rdb文件、或者AOF文件
  • SAVE会阻塞所有客户端的命令
  • BGSAVE会拒绝SAVE,同时延迟BGREWRITEAOF命令到BGSAVE完成以后
  • BGREWRITEAOF会拒绝BGSAVE和SAVE,原因是性能考虑



save选项:持久化的条件

save 900 1
save 300 10
save 60 10000

满足任意一个条件,BGSAVE就会执行

服务器对象有一个saveparam对象数组用于记录时间和次数的条件,除此之外还有dirty计数器和lastsave属性,通过对比saveparam和dirty以及lastsave可以判断是否满足BGSAVE的使用,当然还要配合serverCron()定时任务



RDB文件结构

稍稍看一下就好,只需要知道二进制的形式保存键值对数据,然后不同的键类型和数据类型保存格式也不同,大体上是(元素个数 + 字符个数 + 字符 + 字符个数 + 字符)的形式。



总体

在这里插入图片描述



databases

在这里插入图片描述



合二为一

在这里插入图片描述



pairs

在这里插入图片描述



带有过期时间

在这里插入图片描述

对于不同的键值,redis有不同的方式保存



字符串对象

在这里插入图片描述



列表对象

在这里插入图片描述



集合对象

在这里插入图片描述



哈希对象

在这里插入图片描述



有序集合

在这里插入图片描述



intset编码的集合

会先将整数集合转化为字符串,读取的时候再根据REDIS_RDB_TYPE_SET_INTSET转化回来



ZIPLIST编码的列表、哈希、有序集合:

也会将压缩列表转化为字符串保存



AOF

aof全称append only file是另外一种持久化格式,与Redis二进制字符串存储键值对不同的是,aof直接用文本格式将执行过的命令保存下来。AOF持久化有三个步骤:append、write和sync



持久化策略

Redis服务器本身就是一个事件循环,循环的文件事件处理,循环的定时任务,我么可以通过配置appendfsync来选择AOF持久化的频率。

  • Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
  • Everysec,每秒写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;
  • No,操作系统控制的写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘



AOF重写

因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝,AOF文件中的内容会越来越多,文件的体积也会越来越大,如果不加以控制的话,体积过大的AOF文件很可能对Rdis服务器、甚至整个宿主计算机造成影响,并且AOF文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。



BGREWRITEAOF命令

首先AOF重写放在主线程中执行会造成长时间的阻塞,所以需要fork一个子进程来执行,这也就是BGREWRITEAOF的执行原理,步骤如下:

  1. 服务器正常执行写命令,该写入写入,该同步同步。
  2. 服务器同时fork一个子进程执行重写操作,且将写命令发送到AOF重写缓冲区保存重写过程中的新命令。(重写使用的是新的AOF文件)
  3. 重写完毕后,子线程将AOF重写缓存区的写命令发送到主线程,主线程写入新AOF文件
  4. AOF文件执行新旧替换
  5. 完成

    讲一下为啥要不能写同一份AOF文件,因为如果重写失败,那数据不就丢失了,所以两份保险。



版权声明:本文为qq_41606730原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。