Redis持久化
Posted 峰峰仔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis持久化相关的知识,希望对你有一定的参考价值。
Redis持久化
- RDB持久化(以时间间隔做数据集的快照)
- AOF持久化(记录服务接收到的每个写操作,当服务启动的时候,会再次执行这些写操作,是为了构造原来的数据集。当AOF文件变得很大时,Redis会以后端进程重写log)
- 你也可以禁止持久化,如果你希望你的数据仅仅服务运行的时候存在
- 你也可以在同一个实例中结合AOF和RDB,在这种情况下,当Redis重启的时候,AOF文件主要用来构造原来的数据集,因为AOF保证数据的完整性
RDB和AOF的对比
RDB的优点:
- RDB是一个数据集的快照。RDB非常适合备份。例如,你想每个小时备份RDB文件。在这种情况下,当灾难发生时,你可以恢复数据集的不同版本
- RDB非常适合灾难恢复
- RDB最大化Redis性能,当需要持久化的时候,是父进程启动一个子进程,剩下的事情由子进程来说。
- RDB对比AOF来说,伴随着大数据来说,能更快启动
RDB缺点:
- 当Redis停止工作的时候,为了最小化数据的丢失,RDB并不是很好。通常你会设置每五分钟创建快照,当Redis非正常关闭的时候,这样你最多丢失五分钟的数据。
- RDB为了持久化,需要fork(),但是如果数据集比较大的话,Fork()是消耗时间的。会导致Redis大概几百毫秒不能接收客户端的请求
AOF优点:
- 使用AOF,Redis会更耐用,你可以选择不同的fsync策略:no fsync, fsync every second, fsync at every query。默认的策略是fsync every second,写性能也非常好,并且你最多丢失一秒的写数据。
- 有可能AOF文件中包含写一半的命令,会导致Redis启动不起来,你可以使用redis-check-aof工具来解决这个问题
- 当AOF文件变大的时候,Redis会自动重写AOF文件。并且重写也是非常安全的
- AOF文件以一种容易理解好解析的格式的存储所有的操作。你可以导出AOF文件
AOF缺点:
- 相同数据集来说,AOF比RDB更大
- 如果选择精确的fsync策略,AOF比RDB更慢。通常设置为fsync every second的策略有很高的性能。如果禁止fsync,在高负载下,和RDB一样的快
- 有一些操作,可能会导致不能恢复成原始数据,但是这种情况非常罕见。
我们应该选择哪一个?
通常,如果你想要更深度的数据安全,你应该同时使用这两种方法
如果你更多的关注数据,但是同时能够忍受几分钟数据的丢失,你可以仅仅使用RDB
但是有许多用户仅仅使用AOF,但是我们并不鼓励这样,因为RDB快照能够很好的做数据库备份,能够快速重启,能够避免AOF引擎的一些bugs
快照
默认Redis保存数据集的快照到磁盘上,以名叫dump.rdb的文件名保存。它是一个二进制文件,例如,如果每60秒,至少有1000个keys改变,那么让Redis自动执行快照
save 60 1000
工作流程:
当Redis需要做快照的时候,Redis forks,会有一个子进程和父进程。子进程开始写数据集到一个临时的RDB文件。当子进程完成后,新的文件会替换老的文件
Append-only file
快照并不是很耐用,如果你的计算机停止Redis运行或者你kill -9实例,最新写到Redis的数据会丢失。对一些应用来说,这并不是理想的选择。为了更好的耐用,你可以选择append-only file,在配置文件中
appendonly yes
当设置完成后,每一次修改数据集的操作将会添加到AOF中,当你重启Redis的时候,会重新应用AOF来构建数据集
Log重写
AOF会越来越大,例如,你修改一个key的值100次,你的数据集会存储最终的值,但是在AOF中会有100条记录,99条记录对于重构数据集是不需要的。
Redis支持一个特性:Redis会以守护进程重新构建AOF,而且并不会影响客户端的服务。当你执行BGREWRITEAOF,Redis会写最简短的命令,来构建数据集。如果Redis版本是2.2,你需要时常运行BGREWRITEAOF命令。Redis 2.4会自动触发log重写
append only file怎么耐用
你可以配置Redis同步数据到磁盘的频率,有3个不同的选择
- fsync(每次都添加新的命令到AOF中,是非常慢的,但是非常安全)
- fsync evry second(非常快,如果有灾难发生,你仅仅丢失一秒的数据)
- Never fsync(仅仅放你的数据到内存,是非常快的,但是不安全)
推荐的策略是fsync every second,这也是默认的策略。因为它是相当快并且安全。always策略在实践中是非常慢的。
如果我的AOF文件损害了,我应该做什么?
当写AOF文件的时候,服务崩溃。这样使得Redis无法加载AOF文件。当这个发生的时候,你可以使用下面的流程来解决问题
- 做一下你的AOF文件的备份
- 使用redis-check-aof --fix来解决AOF文件的损害
- 可选,使用diff -u来对比两个AOF文件的不同
- 用修复后的AOF文件来启动服务
Log重写的工作流程
Log重写使用和快照一样的copy-on-write方式,下面是工作流程
- Redis forks,我们会有子进程和父进程
- 子进程会以临时文件的形式写新的AOF文件
- 父进程积累新的改变到内存缓存中,但是同时一会添加新的改变到老的AOF文件中,如果我们重写失败了,那么我们是安全的。
- 当子进程完成重写文件后,父进程得到通知,添加内存缓存中的内容到新的AOF文件中
- Redis会命令命名老的AOF名字到新的文件名字,开始添加新的数据到新的文件
如果现在在使用dump.rdb快照,怎么切换成AOF?
Redis >= 2.2
- 备份下最新的dump.rdb文件
- 传输这个备份文件到安全的地方
- 执行下面的命令
redis-cli config set appendonly yes
redis-cli config set save ""
Redis2.0
- 备份下最新的dump.rdb文件
- 传输备份文件到安全的地方
- 停止所有对数据库的写操作
- 执行redis-cli bgewriteaof命令,会创建一个appendonly文件
- 当Redis完成AOF dump,停止redis服务。
- 编辑redis.conf文件,开启append only file持久化
- 重启Redis服务
AOF和RDB持久化的互动
Redis>2.4会避免当RDB快照正在执行的过程中,来触发AOF重写。当AOF重写正在执行的过程中,来执行BGSAVE。这样做是为了避免两个守护进程带来高强度的磁盘IO
当快照正在执行过程中,用户明确使用BGREWRITEAOF命令来请求log重写操作,服务会返回OK,但是只有当快照执行完成后,才开始执行log重写
当AOF和RDB持久化都开启的时候,Redis重启的时候,AOF文件用来构造数据集,来保证数据的完整性。
备份Redis数据
如果数据不备份,会导致数据的丢失。Redis有非常友好的数据备份。当数据库在运行的时候,你可以复制RDB文件。RDB文件只要生成,并不会修改了。这样意味着复制RDB文件是安全的。下面是我的建议:
- 创建定时任务,在一个目录做每小时的快照,在另一个目录中做每天的快照
- 当cron脚本在运行的时候,使用find命令确保老的快照已被删除。
- 至少保证每天传输RDB快照到数据中心之外护着其他的物理主机
灾难恢复
类似于数据备份,通过传输RDB快照到其他的机器上,然后通过一些验证方法来验证数据的正确性。当数据丢失了,可以使用这些备份文件恢复。
以上是关于Redis持久化的主要内容,如果未能解决你的问题,请参考以下文章