一些概念简介
持久化
持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
Redis持久化
- Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘,当下次Redis重启时,利用持久化文件实现数据恢复。
- 为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。
Redis持久化的方式
RDB
:将当前数据保存到硬盘AOF
:将每次执行的写命令保存到硬盘- Redis默认的持久化方式就是
RDB
Redis持久化详解
Redis持久化-RDB
简介
- RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
- 在默认情况下, Redis 将数据库快照保存在名字为
dump.rdb
的二进制文件中。 - 在 Redis 运行时, RDB 程序将当前内存中的数据库快照保存到磁盘文件中
- 在 Redis 重启动时, RDB 程序可以通过载入 RDB 文件来还原数据库的状态。
- 3和4连起来,运行方式入下图所示展示
Redis中RDB的相关配置
# RDB自动持久化规则
# 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操作
save 900 1
# 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操作
save 300 10
# 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操作
save 60 10000
# RDB持久化文件名
dbfilename dump-<port>.rdb
# 数据持久化文件存储目录
dir ./
# bgsave发生错误时是否停止写入,通常为yes
stop-writes-on-bgsave-error yes
# rdb文件是否使用压缩格式
rdbcompression yes
# 是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes
复制代码
工作方式
- Redis 调用fork(),同时拥有父进程和子进程
- 子进程将数据写入临时的RDB文件
- 写入完成后,Redis将新的RDB文件替换掉旧的RDB文件
触发机制
- 满足
save
规则,执行save命令会自动触发RDB规则,但是如果Redis数据特别多的时候,save执行命令就非常慢,还会阻塞所有客户端的请求。
- 满足
save
规则,执行bgsave命令会自动触发RDB规则。同样的,bgsave命令也会发生阻塞,但是它的阻塞发生在fork()阶段,能很快解决。
- 执行
flushall
命令的时候,也会触发RDB规则。 - 退出Redis也会触发RDB规则。
save vs bgsave
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
阻塞 | 是 | 是,但是发生在fork(),处理非常快 |
优点 | 不耗额外的内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 调用fork(),需要消耗一定的内存 |
恢复数据
只需要在客户端通过config get dir
命令来查看dump.rdb
文件所在的位置,然后将这个目录放在我们redis的启动目录,这样我们在redis启动的时候,它会自动去扫描dump.rdb文件,从而实现数据的恢复
获得dump.rdb文件的位置
数据恢复的标识
RDB优缺点
优点:
- 适合大规模数据的备份和灾难恢复
- 对数据的完整性要求不高
- 生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
缺点:
- 进程操作需要时间,如果Redis意外党纪,就会丢失最后一次快照的数据
- fork()调用进程,会消耗内存
- RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题(版本不兼容)
Redis持久化-AOF
简介
- AOF:每当 Redis 执行一个改变数据集的命令时(比如 SET),这个命令就会被追加到 AOF 文件的末尾。
- AOF默认是关闭的,如果要使用AOF,需要去配置文件打开。
- AOF默认生成的文件是
appendonly.aof
。
AOF相关配置
# AOF持久化方式是否开启,默认是no
appendonly no
# AOF持久化文件名
appendfilename appendonly.aof
# 每秒把缓冲区的数据同步到磁盘
appendfsync everysec
# 数据持久化文件存储目录
dir ./
# 是否在执行重写时不同步数据到AOF文件,默认为no
no-appendfsync-on-rewrite no
# 触发AOF文件执行重写的最小尺寸
auto-aof-rewrite-min-size 64mb
# 触发AOF文件执行重写的增长率
auto-aof-rewrite-percentage 100
复制代码
使用AOF进行持久化
- 在配置文件打开AOF,其他AOF的配置不需要修改
- 重新启动redis服务
- 查看是否生成了
appendonly.aof
文件,发现生成了~
- 这时候,我们在里面存在一些数据
- 直接去查看
appendonly.aof
的内容,发现它将我们的操作一条一条追加了上去
如果我们手动修改了
appendonly.aof
的内容,会怎么样
- 我们先断开redis连接
- 修改
appendonly.aof
内容
- 重新启动服务,会发现连接失败
这显然不是我们想要看到的,这时候我们就需要用到aof的修复工具redis-check-aof
了
修复步骤:
- 输入
redis-check-aof --fix appendonly.aof
命令进行修复
- 再次连接
- 再次查看appendonly.aof文件,发现,被我们恶意修改的数据,都被删除了~
AOF的三种策略
# appendfsync always # 每次修改都会sync 消耗性能
appendfsync everysec # 每秒执行一次 sync 可能会丢失这一秒的数据,默认开启的是这个
# appendfsync no # 不执行 sync ,这时候操作系统自己同步数据,速度最快
复制代码
AOF的优缺点
优点:
- appendfsync everysec策略:每一次修改都会同步,文件的完整性会更加好
- appendfsync everysec策略:每秒同步一次,可能会丢失一秒的数据
- appendfsync no策略:从不同步,效率最高
缺点:
- aof文件比rdb文件大,因为,aof将每个写命令都追加到appendonly.aof文件,所以文件会越来越大,文件越大,修复文件的速度也就越慢
- AOF运行效率比RDB慢
RDB VS AOF
- RDB可以在指定的时间间隔内对数据集进行持久化快照存储
- AOF持久化记录每次客户端发送给Redis服务器的写操作,服务器中重启时会重新执行命令恢复原始数据,AOF持久化的每一次记录都会追加在文件的末尾,并且Redis有重写机制的存在使得AOF的文件被控制在合理的大小
- 如果Redis只做缓存,如果说只希望数据在服务器启动的时候存在,可以不使用任何的持久化方式
- 如果两种持久化同时开启,Redis服务器会默认先找AOF持久化,因为AOF的保存数据集要比RDB要完整,这也就是Redis考虑安全的原因
如何选择
- 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 9001这条规则。
- 如果Enable AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
- 如果不Enable AOF,仅靠Master-Slave Repllcation实现高可用性也可以,能省掉一大笔lO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的 RDB文件,载入较新的那个,微博就是这种架构。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END