Redis持久化的方式

Redis为什么要持久化?


试想一个场景,你的redis在某一天被一个bad egg拔断了电源,而redis是基于内存存数据的,但是内存断电即失。。。你该如何是好?

幸运的是,redis提供了两种持久化的方式,并且基于这两种提出了混合持久化方案,应有尽有,满足你的需求!

Redis的两种持久化方式

RBD

简介


RDB,全称Redis Database Backup(file),翻译redis数据库备份,很直接奥!

流程


  1. 在配置文件中配置开启rdb(其实默认是开启的,redis不会让你伤心的!!!)

  2. 当redis服务器在一段设定的时间内,接收指定数量的写命令(配置文件中有save选项),会触发rdb持久化(bgsave命令,background save)

  3. 这时主进程会用fork()系统调用开启一个子进程(为什么用fork(),后面会讲)

  4. 子进程和父进程共享一块物理内存,将存储在内存中的数据以.rdb为后缀的二进制文件存储起来(恢复起来很快奥!)

  5. 当下次redis重启的时候,就会加载这个.rdb文件到内存啦

实践

命令介绍

  • save : 主进程阻塞进行rdb持久化,此时主进程不再接收写命令

  • bgsave :主进程fork()创建一个子进程,执行rdb持久化,此时还是可以接收写命令

基础配置

# rdb文件路径
dir /usr/local/

# rdb文件名
dbfilename dump.rdb

# 触发rdb持久化的条件
# save <time> <times> (<time1> <times1>...)
#     在time秒之内,执行写命令超过times次,执行bgsave命令
# save "" 表示关闭rdb持久化
save 3600 1 
进阶配置

# 当向磁盘写入.rdb文件时,报错(磁盘损坏),redis会通过拒绝写命令,显示告知rdb持久化失败
stop-writes-on-bgsave-error yes

# 是否开启压缩,开启压缩会消耗cpu资源,不开启压缩,会1:1持久化内存数据(追求性能关掉)
rdbcompression yes

# 开启的话,redis会在文件末尾放置CRC64校验和,可以校验.rdb文件是否损坏
# 关闭的话,校验和为0,跳过CRC校验,性能相较于校验提升10%
rdbchecksum yes

# 在加载.rdb文件时或者接收restore命令时,对ziplist和listpack等数据结构进行校验
# 选项
#     - yes 总是进行全面检查
#     - no 不进行全面检查
#     - client 对普通用户的连接,进行全面检查。而不检查主从复制传输的.rdb文件
# 本来默认client,但是其影响分片集群通过MIGRATE命令重新分片造成影响,所以设成no
sanitize-dump-payload no

# 在主从复制场景下,删除没有开启rdb和aof(第二种持久化方式)持久化的节点的.rdb文件
# 还可以通过无盘复制达到这种效果,但是对于从节点并不是一个好选择
rdb-del-sync-files no

底层原理

  • redis主进程调用fork()系统调用克隆出子进程(如果已经存在bgsave子进程的话,则不会继续本次rdb持久化)

  • 子进程指向父进程的页表(共享同一块内存)

  • 父进程将所有虚拟内存页的权限都设置成只读(read-only)

  • 当父进程执行写命令时,会触发写时复制(Write-on-Copy COW)。触发页异常中断(page-fault),随后父进程拷贝对应的物理内存页,并执行写命令

        

  • 子进程会将调用fork()系统调用之前的的内存数据全部持久化到.rdb文件中(注意:fork()之后执行的那些命令不会持久化)

AOF

简介


aof,append only file,仅向文件添加,意思就是每执行一条写命令,就向文件追加(缓存区,是否追加到磁盘得看配置appendfsync),一看就比rdb持久化得及时。

