4.AOF 写后日志,避免宕机数据丢失
4.1 AOF说明
- AOF日志存储的是Redis服务器的顺序指令序列
- 只记录对内存进行修改的指令
- append-only file(AOF)
- AOF主要是主线程在执行,将日志写入磁盘的过程中,如果磁盘压力太大,写入速度过慢,就会影响后续的操作。
- 比较熟悉的是数据库写前日志,在执行操作前先把修改的数据记入日志,若发生错误了,直接恢复。但是AOF写后日志:先执行命令,写入内存,然后才记录日志。
4.2 写前与写后日志对比
写前日志(Write Ahead Log, WAL):
在实际写数据之前,将修改的数据写到日志文件中,故障恢复得以保证。(先记日志,在执行命令,不会对指令进行语法检查,所以有可能见错误的命令记录,Redis要使用日志恢复数据的话也可能会导致错误)。比如 MySQL Innodb 存储引擎 中的 redo log(重做日志)便是记录修改的数据日志,在实际修改数据前先记录修改日志在执行修改数据。
写后日志:
先执行「写」指令请求,将数据写入内存,再记录日志。Redis记录的每一条命令都是以文本的形式保存的。
为什么 Redis 使用写后日志这种方式呢?写后日志优点:
- 写后日志避免了额外的检查开销,不需要对执行的命令进行语法检查。如果使用写前日志的话,就需要先检查语法是否有误,否则日志记录了错误的命令,在使用日志恢复的时候就会出错。避免可能记录错误命令导致系统客户端出错的情况
- 另外,写后才记录日志,不会阻塞当前的「写」指令执行。
- 如果刚执行完一个命令就宕机了,还没来得及记录日志,就可能会造成数据丢失的风险。如果Redis作为缓存,还可以从后端数据库里重新读入数据进行恢复,如果Redis作为数据库那么此时又没有写入日志,那么久无法进行恢复了。
- 但是如果还没有记录这个写操作,宕机了,就会失去这次操作的数据,AOP避免了当前操作阻塞,但是有可能回引起下一次操作阻塞。AOP主要是主线程在执行,将日志写入磁盘的过程中,如果磁盘压力太大,写入速度过慢,就会影响后续的操作(还没记入宕机,数据丢失,影响下一次操作。磁盘写入,数据过多压力太大,速度缓慢。)
4.3 AOF对日志的要求
Redis接收 [set key MygeByte]命令将数据写到内存后,Redis会按照相关格式写入到AOF文件:
「*3」:表示当前指令分为三个部分,每个部分都是 「$ + 数字」开头,紧跟后面是该部分具体的「指令、键、值」。
「数字」:表示这部分的命令、键、值多占用的字节大小。比如 「$3」表示这部分包含 3 个字节,也就是 「set」指令。
4.4.写回策略
仔细分析的话,你就会发现,这两个风险都是和AOF写回磁盘的时机相关的。这也就意味着,如果我们能够控制一个写命令执行完后AOF日志写回磁盘的时机,这两个风险就解除了。写回机制就很有必要了。
- 为了提高文件的写入效率,当用户调用 write 函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。
- 若计算机出现一些失误或者异常,内存缓冲区里的写入数据会丢失。
写回策略:
可以根据系统对高性能和高可靠性的要求,来选择写回策略。总结如下:
想要获得高性能,就选择 No 策略;如果想要得到高可靠性保证,就选择 Always 策略;如果允许数据有一点丢失,又希望性能别受太大影响的话,那么就选择 Everysec 策略。