Redis持久化详解
前言 在Redis数据库中,我们知道Redis不仅是将数据保存到内存中,而且要将数据同步到磁盘中,这也就是Redis和Memcache的区别之一,这也就是Redis的持久化,Redis的持久化有RDB和AOF两种方式,下面让我们具体了解一下。一、Redis持久化方式RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。
二、Redis持久化方式对比RDB优点:
[*]RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。
这种文件非常适合用于进行备份,灾难恢复等场景
[*]RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
[*]RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
RDB缺点:
[*]如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。
虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率,但是,因为RDB 文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此你可能会至少 5 分钟才保存一次 RDB 文件。在这种情况下,一旦发生故障停机,你就可能会丢失好几分钟的数据。
[*]每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。
在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端;
如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。
虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。
AOF优点:
[*]使用 AOF 持久化默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。
[*]AOF 文件是一个只进行追加操作的日志文件(append only log),
因此对 AOF 文件的写入不需要进行 seek ,
即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等),redis-check-aof 工具也可以轻易地修复这种问题。
[*]Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写:
重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。
整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。
而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
[*]AOF 文件有序地保存了对数据库执行的所有写入操作,这些写入操作以 Redis 协议的格式保存,
因此 AOF 文件的内容非常容易被人读懂,对文件进行分析也很轻松。导出 AOF 文件也非常简单
AOF缺点:
[*]对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
[*]根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。在一般情况下,每秒 fsync 的性能依然非常高,而关闭 fsync 可以让 AOF 的速度和 RDB 一样快,即使在高负荷之下也是如此。不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
[*]AOF 在过去曾经发生过这样的 bug :因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。(举个例子,阻塞命令就曾经引起过这样的 bug 。)测试套件里为这种情况添加了测试:它们会自动生成随机的、复杂的数据集,并通过重新载入这些数据来确保一切正常。虽然这种 bug 在 AOF 文件中并不常见,但是对比来说,RDB 几乎是不可能出现这种 bug 的。
三、RDB保存数据过程
[*]Redis 调用 fork() 子进程,同时拥有父进程和子进程。
[*]子进程将数据集写入到一个临时 RDB 文件中。
[*]当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件
四、RDB快照的配置在redis的配置文件 redis.conf中
1
save 60 1000
注释:在60 秒内有至少有 1000 个键被改动,就保存一次数据
在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。
五、AOF持久化过程
[*]Redis 执行 fork() ,现在同时拥有父进程和子进程。
[*]子进程开始将新 AOF 文件的内容写入到临时文件。
[*]对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾:
这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
[*]当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
[*]现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
六、AOF持久化配置
1
2
3
4
5
6
7
8
9
10
11
12
# grep append /etc/redis.conf
# At the date of writing these commands are: set setnx setex append
appendonly no
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
# always: fsync after every write to the append only log. Slow, Safest.
# appendfsync always
appendfsync everysec
# appendfsync no
# the same as "appendfsync none". In practical terms, this means that it is
no-appendfsync-on-rewrite no
# Automatic rewrite of the append only file.
将appendonly on 改为yes之后AOF持久化化就配置完成了,是不是感觉很简单。哈哈,配置都很简单关键是理论知识都应该理解。
通过配置文件我们看到AOF的默认fsync策略有三个选项
1
2
3
appendfsync always#每次有新命令追加到 AOF 文件时就执行一次 fsync
appendfsync everysec #每秒执行一次fsync
appendfsync no #从不执行fsync
好了 到此做一个总结,Redis有两种持久化方式,上面详细的对比了两种的优缺点,读者可以更具业务的需要合理的选择适合自己的持久化方式,个人感觉AOF有点像是mysql中的二进制日志,都是不保存数据只是记录下来执行的命令,本博文到此结束,如果有什么问题请留言!
页:
[1]