宕机了,Redis如何避免数据丢失?

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

今天是大年初一祝大家新年快乐新的一年技术增进工资翻倍。

目前Redis的持久化主要有两大机制即AOF日志和RDB快照在接下来的两节课里我们就分别学习一下吧。

AOF日志是如何实现的

说到日志我们比较熟悉的是数据库的写前日志Write Ahead LogWAL也就是说在实际写数据前先把修改的数据写到日志文件中以便故障时进行恢复。不过AOF日志正好相反它是写后日志“写后”的意思是Redis是先执行命令把数据写入内存然后才记录日志如下图所示
image

那AOF为什么要先执行命令再记日志呢?要回答这个问题,我们要先知道AOF里记录了什么内容.

传统数据库的日志,例如redo log(重做日志),记录的是修改后的数据,而AOF里记录的是Redis收到的每一条命令,这些命令是以文本形式保存的。

我们以Redis收到“set testkey testvalue”命令后记录的日志为例看看AOF日志的内容。其中“*3”表示当前命令有三个部分每部分都是由“$+数字”开头后面紧跟着具体的命令、键或值。这里“数字”表示这部分中的命令、键或值一共有多少字节。例如“$3 set”表示这部分有3个字节也就是“set”命令。

但是为了避免额外的检查开销Redis在向AOF里面记录日志的时候并不会先去对这些命令进行语法检查。所以如果先记日志再执行命令的话日志中就有可能记录了错误的命令Redis在使用日志恢复数据时就可能会出错。

而写后日志这种方式就是先让系统执行命令只有命令能执行成功才会被记录到日志中否则系统就会直接向客户端报错。所以Redis使用写后日志这一方式的一大好处是可以避免出现记录错误命令的情况。

除此之外AOF还有一共好处它是在命令执行后才记录日志所以不会阻塞当前的写操作。

不过AOF也有两个潜在的风险。

首先如果刚执行完一个命令还没有来得及记日志就宕机了那么这个命令和相应的数据就有丢失的风险。如果此时Redis是用作缓存还可以从后端数据库重新读入数据进行恢复但是如果Redis是直接用作数据库的话此时因为命令没有记入日志所以就无法用日志进行恢复了。

其次AOF虽然避免了对当前命令的阻塞但可能会给下一个操作带来阻塞风险。这是因为AOF日志也是在主线程中执行的如果在把日志文件写入磁盘时磁盘写压力大就会导致写盘很慢进而导致后续的操作也无法执行了。

三种写回策略

其实对于这个问题AOF机制给我们提供了三个选择也就是AOF配置项appendfsync的三个可选值。

  • Always同步写回每个写命令执行完立马同步地将日志写回磁盘
  • Everysec每秒写回每个写命令执行完只是先把日志写到AOF文件的内存缓冲区每隔一秒把缓冲区中的内容写入磁盘
  • No操作系统控制的写回每个写命令执行完只是先把日志写到AOF文件的内存缓冲区由操作系统决定何时将缓冲区内容写回磁盘。

针对避免主线程阻塞和减少数据丢失问题这三种写回策略都无法做到两全其美。我们来分析其中的原因。

  • “同步写回”可以做到基本不丢数据但是它在每一个写命令后都由一个慢速的落盘操作不可避免地影响主线程性能
  • 虽然“操作系统控制的写回”在写完缓冲区后就可以继续执行后续的命令但是落盘的时机已经不在Redis手中了只要AOF记录没有写回磁盘一旦宕机对应的数据就丢失了
  • “每秒写回”采用一秒写回一次的频率避免了“同步写回”的性能开销虽然减少了对系统性能的影响但是如果发生宕机上一秒内未落盘的命令操作仍然会丢失。所以这只能算是在避免主线程性能和避免数据丢失两者取了个折中。

日志文件太大了怎么办

简单来说AOF重写机制就是在重写时Redis根据数据库的现状创建一个新的AOF文件也就说读取数据库中的所有键值对然后对每一个键值对用一条命令记录它的写入。比如说当读取了键值对“testkey”“testvalue”之后重写机制会记录set testkey testvalue这条命令。这样当需要恢复时可以重新执行该命令实现“testkey”“testvalue”的写入。

为什么重写机制可以把日志文件变小呢实际上重写机制具有“多变一”功能。所谓的“多变一”也就是说旧日志文件中的多条命令在重写后的新日志中变成了一条命令。

我们知道AOF文件是以追加的方式逐一记录接收到的写命令。当一共键值对被多条写命令修改时AOF文件会记录相应的多条命令。但是在重写的时候是根据这个键值对当前的最新状态为它生成对应的写入命令这样一来一共键值对在重写日志中只用一条命令就行了而且在日志恢复时只用执行这条命令就可以直接完成这个键值对的写入了。

学习来源极客时间 《Redis核心技术与实战》学习笔记 Day07

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis

“宕机了,Redis如何避免数据丢失?” 的相关文章