前言
本文主要记录 redis 的两种数据磁盘固化方式。
涉及到相关参数,简单的命令操作等。
rdb
通过save或者bgsave存储某一时刻redis数据。rdb持久化是默认方式。
特点:
- 小幅度丢失数据(取决于save或者bgsave命令的执行周期)。
- save命令会阻塞其它客户端访问,基本不会用。
- bgsave会fork一个子进程来处理,子进程不会阻塞,不过会占用额外的内存。✨fork子进程这个操作会阻塞,一般这个操作很快。
- 恢复速度快,因为它就是redis内存数据的快照,只需要将rdb文件直接加到内存里。
# 压缩rdb文件
rdbcompression yes
# rdb 文件名称
dbfilename redis-6379.rdb
# rdb文件保存目录
dir /redis/data/
- 自动执行策略 (满足下列规则,就执行bgsave)
# 900s内至少达到一条写命令
save 900 1
# 300s内至少达至10条写命令
save 300 10
# 60s内至少达到10000条写命令
save 60 10000
- 人工执行策略 (每10分钟计划任务调用一次bgsave)
*/10 * * * * root /export/redis/bin/redis-cli -h 127.0.0.1 bgsave >> /export/redis/bgsave.log 2>&1
bgsave 因需要fork子进程,所以需要额外预留空闲的物理内存,在overcommit_memory=1开启的情况下,预留内存大小 > 周期变化数据大小
aof
记录的是redis每一次的写入操作记录
特点:
- 恢复速度慢,因为aof记录的不是内存数据快照,而是执行过的命令,恢复的时候需要从新执行。
- 丢失数据小。默认是1秒同步一次执行命令到aof文件内。
# 开启aof机制
appendonly yes
# aof文件名
appendfilename "appendonly.aof"
# 写入策略
## always 表示每个写操作在写入aof_buffer后,都立即执行fsync同步到磁盘。
## everysec 表示每个写操作在写入aof_buffer后,每秒执行一次fsync同步到磁盘。这是默认值
## no 表示每个写操作在写入aof_buffer后,由操作系统自身策略执行一次fsync同步到磁盘。(一般默认操作系统是30秒)。
appendfsync everysec
# 重写(压缩)AOF文件的时候不立即执行fsync
## no 意思就是压缩整合aof文件后立即调用fsync。
## yes 意思就是重写aof文件后,将其放置缓冲区。缓解io压力,但可能会因为down机丢数据。
no-appendfsync-on-rewrite yes
# 保存目录
dir /redis/data/
- 人工计划任务重写(压缩)AOF文件
*/10 * * * * root /export/redis/bin/redis-cli -h 127.0.0.1 bgrewriteaof >> /export/redis/bgrewriteaof.log 2>&1
- aof 因服务器挂掉损坏可以修复
cp aof aof.bak
redis-check-aof -fix file.aof
AOF重写
AOF重写意思:将AOF文件中冗余的命令删除,例如多个set key1指令,只需要保留最后一个set key1指令即可。
AOF重写原理:AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制
- Redis 执行 fork() ,现在同时拥有父进程和子进程。
- 子进程开始将 AOF 文件的内容写入到临时文件。
- 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
- 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
- 搞定!现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
✨AOF重写和bgsave不会同时进行。如果bgsave的过程中,发起aof重写,则这个操作是异步。redis会立即返回OK,并在bgsave执行完后执行。
💥 rdb的save操作和aof的文件重写,都会消耗磁盘性能。
结论
官方建议是两者都开启,具体根据业务情况确定是否需要,但是不管是哪一种,都可以在人工计划任务之后,复刻一份备份文件到云端对象存储中。