最近在复习Redis相关的内容,在复习的过程中仔细回顾了一下持久化的两大技术AOF和RDB,本节笔记就围绕他们之一AOF展开。Redis中高可靠性是他在后端领域可以立足的特点之一,高可靠性其中的含义我认为有两部分组成:
- 数据不会轻易丢失
- 服务不会轻易中断
其中数据不轻易丢失就和我们今天回顾的AOF和RDB相关,服务不中断则是和Redis的哨兵机制相关,这个我们以后再回顾,也欢迎大家补充讨论,本节主要介绍AOF。
1. AOF简介
AOF(Append Only File)为了方便理解,我们可以联系WAL(Writer Ahead Log)技术,WAL技术是先写日志,再写磁盘;而AOF则是相反,采取先写内存,再写日志的策略。在AOF日志中他记录的是执行的具体操作,这个我们MySQL中的redo log不同,重做日志记录的是修改后的数据。
我们知道Redis为了追求性能的极致,尽可能减少了一切等待和阻塞的过程,对比先写内存再写日志和先写日志再写内存,如果先写日志那么如果写入内存的过程中发现了执行的语法是有错误的,那么日志的写入是有问题的。对于Redis而言,错误的语句是没法执行的,所以日志中记录的都是有效的操作。
在Redis中AOF持久化默认没有开启,可以通过redis.conf配置文件中查看。但是通过上面的介绍我们你可以发现AOF在某些场景下存在缺陷:
a. 内存中执行完操作以后发生了宕机,这就导致日志中没有记录,这个数据相应的数据可能就存在丢失的风险。
b. Redis在追求性能方面非常关注阻塞操作,先写内存确实可以保证当前操作的非阻塞,但是后写日志会对下一个操作带去阻塞的风险。
以上的两个常见Redis提出了三种写回的策略来解决,我们一起来看看AOF的写回策略。 写回策略分为三种:
a. Everysec:表示每秒写回,每个命令在内存中执行完,会将操作写入日志的缓冲区中,然后每隔1s将缓冲区日志写回磁盘
b. No:日志写入磁盘的时机由操作系统来决定
c. Always:每执行一个命令后就会将其写入磁盘中
对于上面三种写回策略,我们应该根据业务场景中对于数据丢失的容忍程度来选择。
AOF重写
AOF写日志的过程是追加的形式实现的,所以伴随着长时间的记录,这就导致了AOF日志会越来愈多,其中也会包含大量的冗余记录,例如可能存在对同一个数据A的多次修改。日志的变大会对数据恢复性能产生影响,当我们回复Redis数据的时候,是将日志中的一条条记录全部取出来然后执行,日志过大数据恢复的时间自然越长。所以解决日志过大的方式就是AOF重写机制,简单来说就是将日志中对某个数数据的多次修改变成一条修改日志。重写不仅减小了日志体积,同时释放了空间。但是我们需要思考一下重写机制是否是阻塞的?
是否阻塞我们就需要进一步了解重写的具体过程,重写机制涉及到“一处拷贝,两处日志”,首先会fork出一个子线程将主线程中的Redis数据拷贝一份,子线程会将拷贝的Redis数据将执行一遍写操作的日志记录到AOF重写日志中,此时主线程可能接收到新的写操作,写操作会记录到原AOF日志的缓冲区中,同时也会记录到AOF重写日志的缓冲区中,这样既保证了非阻塞,也保证了重写机制,但是我们需要注意fork子线程的过程是阻塞的。
以上就是AOF的大致内容,但是我们发现如果发送宕机需要进行数据恢复,我们最好的情况还是需要将AOF重写日志中所有的记录逐条取出执行一遍,这个过程还是挺耗时的,是否有更好的实现数据恢复的方法呢?这就是我们下节课的主角RDB!