Redis持久化
为什么要持久化
Redis是内存数据库,宕机后数据会消失。
Redis重启后快速恢复数据,要提供持久化机制
Redis持久化是为了快速的恢复数据而不是为了存储数据
Redis有两种持久化方式:RDB和AOF
注意:Redis持久化不保证数据的完整性。
当Redis用作DB时,DB数据要完整,所以一定要有一个完整的数据源(文件、mysql)
在系统启动时,从这个完整的数据源中将数据load到Redis中
数据量较小,不易改变,比如:字典库(xml、Table)
通过info命令可以查看关于持久化的信息
# Persistence loading:0 rdb_changes_since_last_save:1 rdb_bgsave_in_progress:0 rdb_last_save_time:1589363051 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:0 aof_enabled:1 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:0 aof_current_size:58 aof_base_size:0 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 aof_delayed_fsync:0
RDB
RDB(Redis DataBase)即快照模式,是redis默认的存储方式,会将数据库的快照保存在dump.rdb这个二进制文件中。
Redis是单线程的,也就是说一个线程要同时负责多个客户端套接字的并发读写以及内存数据结构的逻辑读写。
触发快照的方式
-
自动触发策略:符合自定义配置的快照规则
在redis.conf中配置
save "" # 不使用RDB存储 不能主从 save 900 1 # 表示15分钟(900秒钟)内至少1个键被更改则进行快照。 save 300 10 # 表示5分钟(300秒)内至少10个键被更改则进行快照。 save 60 10000 # 表示1分钟内至少10000个键被更改则进行快照。
只要上述三个条件任意满足一个,服务器就会自动执行 BGSAVE
命令。
2. 手动触发策略:执行save或者bgsave命令
127.0.0.1:6379> SAVE
OK
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> LASTSAVE #用于查看 BGSAVE 命令是否执行成功。
(integer) 1611298430
上述命令BGSAVE
从后台执行数据保存操作,其可用性要优于执行 SAVE
命令。
SAVE 命令会阻塞 Redis 服务器进程,直到 dump.rdb 文件创建完毕为止,在这个过程中,服务器不能处理任何的命令请求。
BGSAVE
命令是非阻塞式的,所谓非阻塞式,指的是在该命令执行的过程中,并不影响 Redis 服务器处理客户端的其他请求。这是因为 Redis 服务器会 fork() 一个子进程来进行持久化操作(比如创建新的 dunp.rdb 文件),而父进程则继续处理客户端请求。当子进程处理完后会向父进程发送一个信号,通知它已经处理完毕。此时,父进程会用新的 dump.rdb 文件覆盖掉原来的旧文件
3. 执行flushall命令
4. 执行主从复制操作 (第一次)
RDB执行流程(原理)
-
Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof(aof文件重写命令)的子进程,如果在执行则bgsave命令直接返回。
-
父进程执行fork(调用OS的fork函数复制自己包括操作和数据)创建子进程(拥有父进程这一刻的操作和数据),这个复制过程中父进程是阻塞的, Redis不能执行来自客户端的任何命令。
-
父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令。
-
子进程生成RDB文件--根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换。 (RDB始终完整)
-
子进程发送信号给父进程表示完成,父进程更新统计信息。
RDB文件结构
1、头部5字节固定为“REDIS”字符串
2、4字节“RDB”版本号(不是Redis版本号),当前为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、校验和,就是看文件是否损坏,或者是否被修改。
RDB的优缺点
优点
RDB是二进制压缩文件,占用空间小,便于传输(传给slaver)
主进程fork子进程,可以最大化Redis性能,主进程不能太大,Redis的数据量不能太大,复制过程中主
进程阻塞
缺点
不保证数据完整性,会丢失最后一次快照以后更改的所有数据