Redis - 持久化

2022-02-28  本文已影响0人  Zeppelin421

Redis是内存数据库,宕机后数据会消失。
Redis重启后快速恢复数据,需要提供持久化机制

RDB

RDB(Redis DataBase)是Redis默认的存储方式,RDB是通过快照(snapshotting)完成的

触发方式

配置参数

# redis.conf
save <seconds> <change>

save "" # 不使用RDB存储

save 900 1     # 表示15分钟内至少1个key被更改则进行快照
save 300 10   # 表示5分钟内至少10个键值被更改则进行快照
save 60 1000 # 表示1分钟内至少1000个键值被更改则进行快照

TIPS:漏斗设计,提高性能

原理


文件结构
"REDIS" RDB_VERSION AUX_FIELD_KEY_VALUE_PAIRS DB_NUM DB_DICT_SIZE EXPIRE_DICT_SIZE KEY_VALUE_PAIRS EOF CHECK_SUM

1、头部5字节固定位“REDIS”
2、4字节“RDB”版本号,当前为9,填充后0009
3、辅助字段,以key-value的形式

字段名 字段值 字段名 字段值
redis-ver 5.0.5 aof-preamble 是否开启AOF
redis-bits 64/32 repl-stream-db 主从复制
ctime 当前时间戳 repl-id 主从复制
used-mem 使用内存 repl-offset 主从复制

4、存储数据库号码
5、字典大小
6、过期key
7、主要数据,以key-value形式存储
8、结束标识
9、校验和,就是看文件是否损坏或者是否被修改

优缺点

AOF

AOF(append only file)是Redis的另一种持久化方式。Redis默认情况下是不开启的。
开启AOF之后,Redis将所有对数据库进行过写入的命令(及其参数)(RESP)记录到AOF,以此达到记录数据库状态的目的。
当Redis重启后只要按照顺序回放这些命令就会恢复到原始状态
AOF会记录过程,RDB只管结果

配置

appendonly yes # 开启

# AOF文件的保存位置,和RDB文件的位置相同
dir ./

# 默认的文件名是appendonly.aof
appendfilename appendonly.aof

原理

AOP文件中存储的是Redis的命令,同步命令到AOF文件的整个过程可以分为三个阶段:

保存模式

// redis.conf
# appendfsync always
appendfsync everysec
# appendfsync no

TIPS:WRITE 永远阻塞主进程,SAVE 只有在 everysec 模式下才不阻塞主进程

AOF重写

AOF记录数据的变化过程,执行命令越来越多,AOF记录越来越大,此时需要重写瘦身
Redis会在AOF体积变得过大时自动在后台(fork子进程)对AOF进行重写。重写后新的AOF文件包含了恢复当前数据集所需的最小命令集合。

set s1 11
set s1 22
set s1 33
优化后:
set s1 33

lpush list1 1 2 3
lpush list1 4 5 6
优化后:
lpush list1 1 2 3 4 5 6

Redis不希望AOF重写造成服务器无法处理请求,所以AOF重写程序在后台子进程中执行,这样的好处:

  • 子进程进行AOF重写期间,主进程可以继续处理命令请求
  • 子进程带有主进程的数据副本,使用子进程而不是线程,可以在避免锁的情况下,保证数据的安全性

同时子进程也引发新的问题:

子进程在进行AOF重写期间,主进程还需要继续处理命令,而新的命令可能对现有的数据进行修改,会导致当前数据和重写后的AOF文件中的数据不一致

解决方案:

Redis增加了一个AOF重写缓存,这个缓存在fork子进程之后开始启用,Redis主进程在接到新的命令之后,除了将这个写命令的协议内容追加到现有的AOF文件之外,还会追加到这个缓存中。当子进程完成AOF重写之后,它会向父进程发送一个完成信号,父进程在收到完成信号后,调用一个信号处理函数,并完成以下工作:
1、将AOF重写缓存中的内容全部写入到AOF文件中
2、对新的AOF文件进行改名,覆盖原有AOF文件


触发方式

# redis.conf
# 限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
auto-aof-rewrite-min-size 64mb
# 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写,如果之前没有重写过,以启动时aof文件大小为准
auto-aof-rewrite-percentage 100

或者

127.0.0.1:6379> bgrewriteaof

混合持久化

Redis4.0开始支持 rdb 和 aof 的混合持久化。如果把混合持久化打开,aof rewrite 的时候就直接把 rdb 的内容写到 aof 文件开头
RDB的头 + AOF的身体 ------> appendonly.aof

# redis.conf
# 开启混合持久化
aof-use-rdb-preamble yes

AOF文件载入

AOF文件里面包含了重建数据库状态所需要的所有写入命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态

  1. 创建一个不带网络连接的伪客户端(fake client)
  2. 从AOF文件中分析并读取一条写命令
  3. 使用伪客户端执行被读出的写命令
  4. 一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被处理完毕为止

对比

上一篇 下一篇

猜你喜欢

热点阅读