一、背景:
持久化,就是将数据存入到磁盘中去的过程。虽然redis是基于内存运行的服务,但是也需要做持久化操作的。
二、redis服务等持久化机制流程:
Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。
Redis提供了RDB和AOF两种持久化机制,它持久化文件加载流程如下:
三、RDB持久化:
RDB,就是把内存数据以快照的形式保存到磁盘上。
问:什么是快照?
答:可以这样理解,给当前时刻的数据,拍一张照片,然后保存下来。
RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据。
(1)、RDB触发机制:
RDB触发机制主要有以下几种:
(2)、RDB 的优点:
• 适合大规模的数据恢复场景,如备份,全量复制等
(3)、RDB缺点:
• 没办法做到实时持久化/秒级持久化;
• 新老版本存在RDB格式兼容问题。
(4)、RDB的参数配置解析:
save 900 1:900秒之内,对数据库至少修改了1次。
save 300 10:300秒之内,对数据库至少修改了10次。
save 60 10000:60秒之内,对数据库至少修改了10000次。
# 默认的设置为:
save 900 1
save 300 10
save 60 10000
# 导出rdb数据库文件压缩字符串和对象,默认是yes,但会浪费CPU但是节省空间
rdbcompression yes
# 导入时是否检查
rdbchecksum yes
# 持久化文件名称
dbfilename dump.rdb
# 持久化文件存储路径
dir /var/lib/redis
# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes
(5)、bgsave工作流程:
fork系统调用会产生一个子进程,它与父进程可以共享内存地址,所以当产生fork调动那一时刻,父子进程就有着完全相同的内容。
1、刚调用fork函数时,父子进程都映射了同一块物理地址
2、此时如果在子进程bgsave过程中,数据A发生写操作。
看出变化了没,对数据A的写操作并不会影响子进程,而父进程也没有直接对数据A所在的物理地址进行写入,而是重新复制了一份,然后在新复制的数据操作,这就是copy-on-write。
四、AOF持久化:
AOF(append only file) 持久化,采用日志的形式来记录每个写操作,追加到文件中,重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。默认是不开启的。
AOF的工作流程如下:
(1)、如何开启AOF持久化:
#修改配置文件:
vim /etc/redis/redis.conf
appendonly yes # 把 no 改为 yes#确定存储文件名是否正确
appendfilename "appendonly.aof"#重启服务:
sudo /etc/init.d/redis-server restart
(2)、AOF的优点:
• 数据的一致性和完整性更高
(3)、AOF的缺点:
• AOF记录的内容越多,文件越大,数据恢复变慢。
(4)、AOF数据恢复:
AOF文件包含重建Redis数据所需的所有写入命令,因此只要重新读入并执行保存在AOF文件中的写入命令,Redis就可以恢复Redis关闭前的状态。伪客户端是指 Redis命令只能在客户端的上下文中执行,用于加载AOF文件的命令直接来自AOF文件,而不是网络连接。因此,服务器使用没有网络连接的伪客户端来执行保存在AOF文件中的命令。伪客户端执行命令的效果与具有网络连接的客户端的效果完全相同。
(5)、AOF三种写回硬盘策略:
Redis 3 种写回硬盘的策略,说的是在 redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填。
Redis将在结束每个事件之前调用 flushAppendOnlyFile() 函数,以确定是否需要将AOF缓存中的内容写入并同步到AOF文件。flushAppendOnlyFile() 函数的行为由redis.conf 配置中appendfsync选项的值决定,有三个可选值:always、everysec和no。
Always(同步写回):
在执行每个写操作命令后,AOF日志数据将同步写回硬盘;
Everysec(每秒写回):
在执行每个写操作命令后,将命令写入AOF文件的内核缓冲区,然后每秒将缓冲区的内容写回硬盘;
No(操作系统控制的回写)
意味着回写硬盘的时间不受Redis控制,而是转移到由操作系统所控制的回写入时间。也就是说,在执行每个写操作命令之后,该命令首先被写入AOF文件的内核缓冲区,然后操作系统决定何时将缓冲区内容写回硬盘。
这三种方法都有缺点:
Always(同步写回),如果每次执行后命令都同步到瓷盘中,这会影响主线程的性能;
Everysec(每秒回写)使用每秒回写一次的频率,以避免同步回写的性能开销。虽然它减少了对系统性能的影响,但如果发生中断,在最后一秒没有中断的命令操作仍将丢失;
No(操作系统控制写回)。保存到磁盘的操作由操作系统控制。只要AOF中没有写回命令,一旦服务器停机,数据就会丢失;
五、Redis4.0的混合持久化模式
Redis 4.0的新特性是混合持久化模式,混合持久化模式同时使用RDB快照和AOF日志的混合持久模式,将RDB文件内容和增量AOF文件内容存储在同一个文件(相同的AOF格式文件)中,可以通过配置参数 aof-use-rdb-preamble 来启用混合持久性模式,config get aof-use-rdb-preamble命令进行查看。
由于RDB快照数据和AOF日志数据存储在同一个文件中,因此AOF格式文件不再只存储全部AOF日志,而是第一部分存储RDB快照,第二部分存储从RDB快照持久化开始到持久化结束的增量AOF日志。因此,RDB数据通常占大多数,AOF日志只是增量日志的一小部分
在混合持久策略下,当重新启动下一个Redis实例时,首先加载RDB快照的内容,然后重放增量AOF日志。这可以取代以前的RDB完全导入或AOF完全重放。