你真的了解 redis 持久化机制 AOF 吗?
前言
说到关系型数据库,最常想到的就是 MySQL、oracle 了;说到非关系型数据库,最常想到的就是 redis、MongoDB 了。而 Redis 因其速度快的优势,广泛应用在各种缓存场景中。
但 redis 数据是存储在内存中,所以数据的持久化就显得尤为重要,我们都知道,Redis 有两大持久化机制,分别是 AOF 日志 和 RDB 快照,今天就先来说说 AOF 日志的重要知识吧。
AOF 写入规则
简单来说,AOF 写入规则就是:
redis 执行命令
执行成功后,将命令记录到日志中(注意,是将命令记录起来)
注意,命令成功后才会记录命令,这样就可以避免记录大量错误命令到日志中了。
AOF 存在 2 个潜在风险:
丢失数据,比如刚执行完一个命令,AOF 日志还没记录就宕机了,此时会丢失这个命令日志。
会阻塞 Redis 主线程:AOF 不会阻塞当前的操作,但是可能会给下一操作带来阻塞的风险,因为 AOF 日志也是在 Redis 的主线程中完成的。
AOF 的 3 种写回策略
为了解决丢失数据的风险,AOF 有提供了 3 种写回策略,分别是:
Always 同步写回:每个写命令执行完成,立刻同步地将日志写回磁盘;
Everysec 每秒写回:每个写命令执行后,日志先写到内存缓冲区,每 1 秒将缓冲区的内容写入磁盘;
No 操作系统控制的写回:每个写命令执行后,把日志写到 AOF 文件的内存缓冲区,写入时机由操作系统决定。
每种策略都有各自的优缺点,总结就是:
Always:优点就是数据基本不丢失, 缺点是每个命令执行后都得同步,性能影响大;
Everysec:优点就是性能适中,缺点是宕机会丢失 1 秒内的数据;
No:优点就是性能最好,缺点是宕机会丢失较多数据。
根据每种策略的优缺点,我们结合项目的要求来选择策略。比如说我们的数据可靠性的要求特别高,就选择 Always 策略;如果想高性能,可靠性要求不是很高,就选择 No 策略;如果允许数据有少部分丢失,性能要求不能受太大影响,我们可选择 Everysec 策略。
当 AOF 记录的日志越来越多,日志文件也会随着增大,我们需要注意随之产生的性能问题。总结有 3 点:
系统会限制保存过大的文件;
文件太大,追加日志的话,效率会变低;
文件太大,如果发生宕机,恢复时间就会很慢。
Redis 的设计者也考虑到了这个问题,因此就有了下面要讲的 AOF 重写机制。
AOF 重写机制
重写机制说简单点,就是会对记录的多条命令加以判断,如果可合并,就对多条命令合并,这样就减少了文件大小。举个例子来说:
此时 nba 这个哈希列表中有的数据是:curry 30, kobe 24
经过 AOF 重写后的命令就会简化成:
AOF 重写这个过程,不会阻塞主线程。因为这个过程是通过后台子进程 bgrewriteaof 去完成的。重写这个过程,总结来说就是一个拷贝,两处日志。
一个拷贝 意思就是当 AOF 重写时,主线程会 fork 出一个子进程 bgrewriteaof。同时,fork 会将主线程的内存拷贝一份给子进程,这样子进程就能访问到最新的数据,bgrewriteaof 就将需要拷贝的数据记录到重写日志。
两处日志 指的是:1. 正在使用的 AOF 日志,redis 会将它写到缓冲区;2.新的 AOF 重写日志,也会被写到重写日志的缓冲区,等到拷贝数据的重写完成后,再将新的重写日志也写到 AOF 文件中。
归纳一下,每次 AOF 重写时,Redis 会拷贝一份内存用于重写。然后 2 处日志就是保证重写过程中,新产生的数据不会丢失。
AOF 重写的触发条件
我们可通过 2 个配置项去控制 AOF 重写的触发:
auto-aof-rewrite-min-size: 表示运行 AOF 重写时文件的最小大小,默认为 64MB
auto-aof-rewrite-percentage: 当前 AOF 文件比上一次重写后 AOF 文件的增量大小,和上一次重写后 AOF 文件大小的比值。
当 AOF 文件大小同时超出 2 个配置项的值时,Redis 就会触发 AOF 重写这个机制。
小结
Redis AOF 日志,是 Redis 持久化机制的一种。当我们要选择此机制时,需要了解其写入规则及其重要参数,才能更好的配置好 redis。
版权声明: 本文为 InfoQ 作者【芥末拌个饭吧】的原创文章。
原文链接:【http://xie.infoq.cn/article/0ea6f45a83612018a81d3aad7】。文章转载请联系作者。
评论