华子目录
- 数据持久化
- `RDB`
- 什么是RDB
- 如何备份
- Fork
- 持久化流程
- `rdb`持久化过程
- 一、触发`RDB`持久化的方式
- 二、`RDB`持久化的具体过程
- 三、`RDB`持久化的优缺点
- 相关配置
- 1.db文件名
- 2.rdb文件和aof文件路径
- 3.save
- 示例
- 4.`stop-writes-on-bgsave-error`
- `stop-writes-on-bgsave-error` 的配置选项和含义
- 为什么要设置 `stop-writes-on-bgsave-error`
- 如何配置 `stop-writes-on-bgsave-error`
- 注意事项
- 5.`rdbcompression`
- `rdbcompression` 参数的作用
- 如何配置 `rdbcompression`
- 注意事项
- 6.`rdbchecksum`
- 作用
- 如何配置
- 注意事项
- rdb备份与恢复
- rdb备份
- rdb恢复
- rdb优势
- 劣势
- AOF
- 什么是`AOF`
- 持久化流程
- 使用AOF
- 开启AOF(`配置文件`)
- `appendfsync`选项
- 使用演示
- `aof`备份与恢复
- 备份
- 恢复
- 异常恢复
- rewrite压缩
- rewrite是什么
- 重写原理
- `no-appendfsync-on-rewrite:`
- 触发机制,何时重写
- `auto-aof-rewrite-percentage`
- `auto-aof-rewrite-min-size`
- 重写流程
- 优势
- 劣势
- 如何选择
- 总结
数据持久化
Redis
主要提供了2
种不同形式的持久化
方式:
rdb
(Redis database
):RDB
持久性以指定的时间间隔
执行数据集的时间点快照
aof
(Append Only File
):AOF
持久化记录服务器接收到的每个写操作
,在服务器启动时再次播放
,重建原始数据集
。命令使用与Redis
协议本身相同的格式
以仅附加
方式记录
。当日志变得太大
时,Redis
能够在后台重写日志
。
RDB
什么是RDB
- 在指定的
时间间隔
内将内存
中的数据集
快照写入磁盘
,也就是Snapshot
快照,它恢复时是将快照文件
直接读到内存
里。
如何备份
Redis
会单独创建分支(fork
)一个子进程
来进行持久化
,会先将数据
写入到 一个临时文件
中,待持久化过程
都结束后,再用这个临时文件
替换上次持久化好的文件
。 整个过程中,主进程
是不进行任何IO
操作的,这就确保了极高的性能
。如果需要进行大规模数据的恢复
,且对于数据恢复的完整性
不是非常敏感
,那RDB
方式要比AOF
方式更加的高效
。RDB的缺点
是最后一次持久化后
的数据可能丢失
。
Fork
Fork
的作用是复制
一个与当前进程
一样的进程
。新进程
的所有数据
(变量、环境变量、程序计数器
等) 数值都和原进程
一致,但它是一个全新的进程
,并作为原进程的子进程
。
- 在
Linux
程序中,fork()
会产生
一个和父进程
完全相同
的子进程
,但子进程
在此后多次会被exec
系统调用,出于效率考虑,Linux
中引入了“写时复制技术
”。- 一般情况下
父进程
和子进程
会共用同一段物理内存
,只有进程空间的某一段
的内容要发生变化
时,才会将父进程
的内容
复制一份给子进程
。
- 一般情况下
持久化流程
启动:
- 检查是否存在
子进程
正在执行AOF
或者RDB
的持久化任务
。如果有
则返回false
。 - 调用
Redis
源码中的rdbSave
方法,方法中执行fork()
产生子进程
执行RDB
操作。 - 关于
fork()
中的Copy-On-Write
(写时复制)。
rdb
持久化过程
Redis
中的RDB
(Redis Database
)持久化过程是将Redis
在某个时间点的内存数据集以快照
形式写入磁盘文件
的过程。以下是Redis
中RDB
持久化的详细
过程:
一、触发RDB
持久化的方式
Redis
中RDB
持久化可以通过以下几种方式触发:
-
手动触发:
save
命令:执行save
命令时,Redis
会阻塞当前服务器进程,直到RDB
文件创建完毕为止。因此,save
命令会严重影响Redis
服务器的性能,不推荐在生产环境中使用。bgsave
命令:bgsave
命令会创建一个子进程
来异步
执行RDB
持久化,这样Redis
服务器就可以继续处理客户端
请求,而不会阻塞
服务器进程。bgsave
是Redis RDB
持久化的主要方式。
-
自动触发:
- 根据配置文件中的
save
指令:Redis
的配置文件(redis.conf
)中可以设置save
指令,用于定义在一定时间内
发生指定数量的写操作后自动执行bgsave
。例如,save 900 1
表示在900秒
内如果有至少1个key
被改变,则触发RDB
持久化。 - 执行
flushall
、flushdb
命令:这两个命令分别用于清空Redis
数据库中的所有key
或当前选中数据库的key
,执行后
会自动
触发RDB
持久化,但
生成的RDB
文件为空
。 - 执行
shutdown
命令且没有开启AOF
持久化:在关闭Redis
服务器时,如果没有开启AOF
持久化,则会自动触发RDB
持久化。
- 根据配置文件中的
二、RDB
持久化的具体过程
-
创建子进程:当
bgsave
命令被执行
或满足自动触发
的条件时,Redis
会fork
一个子进程来进行RDB
持久化操作。 -
内存数据快照:
子进程
会读取内存
中的数据,并将其写入
到一个临时RDB
文件中。这个过程中,主进程
可以继续处理客户端
请求,而子进程
则负责
将数据写入
磁盘。 -
写入数据:
子进程
将内存
中的数据以二进制
格式写入到临时RDB
文件中。这个过程通常很快,因为Redis
采用了高效的内存管理和数据结构。 -
替换旧文件:当
临时RDB文件
写入完成后,子进程
会通知主进程
进行文件替换
。主进程
会使用原子操作
将临时RDB
文件替换
为原来的RDB
文件,确保在替换
过程中数据的完整性
和一致性
。(是怎样替换掉临时文件的?
) -
完成持久化:当
文件替换
完成后,RDB持久化
过程结束。此时,Redis
的内存数据
已经成功保存
到磁盘
上,即使Redis
服务器发生宕机
,也可以通过RDB文件
恢复数据。
三、RDB
持久化的优缺点
优点:
RDB文件
是一个紧凑的二进制
文件,存储效率较高。RDB
恢复数据的速度比AOF
快很多。RDB
内部存储的是Redis
在某个时间点的数据快照
,非常适合用于数据备份、全量复制等场景。
缺点:
RDB
文件生成存在时间间隔,如果Redis
服务器在两次RDB持久化
之间发生宕机,可能会丢失一定的数据。RDB文件采用二进制
格式,存在版本兼容性问题。不同版本的Redis
可能无法直接读取或写入由其他版本生成的RDB
文件。fork
创建子进程
时,会存在一定的内存消耗
和性能影响
。在大规模数据场景下,这种影响可能更加明显。
相关配置
- 当关闭
redis
服务时,会生成.rdb
文件 - 当开启
redis
服务时,会生成aof
文件 - 当重启
redis
服务时,都会生成.rdb
和aof
文件 - 退出
redis
数据库也会生成.rdb
文件
1.db文件名
快照持久化是Redis
中默认开启的持久化
方案,根据redis.conf
中的配置,快照
将被写入dbfilename
指定的文件中(默认是dump.rdb
文件)。
[root@server ~]# cat /etc/redis.conf | grep dbfilename
dbfilename dump.rdb
2.rdb文件和aof文件路径
根据redis.conf
中的配置,快照
将保存在dir
选项指定的路径上
,我们可以修改为指定目录
[root@server ~]# cat /etc/redis.conf | grep dir
dir "/usr/local/redis/data"
- 注意:由于此路径是一个
相对路径
,它会根据执行命令所在目录来生成dump.rdb
文件,因此建议改为一个固定位置
,如:/usr/local/redis/data
(目录必须存在
)
3.save
- 格式
save 秒 写操作次数
save 900 1 # 在900s内如果有1条数据被写入,则产生一次快照。
save 300 10 # 在300s内如果有10条数据被写入,则产生一次快照
save 60 10000 # 在60s内如果有10000条数据被写入,则产生一次快照
示例
我们把持久化的策略修改为 save 30 5
,表示 30 秒内写入 5 条数据
就产生一次快照
,也就是生成rdb
文件。
- 修改好的保存并重启
redis
服务,然后打开会话,执行如下命令:
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> set k4 v4
OK
127.0.0.1:6379> set k5 v5
OK
127.0.0.1:6379> set k6 v6
OK
然后查看 dump.rdb
文件的大小,就可以发现文件快照已经产生了。
[root@server ~]# cd /usr/local/redis/data/
[root@server data]# ls
dump.rdb
问题:是否这 6
条数据都持久化了?
- 答:只持久化了
前 5 条
数据,最后 1 条
数据没有持久化。
注意:Redis
中持久化命令有两种:
save
:手动保存,只管保存不管其它,所有操作全部阻塞
。不建议使用。bgsave
:自动保存,Redis
会在后台异步
进行快照操作, 快照同时还可以响应客户端
请求。
4.stop-writes-on-bgsave-error
stop-writes-on-bgsave-error
是 Redis
配置文件中的一个参数,用于控制在后台保存(bgsave
)过程中发生错误时 Redis
的行为。具体来说,这个参数决定了当 Redis
无法将内存中的数据写入磁盘(即 bgsave
操作失败)时,是否应该停止接受新的写操作。
stop-writes-on-bgsave-error
的配置选项和含义
- yes(默认值):当
bgsave
操作失败时,Redis
将停止接受新的写操作。这是为了提醒管理员注意,可能由于磁盘空间不足、权限问题或其他I/O
错误导致的数据持久化失败。 - no:即使
bgsave
操作失败,Redis
也会继续接受新的写操作。这可能会导致数据丢失的风险增加,因为未成功持久化的数据在Redis
重启后将无法恢复。
为什么要设置 stop-writes-on-bgsave-error
- 数据安全性:通过停止写操作,
stop-writes-on-bgsave-error
参数可以确保在数据持久化失败时,管理员能够及时发现并处理问题,从而避免数据丢失。 - 系统稳定性:在磁盘空间不足或存在其他
I/O
错误的情况下,继续接受写操作可能会进一步加剧系统资源的紧张状况,甚至导致Redis
服务崩溃。
如何配置 stop-writes-on-bgsave-error
stop-writes-on-bgsave-error
参数可以在 Redis
的配置文件中(通常是 redis.conf
)进行设置。你可以通过编辑配置文件来更改此参数的值,然后重启 Redis
服务以应用更改。
例如,要将 stop-writes-on-bgsave-error
设置为 no
,你可以在 redis.conf
文件中找到该参数并将其值更改为 no
:
stop-writes-on-bgsave-error no
然后,保存配置文件并重启 Redis
服务。
注意事项
- 在更改
stop-writes-on-bgsave-error
参数之前,请确保你了解更改该参数可能带来的后果,并根据你的实际需求和系统环境做出决策。 - 如果你选择将
stop-writes-on-bgsave-error
设置为no
,请确保你的系统有足够的监控和告警机制,以便在数据持久化失败时能够及时发现并处理。
综上所述,stop-writes-on-bgsave-error
是一个重要的 Redis
配置参数,它关系到数据的安全性和系统的稳定性。在配置和使用 Redis
时,请务必注意该参数的设置。
5.rdbcompression
rdbcompression
是 Redis
配置文件中用于控制是否对 RDB
文件进行压缩
的参数。在 Redis
中,RDB
(Redis Database
)持久化是一种将内存中的数据以快照的形式保存到磁盘上的方式,以确保数据的安全性和持久性。
rdbcompression
参数的作用
- 当
rdbcompression
设置为yes
时,Redis
会在生成RDB
文件时自动对其进行压缩。这有助于减小RDB
文件的大小,节省存储空间,但可能会增加CPU
的负担,因为压缩过程需要消耗计算资源。 - 当
rdbcompression
设置为no
时,Redis
将不会压缩RDB
文件。这可能会导致RDB
文件占用更多的磁盘空间,但可以减少CPU
的负担,提高Redis
的性能。
如何配置 rdbcompression
要在 Redis 中配置 rdbcompression
,需要编辑 Redis
的配置文件(通常是 redis.conf
),并找到 rdbcompression
这一行。然后,将其值设置为 yes
或 no
,以启用或禁用 RDB
文件的压缩。
例如:
rdbcompression yes
或者
rdbcompression no
注意事项
- 在修改
Redis
配置文件后,需要重启Redis
服务以使配置生效。 - 压缩
RDB
文件虽然可以节省存储空间,但可能会对Redis
的性能产生一定影响。因此,在配置rdbcompression
时,需要根据实际情况进行权衡。 Redis
默认使用LZF
算法对RDB
文件进行压缩,但也可以通过安装第三方模块或修改Redis
源码来支持其他压缩算法。
6.rdbchecksum
rdbchecksum
是 Redis
配置文件中用于控制是否对 RDB
文件进行 CRC64
校验的参数。以下是关于 rdbchecksum
的详细解释:
作用
- 当
rdbchecksum
设置为yes
时,Redis
在存储RDB
快照后,会使用CRC64
算法对文件内容进行校验。这样做可以确保RDB
文件的完整性和正确性,但会增加大约10%
的性能消耗,因为校验过程需要额外的计算资源。 - 当
rdbchecksum
设置为no
时,Redis
将不会对RDB
文件进行CRC64
校验。这可以提高Redis
的性能,但可能会降低数据的安全性,因为如果RDB
文件在存储或传输过程中被损坏,Redis
将无法检测到这一点。
如何配置
要在 Redis
中配置 rdbchecksum
,需要编辑 Redis
的配置文件(通常是 redis.conf
),并找到 rdbchecksum
这一行。然后,将其值设置为 yes
或 no
,以启用或禁用 RDB
文件的 CRC64
校验。
例如:
rdbchecksum yes
或者
rdbchecksum no
注意事项
- 在修改
Redis
配置文件后,需要重启Redis
服务以使配置生效。 - 考虑到数据的安全性和完整性,通常建议将
rdbchecksum
设置为yes
,尽管这可能会带来一定的性能开销。 - 在高并发或性能要求极高的场景下,如果确信
RDB
文件在存储和传输过程中不会受到损坏,也可以考虑将rdbchecksum
设置为no
以提高性能。
rdb备份与恢复
rdb备份
首先执行如下命令来清空数据:
127.0.0.1:6379> flushdb
删除之前的dump.rdb
文件
[root@server data]# rm -rfv dump.rdb
已删除 'dump.rdb'
然后再重新添加如下数据:
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> set k4 v4
OK
127.0.0.1:6379> set k5 v5
OK
127.0.0.1:6379> set k6 v6
OK
接着执行如下命令来备份 dump.rdb
[root@server data]# cp dump.rdb dump.rdb.back
最后把 Redis
服务关闭
[root@server ~]# systemctl stop redis
然后把 dump.rdb
文件删除
[root@server data]# rm -rfv dump.rdb
已删除 'dump.rdb'
rdb恢复
先重启 Redis 服务
[root@server ~]# systemctl start redis
查看(发现无数据)
[root@server ~]# redis-cli
127.0.0.1:6379> keys *
(empty array)
停止服务
[root@server ~]# systemctl stop redis
删除dump.rdb
(因为停止服务时会备份dump.rdb
)
[root@server data]# rm -rfv dump.rdb
已删除 'dump.rdb'
将之前备份的文件进行还原
[root@server data]# mv dump.rdb.back dump.rdb
[root@server data]# ls
dump.rdb
再重启redis服务
[root@server ~]# systemctl start redis
查看
[root@server ~]# redis-cli
127.0.0.1:6379> keys *
1) "k4"
2) "k1"
3) "k2"
4) "k5"
5) "k3"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k5
"v5"
127.0.0.1:6379> get k6 #证明K6没有备份
(nil)
127.0.0.1:6379>
rdb优势
RDB
方式适合大规模的数据恢复,并且对数据完整性和一致性要求不高
更适合使用。
- 节省磁盘空间
- 恢复速度快
劣势
Fork
的时候,内存
中的数据
被克隆
了一份,大致2
倍的膨胀性需要考虑- 虽然
Redis
在fork
时使用了写时拷贝
技术,但是如果数据庞大时还是比较消耗性能
。 - 在备份周期在一定间隔时间做一次备份,所以如果
Redis
意外down
掉的话,就会丢失
最后一次快照
后的所有修改
。
AOF
什么是AOF
- 以
日志
的形式来记录每个写
操作(增量保存
),将Redis
执行过的所有写指令
记录下来(读操作不记录
), 只追加文件
但不可以改写文件
,Redis
启动之初
会读取该文件
重新构建数据。简单说,Redis
重启时会根据日志文件
的内容将写指令
从前到后
执行一次以完成数据的恢复工作
。 - 在
Redis
的默认配置中,AOF
(Append Only File
)持久化机制是没有开启
的,要想使用AOF
持久化需要先开启此功能。AOF
持久化会将被执行的写命令写到AOF文件末尾
,以此来记录数据发生的变化,因此只要Redis
从头到尾执行一次AOF
文件所包含的所有写命令
,就可以恢复AOF
文件的记录的数据集。
持久化流程
- 客户端的请求
写
命令会被append
追加到AOF缓冲区
内。 AOF缓冲区
根据AOF
持久化策略 [always
,everysec
,no
] 将操作sync
同步到磁盘的AOF文件
中。AOF文件
大小超过重写策略或手动重写时,会对AOF
文件rewrite
重写,压缩AOF文件容量
。Redis
服务重启时,会重新load
加载AOF
文件中的写操作
达到数据恢复
的目的。
使用AOF
- 当关闭
redis
服务时,会生成.rdb
文件 - 当开启
redis
服务时,会生成aof
文件 - 当重启
redis
服务时,都会生成.rdb
和aof
文件 - 退出
redis
数据库也会生成.rdb
文件
开启AOF(配置文件
)
修改 redis.conf
配置文件:
- 通过修改
redis.conf
配置中appendonly yes
来开启AOF
持久化
[root@server ~]# cat /etc/redis.conf | grep appendonly
appendonly yes
- 通过
appendfilename
指定日志文件名字(默认为appendonly.aof
)
[root@server ~]# cat /etc/redis.conf | grep appendfilename
appendfilename "appendonly.aof"
AOF文件
存储的目录
[root@server ~]# cat /etc/redis.conf | grep appenddirname
appenddirname "appendonlydir"
- 通过
appendfsync
指定日志记录频率
[root@server ~]# cat /etc/redis.conf | grep appendfsync
appendfsync everysec
appendfsync
选项
选项 | 同步频率 |
---|---|
always | 每个redis 写命令都要同步写入硬盘 ,严重降低redis 速度 |
everysec | 每秒 执行一次同步显式的 将多个写命令 同步到磁盘 |
no | 由操作系统 决定何时同步 |
always
选项,每个redis
写命令都会被写入AOF文件
中,好处是当发生系统崩溃时数据丢失减至最少,缺点是这种策略会产生大量
的I/O
操作,会严重降低服务器的性能
。everysec
选项,以每秒一次的频率
对AOF文件
进行同步,可以保证系统崩溃时只会丢失一秒左右
的数据,并且Redis
每秒执行一次
同步对服务器几乎没有任何影响
。no
选项,完全由操作系统
决定什么时候同步AOF日志文件
,这个选项不能给服务器性能
带来多大的提升,反而会增加系统崩溃时数据丢失的数量
。
使用演示
- 先开启
AOF功能
[root@server ~]# vim /etc/redis.conf
appendonly yes[root@server ~]# systemctl restart redis
- 配置好后,停止
Redis
服务,然后再重新开启Redis
服务后,就可以在RDB
生成的同目录下(/usr/local/redis/data
)会生成一个appenddirname
指定的目录
。
[root@server ~]# cd /usr/local/redis/data/
[root@server data]# ls
appendonlydir dump.rdb[root@server data]# cd appendonlydir/
[root@server appendonlydir]# ls
appendonly.aof.1.base.rdb appendonly.aof.1.incr.aof appendonly.aof.manifest
- 使用客户端连接
Redis
服务,然后执行:
127.0.0.1:6379> keys *
(empty array)
- 发现没有任何数据。这说明:如果
RDB 和 AOF
文件同时存在,Redis
默认使用的是AOF文件
。
aof
备份与恢复
备份
AOF
的备份机制和性能虽然和RDB
不同,但是备份和恢复的操作同RDB
一样:都是拷贝备份
文件,需要恢复时再拷贝到Redis
工作目录下,启动系统即加载
。
- 首先添加数据:
127.0.0.1:6379> set k11 v11
OK
127.0.0.1:6379> set k12 v12
OK
127.0.0.1:6379> set k13 v13
OK
127.0.0.1:6379> set k14 v14
OK
127.0.0.1:6379> set k15 v15
OK
- 然后停止 Redis 服务,并重命名文件
[root@server ~]# redis-cli shutdown
[root@server ~]# cd /usr/local/redis/data
[root@server data]# mv appendonly.aof appendonly.aof.back
恢复
- 重新把
aof
文件改名回来,再重启Redis
服务,连接客户端:
127.0.0.1:6379> keys *
1) "k11"
2) "k12"
3) "k13"
4) "k14"
5) "k15"
- 发现确实可在恢复。
异常恢复
- 如遇到
AOF
文件被损坏,可以通过/usr/local/bin/redis-check-aof --fix .aof文件
进行恢复。 - 首先我们人为的在
appendonly.aof
中任意添加一点内容,如:
vim appendonly.aof# 在文件最后添加
redis-aof
- 保存退出后关闭
Redis
服务后再重启Redis
服务,并用客户端进行连接。这时会发现连接出错:
[root@server ~]# redis-cli
Could not connect to Redis at 127.0.0.1:6379:Connection refused.
- 这时我们需要对
appendonly.aof
文件进行修复:
[root@server ~]# redis-check-aof --fix /usr/local/redis/data/appendonly.aof
- 在提示中输入
y
即可。 - 修复后再次重启
Redis
服务,并连接客户端就可以了。 - 但是这个
修复无法
做到百分百修复
!会丢弃一小部分
rewrite压缩
rewrite是什么
AOF
采用文件追加
方式,文件会越来越大
为避免出现此种情况,新增了重写
机制, 当AOF文件
的大小超过所设定的阈值
时,Redis
就会启动AOF文件
的内容压缩
, 只保留
可以恢复数据的最小指令集
。可以使用命令bgrewriteaof
重写原理
AOF文件
持续增长而过大
时,会fork
出一条新进程
来将文件重写
(也是先写临时文件最后再 rename),redis 4.0
版本后的重写,就是把rdb
的快照,以二级制
的形式附在新的aof
头部,作为已有的历史数据,替换掉原来的流水账操作。
no-appendfsync-on-rewrite:
- 如果
no-appendfsync-on-rewrite=yes
,表示不写入aof
文件只写入缓存
,用户请求不会阻塞
,但是在这段时间如果宕机会丢失
这段时间的缓存数据。 这样做可以降低数据安全性,提高性能。 - 如果
no-appendfsync-on-rewrite=no
, 还是会把数据往磁盘里刷
,但是遇到重写
操作,可能会发生阻塞
。这样做可以数据安全,但是性能降低。
触发机制,何时重写
Redis
会记录上次重写时的AOF
大小,默认配置是当AOF
文件大小是上次rewrite
后大小的一倍且文件大于64M
时触发- 重写虽然可以节约
大量磁盘空间
,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis
要满足一定条件才会进行重写。
auto-aof-rewrite-percentage
auto-aof-rewrite-percentage
:设置重写的基准值
,文件达到100%
时开始重写
(文件是原来重写后文件的2倍时触发
)
auto-aof-rewrite-min-size
auto-aof-rewrite-min-size
:设置重写
的基准值
,最小文件64MB
。达到这个值开始重写
。
例如:文件达到70MB
开始重写,降到50MB
,下次什么时候开始重写?100MB
- 系统
载入时
或者上次重写完毕时
,Redis
会记录此时AOF
大小,设为base_size
,如果Redis
的AOF
当前大小>= base_size +base_size*100%
(默认)且当前大小>=64mb
(默认)的情况下,Redis
会对AOF
进行重写。
重写流程
- bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
- 主进程fork出子进程执行重写操作,保证主进程不会阻塞。
- 子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
- 子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
- 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。
优势
- 备份机制更稳健,丢失数据概率更低。
可读的日志文本
,通过操作AOF
稳健,可以处理误操作。
劣势
- 比起
RDB
占用更多的磁盘空间
。 - 恢复备份
速度要慢
。 - 每次读写都同步的话,有一定的
性能压力
。 - 存在个别
Bug
,造成恢复不能。
如何选择
RDB
持久化方式能够在指定的时间间隔能对你的数据进行快照存储
AOF
持久化方式记录每次对服务器写
的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF
命令以redis
协议追加保存每次写的操作到文件末尾.Redis
还能对AOF
文件进行后台重写,使得AOF
文件的体积不至于过大- 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
- 同时开启两种持久化方式
- 在这种情况下,当
redis
重启的时候会优先载入AOF
文件来恢复原始的数据, 因为在通常情况下AOF
文件保存的数据集要比RDB
文件保存的数据集要完整. RDB
的数据不实时,同时使用两者时服务器重启也只会找AOF
文件。那要不要只使用AOF
呢?- 建议
不要
,因为RDB
更适合用于备份数据库
(AOF在不断变化不好备份
), 快速重启,而且不会有AOF
可能潜在的bug
,留着作为一个万一的手段。
- 建议
总结
- RDB 持久化方式能够在指定的时间间隔内对你的数据进行快照存储
- AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis 协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
- 只做缓存,如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化
- 同时开启两种持久化方式
- 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
- RDB 的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的Bug,留着作为一个万一的手段。
- 性能建议
- 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留 save 900 1 这条规则。
- 如果Enable AOF ,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
- 如果不Enable AOF ,仅靠 Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB文件,载入较新的那个,微博就是这种架构。