流程


  • 配置文件开启aof持久化(appendonly yes)

  • 当主进程接收到写命令,先执行命令,操作内存数据

  • 然后将命令缓存到操作系统的page cache缓存区

  • 根据配置(appendfsync)来调用fsync()系统调用,将缓存区中的数据写到aof文件中(长这鸟样)

        

  • 如果此时aof文件大小达到一定容量,则主进程会调用fork()系统调用创建一个子进程

  • 此时所有写命令,主进程会执行并且缓存到aof重写缓冲区

  • 子进程将数据库中的数据持久化到aof临时文件中

  • 子进程持久化完成之后,向主进程发出一个信号,主进程收到后调用信号处理函数

  • 将aof重写缓冲区中的命令持久化到aof临时文件中,并将临时文件改名覆盖原来的aof文件

实践

命令介绍

  • bgrewriteaof : 重写aof文件,redis可以自动调用,配置项为(auto-aof-rewrite-min-size,auto-aof-rewrite-percentage)

基础配置

# 开启aof持久化,数据恢复就不会加载.rdb文件了
appendonly yes

# aof文件前缀
# Redis7及以后会生成三个文件
# - appendonly.aof.1.base.rdb 快照文件,在aof重写时创建,数据库数据持久化到这个文件
#    ,后缀取决于配置aof-use-rdb-preamable.
# - appendonly.aof.1.incr.aof 追加文件,当后续有写命令执行,持久化到这个文件.
# - appendonly.aof.manifest 顺序文件,内容时上面两个文件加载的顺序(启动redis时).
appendfilename "appendonly.aof"

# aof文件夹路径
appenddirname "appendonlydir"
进阶配置

# page cache写入磁盘的时机(调用fsync()系统调用)
# - always 每执行一条命令就调用
# - no 交由操作系统调用(随缘...)
# - everysec 每秒调用
appendfsync everysec

# 是否开启混合持久化模式,rdb & aof,详见配置appendfilename注释
aof-use-rdb-preamble no

# 是否开启aof文件时间戳功能,会在持久化时加上时间注释,
# 在用redis恢复工具可以指定恢复哪一段时间的数据
aof-timestamp-enabled no

# 在aof持久化的过程中会出现各种各样的事故,像突然断电,或者操作系统运行时崩溃了,
# 尤其是ext4文件系统没有设置data=orderd选项,
# 就会出现aof文件末尾被截断(但是redis自己崩溃,但操作系统正常不会出现这种情况)
#     - 关闭 则在加载aof文件发现文件被截断,则会断言报错,拒绝启动redis,提醒用户修复aof文件,
#     - 开启 则会尽可能的加载aof文件(在aof文件中间被截断,则也无法正常启动)
aof-load-truncated yes

# 在aof后台重写进程在执行大量I/O操作时,redis主进程调用fsync()会被阻塞
# 开启 上述情况中,redis主进程将不会调用fsync(),也就是说在aof重写时,appendfsync短暂设置为no
#         这样可以保证响应时间相对短,但linux默认配置下,最坏会损失30s的数据
# 关闭 可以保证aof持久化减少数据丢失
no-appendfsync-on-rewrite no

# 每次重写都会记录aof文件的base-size(没有重写过,则以redis启动时的aof文件大小设为base-size),
# 如果current-size大于base-size * (1 + percentage)并且大于min-size,
# 则会自动触发bgrewriteaof命令,即,aof重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
  • 补充说明

    • 混合持久化模式

      • 开启 :在加载持久化文件时更快,rdb毕竟是二进制文件

      • 关闭 :没啥好说的,全是aof文件,稍微大一点

                        

总结

  1. rdb持久化

    1. 优点 :持久化文件小,重启恢复快,仅fork()子进程时会阻塞主进程

    2. 缺点 :每次持久化成本高(全量持久化),如果设置的间隔大,则会损失较多数据

  2. aof持久化

    1. 优点 :持久化成本低(增量持久化),持久化可靠性高

    2. 缺点 :重启恢复慢,持久化文件大(会重写),fork()子进程和调用fsync()会阻塞主进程

  3. 混合持久化(aof & rdb)

    1. 在aof持久化的基础上,重写aof文件改为rdb快照持久化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值