前言
Redis作为内存型的数据库,虽然很快,依然有着很大的隐患,一旦「服务器宕机」重启,内存中数据还会存在吗?
很容易想到的一个方案是从后台数据恢复这些数据,如果数据量很小,这倒是一个可行的方案。但是如果数据量过大,频繁的从后台数据库访问数据,压力很大;另外一方面恢复数据的时间极慢。
对于Redis来说,实现数据的持久化和快速恢复是至关重要。
什么是 AOF 日志?
AOF(Append Only File)日志称之为「写后日志」,即是命令先执行完成,把数据写入内存,然后才会记录日志。
AOF日志(文本形式)会将收到每一条的命令且执行成功的命令以一定的格式写入到文本中(追加的方式)。
「写后日志有什么好处呢?」 如下:
- 对于写前日志无论命令是否执行成功都会被记录,但是Redis的写后日志则只有命令执行成功才会被写入日志,避免了日志中存在错误命令;
- 同时由于是命令执行成功之后才会写入日志,因此不会阻塞当前命令的执行。
但是AOF日志也有「潜在的风险」,分析如下:
- 由于是写后日志,如果在命令执行成功之后,在日志未写入磁盘之前服务器突然宕机,那重启恢复数据的时候,这部分的数据肯定在日志文件中不存在了,那么将会丢失。(无法通过后台数据库恢复的情况下)
- 虽然不会阻塞当前命令的执行,由于记录日志也是在主线程中(Redis是单线程),如果日志写入磁盘的时候突然阻塞了,肯定会影响下一个命令的执行。
为了解决上面的风险,AOF日志提供了三种回写策略。
三种写回策略
AOF机制提供了三种回写策略,这些都在appendfsync配置,如下:
- Always(同步写回):命令执行完成,立马同步的将日志写入磁盘
- Everysec(每秒写回):命令执行完成后,先将日志写入 AOF 文件的内存缓冲区,每隔一秒把缓冲区中内容写入磁盘。
- No(操作系统控制的写回):每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。
其实这三中写回策略都无法解决主线程的阻塞和数据丢失的问题,分析如下:
- 同步写回:基本不丢失数据,但是每步操作都会有一个慢速的落盘操作,不可避免的影响主线程性能。
- 每秒写回:采用一秒写一次到 AOF 日志文件中,但是一旦宕机还是会丢失一秒的数据。
- 操作