Redis 持久化方式(AOF RDB 混写)
文章目录
AOF
AOF 日志格式
- AOF 日志里面记录的是 Redis 接收到的每条命令
- AOF 日志格式:
- “*3"表示当前命令有三个部分
- “$数字”:表示表示这部分中的命令、键、值一共有多少字节
- set/key1/value1:具体的命令、键、值
|
|
写回策略
- Always:同步写回,每个写命令执行完后,都会执行 fsync()
- 可以保重数据不丢失,但是每次落盘操作都由主线程执行,可能会堵塞下一条命令的执行
- Everysec:每秒写回,每个写命令执行完后,并不会直接落盘,而是写入操作系统的写buffer中,每秒执行 fsycn()
- 减少了每次写操作都刷盘的压力,但是系统宕机会丢失上一秒的数据
- No:由操作系统控制写回,Redis 将日志写入系统的写buffer中,由操作系统决定什么时候写入磁盘
- 性能比较好,但是宕机时会丢失比较多的数据
AOF 重写
概述
- 随着数据变更的增多,AOF 日志会不断增大,Redis 启动时加载数据所需的时间也会增加
- 大量对于一个 key 的多次变更操作,导致一个 key 在日志中存储多分数据
- AOF 重写相当于压缩掉中间 key 的变更、只保留 key 的终态结果
- 重写机制最后会记录 set testkey testvalue 这样的命令。这样,在恢复时,可以重新执行该命令,实现 “testkey”: “testvalue” 的写入
执行方式(BGREWRITEAOF)
- 每次执行重写时,主线程 fork 出后台的 bgrewriteaof 子进程。此时,fork 会把主线程的fork(Copy On Write)拷贝一份给 bgrewriteaof 子进程,这里面就包含了数据库的最新数据。
- 然后,bgrewriteaof 子进程就可以在不影响主线程的情况下,逐一把拷贝的数据写成操作,记入重写日志。
- 执行期间内的 AOF 日志,仍会写入新旧两个 AOF 文件的缓冲区
- 写入旧 AOF 日志文件 用于防止这段期间内异常宕机引起的数据丢失
- 写入新 AOF 日志文件 用于保证数据一致
RDB
RDB 格式
- RDB 的持久化方式就类似于 内存快照,相当于把内存中的所有数据保存到磁盘中
- RDB 记录的是某一时刻的数据,并不是操作,所以,在做数据恢复时,我们可以直接把 RDB 文件读入内存,很快地完成恢复
执行方式(BGSAVE/SAVE)
- SAVE:在主线程中执行,会导致阻塞;
- BASAVE:建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞
- 子进程会 fork 一份内存地址、采用 Copy On Write 的方式拷贝数据 需保证内存充足,极限情况下(bgsave 期间 Redis 中所有数据均发生变更)会完全复制一份内存,redis 内存大小会变为之前的两倍
AOF RDB 混写
- 内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作
- 实际上还是以 AOF 的持久化配置调用,但是 AOF 重写时,并不是写 set key value 的方式,而是用 RDB 的方式写在 AOF 重写文件的头部,后续变更仍以 AOF 方式追加。
配置文件
AOF
- appendonly:no/yes 默认为 no,是否开启 AOF
- appendfilename “appendonly.aof”:持久化文件的名称
- appendfsync always/everysec/no:AOF 落盘策略
- no-appendfsync-on-rewrite no/yes:落盘时机为 everysec 或 always 时,后台如果有正在重写文件(包括bgsave、bgrewriteaof、bgrewriteaof)时,推迟 fsync() 的调用
- auto-aof-rewrite-percentage:Redis能够在AOF文件大小增长了指定百分比时,自动隐式调用 BGREWRITEAOF 命令进行重写
- 计算方法:当前AOF文件大小和上一次重写后AOF文件大小的差值,再除以上一次重写后AOF文件大小。也就是当前AOF文件比上一次重写后AOF文件的增量大小,和上一次重写后AOF文件大小的比值。
- Redis记录上一次执行AOF重写后的文件大小作为基准。(如果启动后没有发生过重写,则使用启动时的AOF文件大小)。
- 将该基准值与当前文件大小进行比较,如果当前体积超出基准值的指定百分比,将触发重写。
- auto-aof-rewrite-min-size 64mb:AOF 日志小于 64mb 时,不触发 AOF 重写
- aof-load-truncated:Redis 基于 AOF 日志恢复时,遇到文件末尾截断时,是继续加载文件还是报错退出
- Redis所在的机器运行崩溃,就可能导致该现象
- 当发生了末尾截断,Redis可以选择直接报错退出,或者继续执行并恢复尽量多的数据(默认选项)
- yes :末尾被截断的 AOF 文件将会被加载,并打印日志通知用户。
- no :服务器将报错并拒绝启动。(可使用 redis-check-aof 修复 AOF 文件)
RDB
- save 3600 1:3600秒内,至少有1个key值改变,则落盘
- save “":关闭 RDB 持久化方式
- stop-writes-on-bgsave-error no/yes:默认为no,如果RDB文件写入过程中出错、Redis则认为持久化出现问题、会禁止所有的写入操作
- rdbcompression yes:Redis 写 RDB 文件时,是否压缩
- rdbchecksum:默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
AOF/RDB 混合落盘
- aof-use-rdb-preamble yes/no:AOF 重写时,在文件头写入 RDB 文件,而不是类似于set kye value 的AOF文件,后续变更用AOF格式文件追加
文章作者 Xiang
上次更新 2021-06-06