Redis 水滴石穿之(四)持久化

目录

  • Redis 水滴石穿之(四)持久化
    • 一、概述
    • 二、RDB
      • 1、RDB快照触发时机
        • 1.1 手动触发 (save & bgsave)
        • 1.2 自动触发
      • 2、RDB快照实现原理
      • 3、RDB文件结构
      • 4、RDB常用配置
      • 5、RDB方式的优缺点
    • 三、AOF
      • 1、开启AOF
      • 2、AOF执行流程
        • 2.1 AOF命令同步
        • 2.2 AOF文件写入
        • 2.3 AOF文件重写
          • 2.3.1 AOF文件重写触发方式
          • 2.3.2 AOF重写流程
      • 3、AOF常用配置
      • 4、AOF方式的优缺点
      • 5、启动时加载
    • 四、混合持久化
      • 1、开启混合持久化
      • 2、混合持久化触发方式
      • 3、混合持久化执行流程
      • 4、混合持久化的加载
    • 五、总结
    • 六、拓展
      • 1、fork阻塞:CPU的阻塞
      • 2、AOF追加阻塞:硬盘的阻塞
    • 参考文献
    • 每日一皮

在上一篇 Rdis 水滴石穿之(三)数据类型与内存编码当中我们介绍了Redis的内存模型、内部存储的一些细节以及每种数据类型的内存编码等,本章我们来讨论下Redis的持久化部分。

一、概述

我们都知道,数据可以存放在磁盘也可以放在内存当中,它们各有特点,内存的存取速度比较快,但是重启后数据会丢失,资源比较珍贵;硬盘的存取速度不如内存快,但是重启之后数据不会丢失,所以我们平时大多都是选择把数据放到硬盘,需要的时候加载到内存。

存储数据的文件随着业务的增长可能会越来越大,面对一些并发较高的场景时,为了避免在海量数据中检索,我们可以把热点数据放到Redis缓存里面,来缓解数据库的压力,同时提高我们系统的吞吐量。

Redis为了内部数据的安全考虑,会把自身的数据以文件的形式保存在硬盘中,这样在重启之后数据会自动恢复,保证了数据不会丢失,提高了系统应对灾难故障的性能。

Redis提供了三种持久化方案,下面我们依次来看下Redis持久化的实现原理,细节及需要注意的问题。

二、RDB

RDB持久化保存的是某一个时间点之前的数据,当符合一定条件时,Redis会自动将当前进程中的数据生成快照保存到硬盘,因此也称作快照持久化,保存的文件后缀是rdb(RDB 文件是经过压缩的二进制文件 ,占用的空间会小于内存中的数据,更加利于传输。);当Redis重新启动时,可以读取快照文件恢复数据(服务器载入RDB文件期间处于阻塞状态,直到载入完成为止。 )。

1、RDB快照触发时机

RDB持久化的触发分为手动触发和自动触发两种。

1.1 手动触发 (save & bgsave)

save命令和bgsave命令都可以生成RDB文件,不同的是save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在此期间,整个过程都会阻塞Redis服务器,此时服务器不能处理任何命令请求,所以save命令需要慎用,实际生产中一定要杜绝使用save命令。

而bgsave命令会创建一个子进程,由子进程来负责创建RDB文件,父进程即Redis主进程则继续处理请求,在bgsave命令执行过程中,只有fork子进程时会阻塞服务器,所以在后面讲到的自动触发快照时,Redis会选择bgsave而不是save来进行持久化。

1.2 自动触发

1)配置文件中的 save seconds changes

最常见的是通过在redis.conf配置文件中通过配置 save seconds changes,指定在设定的seconds时间内发生了指定的changes次变化,会触发快照(这里是bgsave方式)。

save 900 1 :表示15分钟(900秒)内Redis数据发生了至少1次变化,到达900秒时则进行快照;

save 300 10 : 表示5分钟(300秒)内Redis数据发生了至少10次变化,到达300秒时则进行快照;

save 60 10000 :表示1分钟内Redis数据发生了至少10000次变化,到达60秒时则进行快照。

下图是满足save seconds changes条件时触发快照的日志

save seconds changes 的实现原理

Redis的save seconds changes,是通过serverCron函数、dirty计数器、和lastsave时间戳来实现的。

每隔100ms,执行serverCron函数;在serverCron函数中,遍历save seconds changes配置的保存条件,只要有一个条件满足,就进行bgsave。

对于每一个save seconds changes条件,需要同时满足当前时间-lastsave > seconds 且dirty >= changes

  • serverCron是Redis服务器的周期性操作函数,默认每隔100ms执行一次;

    该函数对服务器的状态进行维护,其中一项工作就是检查save seconds changes 配置的条件是否满足,如果满足就执行bgsave。

  • dirty计数器是Redis服务器维护的一个状态,记录了上一次执行bgsave/save命令后,服务器状态进行了多少次修改(包括增删改);而当save/bgsave执行完成后,会将dirty重新置为0。

    例如,如果Redis执行了set key hello,则dirty值会+1;如果执行了sadd myset 1 2 3,则dirty值会+3;需要注意的是,dirty记录的是服务器进行了多少次修改,而不是客户端执行了多少修改数据的命令。

  • lastsave时间戳也是Redis服务器维持的一个状态,记录的是上一次成功执行save/bgsave的时间。

2)主从复制场景

在主从复制场景下,如果从节点执行全量复制操作,则主节点会执行bgsave命令,并将快照文件发送给从节点;

3)停止服务或执行 shutdown

当停止Redis服务或者执行shutdown命令时,会自动执行rdb持久化。

4)执行flushall命令

当执行flushall命令时,也会触发rdb持久化。

2、RDB快照实现原理

该持久化方式实际是在 Redis 内部一个定时器事件,每隔固定时间去检查当前数据发生的改变次数与时间是否满足配置的持久化触发的条件,如果满足则通过操作系统 fork 调用来创建出一个子进程,这个子进程默认会与父进程共享相同的地址空间,这时就可以通过子进程来遍历整个内存来进行存储操作,而主进程则仍然可以提供服务,当有写入时由操作系统按照内存页为单位来进行 copy-on-write 保证父子进程之间不会互相影响。

下面主要说明bgsave命令的执行流程,如图所示:

具体流程说明如下:

  • Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof的子进程,如果在执行则bgsave命令直接返回。bgsave/bgrewriteaof 的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。
  • 父进程执行fork操作创建子进程,创建过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令;
  • 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,此时父进程可以响应其他命令;
  • 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后替换原来的RDB文件,需要注意的是 Redis 在进行快照的过程中不会修改 RDB 文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候 RDB 文件都是完整的 ;
  • 子进程发送信号给父进程表示完成,父进程更新统计信息。

3、RDB文件结构

上面提到过,RDB 文件是经过压缩的二进制文件 ,占用的空间会小于内存中的数据,更加利于传输,这里我们来看看它到底长成什么样,如图所示,

vim dump.rdb 文件内容如下,

各字段按顺序说明如下:

  • 头部5字节固定为“REDIS”字符串

  • 4字节的RDB文件版本号,需要注意它不是Redis的版本号

  • 辅助字段,含义如下表,(表中的字段名称可以结合上图dump.rdb一起看,因为没有做主从,所以主从相关的字段上图没有显示)

    字段名称 字段值 字段名称 字段值
    redis-ver 5.0.8 aof-preamble 是否开启aof/rdb混合持久化
    redis-bits 64/32 repl-stream-db 主从复制相关
    ctime 当前时间戳 repl-id 主从复制相关
    used-mem Redis占用内存 repl-offset 主从复制相关
  • 数据库序号,指明数据需要放到哪个数据库

  • 指明当前数据库键值对散列表的大小,Redis的每个数据库是一个散列表,这样在加载时可以直接将散列表扩展到指定的大小,来提升加载速度

  • 当前数据库过期时间散列表的大小,Redis的过期时间也是保存为一个散列表

  • Redis 中具体键值对的存储

  • RDB文件结束标志

  • 8字节的校验码, 前面所有内容的校验和;Redis在载入RBD文件时,会计算前面的校验和并与check_sum值比较,判断文件是否损坏。

小贴士:我们前面提到过,Redis中的键都是字符串,RDB中对字符串的保存会有两种优化形式,一种是尝试将字符串按整型保存;另一种是将字符串进行LZF压缩之后保存。虽然压缩耗时,但是可以大大减小RDB文件的体积,因此压缩默认开启。

4、RDB常用配置

下面是关于RDB常用的配置,及其默认值如下:

  • save seconds changes:bgsave自动触发的条件;如果没有配置比如save ‘’ ‘’,相当于自动的RDB持久化关闭,此时可以通过其他方式触发。
  • stop-writes-on-bgsave-error yes:当bgsave出现错误时,Redis是否停止执行写命令;设置为yes,则当硬盘出现问题时,可以及时发现,避免数据的大量丢失;设置为no,则Redis无视bgsave的错误继续执行写命令,当对Redis服务器的系统使用了监控时,该选项可以考虑设置为no。
  • rdbcompression yes:是否开启RDB文件压缩。
  • rdbchecksum yes:是否开启RDB文件的校验,在写入文件和读取文件时都起作用;关闭checksum在写入文件和启动文件时大约能带来10%的性能提升,但是数据损坏时无法发现。
  • dbfilename dump.rdb:RDB文件名。
  • dir ./:RDB文件和AOF文件所在目录。

5、RDB方式的优缺点

  • 优点: RDB文件紧凑,体积小,网络传输快,适合全量复制;恢复速度快,对性能的影响相对较小。
  • 缺点: 使用 RDB 方式实现持久化,一旦 Redis 异常退出,就会丢失最后一次快照以后更改的所有数据。这个时候我们就需要根据具体的应用场景,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受范围;此外RDB文件需要满足特定格式,兼容性不好,如老版本的Redis不兼容新版本的RDB文件。

三、AOF

Redis的另一种持久化方式AOF (Append Only File) ,简单来说是将Redis服务端每次执行的写命令记录到日志文件中,当Redis重启时再次执行AOF文件中的命令来恢复数据。

1、开启AOF

Redis服务器默认使用RDB持久化,关闭AOF;要开启AOF,需要在redis.conf配置文件中配置:

appendonly yes    //默认为no不开启

2、AOF执行流程

由于要记录Redis服务端执行的的每一条写命令,所以AOF没有触发机制,其执行流程主要包括AOF命令的同步和文件的写入。

2.1 AOF命令同步

Redis会先将写命令写到缓冲区,而不是直接写入文件,主要是为了避免每次都直接写入硬盘,导致硬盘IO影响Redis整体的性能。

其实Redis的每一条命令的执行都会调用call函数,而AOF命令的同步就是在call命令中实现的,它首先会判断是否开启了AOF,如果开启则每条命令的执行完毕后都会同步写入到aof_buf(aof_buf是个全局的SDS类型的缓冲区)中,然后继续判断当前是否正在执行AOF重写操作,如果是则将命令再次写入到aof_rewrite-buf_blocks中(关于aof_rewrite-buf_blocks,这个我们会在AOF重写流程里面介绍),其命令写入的格式是通过catAppendOnlyGenericCommand函数将命令转换为保存在aof_buf缓冲区的数据结构,假如执行了命令 set key 123,其转换后的格式如下,

//其中\r\n为分隔符,
"*3\r\n$3\r\nset\r\n$3\r\nkey\r\n$3\r\n123\r\n"//去掉分隔符之后,
"*3 $3 set $3 key $3 123 "

说明如下,

​ *3 :表示该命令共有3个参数

​ $3 :表示后面的参数长度为3,顺序读取3个字符 即 set,后面会依次解析到key 123

后面如果读取到另一个*的时候表明另一条命令的解析。

2.2 AOF文件写入

上面提到的命令同步只是将命令写到了aof_buf缓冲区,AOF的持久化最终是需要将缓冲区中的内容写入到磁盘文件。写文件是通过系统的write函数执行,但是write之后数据只是保存在kernel的缓冲区中,即操作系统内存缓冲区中, 当缓冲区被填满或超过指定时限后,才真正将缓冲区的数据写入到硬盘里,这样虽然提高了效率,但也存在安全问题。如果计算机断电或发生故障导致停机,此时内存缓冲区中的数据会丢失;所以操作系统提供fsync、fdatasync等函数,强制操作系统立刻将缓冲区中的数据写入到硬盘里,来保证数据的安全性。

也就是真正的写入磁盘还需要调用fsync函数,由于fsync操作缓慢且会阻塞,所以Redis通过appendfsync来控制调用fsync的频率,共有3种模式,具体如下,

  • no:命令写入aof_buf后调用系统write操作,不执行fsync,同步时机由操作系统负责,数据安全性最低,但Redis性能最高;
  • always:命令写入aof_buf后立即调用系统fsync操作同步到AOF文件,fsync完成后线程返回。数据安全性最高但性能最低;
  • everysec:命令写入aof_buf后调用系统write操作,write完成后,由专门的线程每秒执行一次fsync,属于折中的方案,在数据安全性和性能之间达到一个平衡,因此是Redis的默认配置,也是我们推荐的配置。

2.3 AOF文件重写

随着Redis 服务的运行,执行的写命令越来越多,AOF文件会越来越大,过大的AOF文件不仅会影响服务器的正常运行,也会导致数据恢复需要的时间过长。而且当有大量的修改操作时,对同一个键可能有成百上千条执行命令,由于AOF方式会记录每一次的改写命令,所以可能会有很多不需要记录的命令,比如,

rpush mylist 1
rpush mylist 2
rpush mylist 3
rpush mylist 4
rpush mylist 5
lpop mylist

此时AOF文件种会保存对mylist操作的6条命令,mylist当前的内容为 2 3 4 5,AOF重写就是直接按当前mylist种的内容 写为rpush mylist 2 3 4 5,这样6条命令就变为了一条,这样就减小了AOF文件大小,同时提高加载速度。

总结一下,文件重写就是定期重写AOF文件,减小AOF文件的体积。需要注意的是,AOF重写是把Redis进程内的数据转化为写命令,同步到新的AOF文件,不会对旧的AOF文件进行任何读取、修改操作。

另外需要注意的是,AOF文件重写虽然是强烈推荐的,但并不是必须的。即使没有文件重写,数据也可以被持久化并在Redis启动的时候导入。因此在生产中,可以关闭自动的文件重写,然后定时在每天的某一时刻定时执行。

2.3.1 AOF文件重写触发方式

AOF重写有两种触发方式,一种是通过配置自动触发,另一种是手动执行bgrewriteaof命令触发。

自动触发: 由auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数决定。

当AOF文件大于auto-aof-rewrite-min-size配置的大小并且AOF文件当前大小比基准大小增长了auto-aof-rewrite-percentage配置的参数时会自动触发一次AOF重写操作,即执行bgrewriteaof操作。其中,基准大小为Redis重启加载完AOF文件后,aof_buf缓冲区的大小,每执行完一次AOF重写之后,基准大小相应的更新为重写之后AOF文件的大小。

手动触发: 通过客户端输入bgrewriteaof,该命令的执行与bgsave类似,都是fork子进程完成相应的工作,且都只有在fork时会阻塞。

2.3.2 AOF重写流程

AOF重写的触发无论是自动配置还是手动触发,最后都会执行bgrewriteaof流程,示例如图,

详细说明如下,

该命令调用bgrewriteaofCommand,然后创建管道,fork进程,子进程调用rewriteAppendOnlyFile执行AOF重写操作,父进程会继续处理客户端请求,当子进程执行完毕后,父进程调用回调函数做一些后续的处理操作。

需要注意的是,当子进程执行重写时,父进程仍然会执行客户端的命令,为了保证重写完成后的文件也包含这些命令,Redis引入了一个list类型的缓冲区rewrite_buf_blocks,我们之前在AOF命令的同步流程中提到过, 也就是说,bgrewriteaof执行期间,Redis的写命令会同时追加到aof_buf和aof_rewirte_buf两个缓冲区中,然后将这些命令在重写后的文件中进行回放即可。

Redis为了尽可能的减少主进程的阻塞时间,通过管道按批次将重写过程中父进程积累的命令发送给子进程,由子进程重写完成后进行回放,那么它是如何通过管道同步给子进程的呢?示例如图,

父进程在fork之前会建立3对管道,即fd0/fd1,fd2/fd3,fd4/fd5,它们各自配对执行。

首先父进程通过fd1将执行AOF重写时积累的命令发送给子进程,子进程通过fd0进行接收并保存;

当子进程执行完重写之后,通过fd3写入一个“!”通知父进程不需要继续通过管道发送累计命令,父进程通过fd2接收到“!”后,通过fd5也写入一个“!”表示确认,子进程通过fd4同步阻塞接收到“!”才可以进行后续的退出操作。退出时首先会将接收到的累计命令进行回放,然后执行fsync。

3、AOF常用配置

下面是AOF常用的配置项,及其默认值,

  • appendonly no:是否开启AOF,默认为no;
  • appendfilename “appendonly.aof”:AOF文件名;
  • dir ./:AOF文件所在目录;
  • appendfsync everysec:fsync调用策略;
  • no-appendfsync-on-rewrite no:AOF重写期间是否禁止调用fsync,需要在负载和安全性之间进行平衡;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载,但是可能会丢失AOF重写期间的数据;
  • auto-aof-rewrite-percentage 100:文件重写触发条件之一;
  • auto-aof-rewrite-min-size 64mb:文件重写触发条件之一;
  • aof-load-truncated yes:如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件。

4、AOF方式的优缺点

  • 优点

    AOF保存的是一条条命令,理论上可以做到故障时只丢失一条命令,数据安全性较高,同时没有兼容性的问题。

  • 缺点

    由于操作系统中执行写文件操作代价比较大,比较影响性能,另外如果AOF文件很大的话,数据恢复也会很慢。

5、启动时加载

讨论了RDB与AOF两种持久化方式后,我们再来看Redis重启时加载AOF与RDB的顺序,

如果aof和rdb都开启,只会加载aof,因为aof最能保证数据的完整性;即使没有aof文件,也不会加载rdb文件;

四、混合持久化

讨论了RDB和AOF两种持久化方式后,我们回头来总结一下这两种持久化的实现方式。

RDB保存的是一个时间点的快照,保存的是数据,可以看成是一个最终的状态;

而AOF保存的是一条条命令,可以看成是到达最终状态的过程,如果Redis有大量的修改操作,那么RDB中一个数据的最终状态可能会需要大量的命令才能达到,这样会造成AOF文件过大且加载变慢,所以Redis提供了AOF重写策略解决这个问题。

在加载的时候,RDB只需要把相应的数据加载到内存即可,而AOF文件的加载相当于是创建一个伪客户端,然后把命令一条条发送给Redis服务端,由服务端完整的再执行一遍相应的命令。

因为AOF和RDB各有优缺点,重启时如果优先加载RDB,加载速度更快,但数据可能不是很完整;如果优先加载AOF,数据会比RDB方式的完整,但速度会变慢,所以为了结合这两者的优点,Redis4.0提出了新的持久化方式–混合持久化。

1、开启混合持久化

是否开启混合持久化需要在redis.conf文件中配置:aof-use-rdb-preamble yes/no,yes表示开启,Redis5.0默认为yes。其它版本需要检查一下是否开启,可以使用 config get aof-use-rdb-preamble 命令查看。

另外需要注意的是,此种模式下,aof方式必须开启,即appendonly 参数必须为yes,这样开机启动后才会加载aof文件。

2、混合持久化触发方式

混合持久化是基于AOF重写机制的,关于AOF的重写机制上面已详细讨论过,这里不再重复。

3、混合持久化执行流程

混合持久化是指进行AOF重写时,子进程将当前时间点的数据快照保存为RDB文件格式写入AOF文件头部,那些在重写操作执行之后执行的 Redis 命令,则以AOF持久化的方式追加到AOF文件的末尾,最终的AOF文件是这样的,开头是RDB格式的二进制+增量时AOF日志,如图

4、混合持久化的加载

我们在介绍AOF重写时执行的bgrewriteaof流程中,提到过rewriteAppendOnlyFile,子进程在执行此函数时会判断是否开启了混合持久化,如果开启,则首先按RDB保存方式保存当前数据的快照,保存完毕后回放父进程累计的命令到aof文件末尾即可。

加载时首先会识别AOF文件是否以REDIS字符串开头,如果是就按RDB格式加载,加载完RDB后继续按AOF格式加载剩余部分。

五、总结

本章介绍了Redis持久化的三种实现方式,RDB、AOF和混合持久化。

首先介绍了RDB的文件结构、触发时机、实现原理及RDB相关的常用配置;

然后介绍了AOF的执行流程包括命令同步、文件写入、文件重写及常用配置;

最后通过比较AOF和RDB的优缺点引出了混合持久化的实现方式以及执行加载流程。

通过了解Redis持久化实现的原理,我们就可以依据实际情况对数据安全性和性能做取舍。
但实际生产当中会有这样的问题, 持久化可以保证内存数据不会丢失,其侧重解决的是Redis单机备份的问题,即数据从内存到硬盘的备份;但如果Redis所在的服务器发生了故障或者硬盘损坏了,即使做了持久化,数据仍会丢失,所以为了避免这种单点故障,Redis提供了多机热备方案,在下一章Redis-水滴石穿之(五)主从复制 中我们会介绍Redis的主从复制,不见不散,感谢关注。

六、拓展

1、fork阻塞:CPU的阻塞

在Redis的实践中,众多因素限制了Redis单机的内存不能过大,例如:

  • 当面对请求的暴增,需要从库扩容时,Redis内存过大会导致扩容时间太长;
  • 当主机宕机时,切换主机后需要挂载从库,Redis内存过大导致挂载速度过慢;
  • 以及持久化过程中的fork操作,下面详细说明。

首先说明一下fork操作:

父进程通过fork操作可以创建子进程;子进程创建后,父子进程共享代码段,不共享进程的数据空间,但是子进程会获得父进程的数据空间的副本。在操作系统fork的实际实现中,基本都采用了写时复制技术,即在父/子进程试图修改数据空间之前,父子进程实际上共享数据空间;但是当父/子进程的任何一个试图修改数据空间时,操作系统会为修改的那一部分(内存的一页)制作一个副本。

虽然fork时,子进程不会复制父进程的数据空间,但是会复制内存页表(页表相当于内存的索引、目录);父进程的数据空间越大,内存页表越大,fork时复制耗时也会越多。

在Redis中,无论是RDB持久化的bgsave,还是AOF重写的bgrewriteaof,都需要fork出子进程来进行操作。如果Redis内存过大,会导致fork操作时复制内存页表耗时过多;而Redis主进程在进行fork时,是完全阻塞的,也就意味着无法响应客户端的请求,会造成请求延迟过大。

对于不同的硬件、不同的操作系统,fork操作的耗时会有所差别,一般来说,如果Redis单机内存达到了10GB,fork时耗时可能会达到百毫秒级别(如果使用Xen虚拟机,这个耗时可能达到秒级别)。因此,一般来说Redis单机内存一般要限制在10GB以内;不过这个数据并不是绝对的,可以通过观察线上环境fork的耗时来进行调整。观察的方法如下:执行命令info stats,查看latest_fork_usec的值,单位为微秒。

为了减轻fork操作带来的阻塞问题,除了控制Redis单机内存的大小以外,还可以适度放宽AOF重写的触发条件、选用物理机或高效支持fork操作的虚拟化技术等,例如使用Vmware或KVM虚拟机,不要使用Xen虚拟机。

2、AOF追加阻塞:硬盘的阻塞

前面提到过,在AOF中,如果AOF缓冲区的文件同步策略为everysec,则:在主线程中,命令写入aof_buf后调用系统write操作,write完成后主线程返回;fsync同步文件操作由专门的文件同步线程每秒调用一次。

这种做法的问题在于,如果硬盘负载过高,那么fsync操作可能会超过1s;如果Redis主线程持续高速向aof_buf写入命令,硬盘的负载可能会越来越大,IO资源消耗更快;如果此时Redis进程异常退出,丢失的数据也会越来越多,可能远超过1s。

为此,Redis的处理策略是这样的:主线程每次进行AOF会对比上次fsync成功的时间;如果距上次不到2s,主线程直接返回;如果超过2s,则主线程阻塞直到fsync同步完成。因此,如果系统硬盘负载过大导致fsync速度太慢,会导致Redis主线程的阻塞;此外,使用everysec配置,AOF最多可能丢失2s的数据,而不是1s。

AOF追加阻塞问题定位的方法:

1)监控info Persistence中的aof_delayed_fsync:当AOF追加阻塞发生时(即主线程等待fsync而阻塞),该指标累加。

2)AOF阻塞时的Redis日志:

Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.

3)如果AOF追加阻塞频繁发生,说明系统的硬盘负载太大;可以考虑更换IO速度更快的硬盘,或者通过IO监控分析工具对系统的IO负载进行分析,如iostat(系统级io)、iotop(io版的top)、pidstat等。

参考文献

《Redis设计与实现》

《Redis设计与源码分析》

https://www.sohu.com/a/379930347_610509

http://www.redis.cn/topics/persistence.html

https://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=2650769300&idx=1&sn=49a11efa1a6ee605fceaddf240a55c40&chksm=f3f93201c48ebb175fa76053d95e315b621485b0e65e42d8b41fe91b8f859c9278f3adec7ca9&mpshare=1&scene=23&srcid=0731SR4C94CRM0Mljym0oEI3%23r

每日一皮

多年前你的一句保重,我至今没瘦。

Redis 水滴石穿之(四)持久化相关推荐

  1. Redis系列-第四篇持久化与事务

    一.持久化 Redis是一个内存数据库,为了保证数据的持久性,它提供了两种持久化方案: RDB方式(默认) AOF方式 持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的 ...

  2. Redis总结(四)Redis 的持久化

    前面已经总结了Redis 的安装和使用今天讲下Redis 的持久化. redis跟memcached类似,都是内存数据库,不过redis支持数据持久化,也就是说redis可以将内存中的数据同步到磁盘来 ...

  3. Redis基础学习(四)—Redis的持久化

    一.概述 Redis的强大性能很大程度上都是因为数据时存在内存中的,然而当Redis重启时,所有存储在内存中的数据将会丢失,所以我们要将内存中的数据持久化. Redis支持两种数据持久化的方式: RD ...

  4. redis 数据结构 内存管理 持久化

    为什么80%的码农都做不了架构师?>>>    Redis 内存数据结构与编码 OBJECT encoding key.DEBUG OBJECT key 简单动态字符串(simple ...

  5. redis 硬件要求_Redis持久化机制

    介绍 Redis所有的数据都保存在内存中,数据的更新将异步的保存到硬盘上,当需要恢复数据时,从硬盘上将数据再读取到内存中,这就是Redis的持久化过程.主流的持久化方式有两种: 快照:MySQL的Du ...

  6. Redis数据库(四)——Redis集群模式(主从复制、哨兵、Cluster)

    Redis数据库(四)--Redis集群模式(主从复制.哨兵.Cluster) 一.Redis主从复制 1.主从复制流程 二.哨兵模式 1.哨兵模式集群架构 2.哨兵模式主要功能 3.哨兵监控整个系统 ...

  7. Redis数据库(二)——Redis高可用、持久化及性能管理

    Redis数据库(二)--Redis高可用.持久化及性能管理 一.Redis 高可用 主要的高可用技术 二.Redis 持久化 1.持久化的功能 2.两种持久化方式 3.RDB 和 AOF 的区别 ① ...

  8. Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)

    Redis6引入新的RESP3协议,并以此为基础加入了客户端缓存的新特性,在此特性下,大大提高了应用程序的响应速度,并降低了数据库的压力,本篇就带大家来看一下Redis6的新特性:客户端缓存. 目录 ...

  9. Redis简单案例(四) Session的管理

    Redis简单案例(四) Session的管理 原文:Redis简单案例(四) Session的管理 负载均衡,这应该是一个永恒的话题,也是一个十分重要的话题.毕竟当网站成长到一定程度,访问量自然也是 ...

最新文章

  1. matlab 2012 vs2010混合编程
  2. PYPL 12月榜单发布,编程语言、IDE与数据库市场如何?
  3. spring 异常捕获异常_跟踪异常–第5部分–使用Spring进行计划
  4. android 巧用资源文件(不断积累)
  5. informix linux 下载,linux安装informix
  6. oracle查参数,各种oracle参数查询语句
  7. 【贪玩巴斯】一文学会检索三要素:检索字段、检索词、检索算法检索(二)——「一文学会检索三要素:检索字段、检索词、检索算法」 2021-09-18
  8. win7计算机开机黑屏解决办法参考
  9. 后缀是lnk是什么文件_ink是什么文件
  10. vue3生成二维码打印
  11. 干货 | 手把手教你iOS自定义视频压缩
  12. mysql统计分数段人数_mysql 按分数段,每个专业分数段统计人数
  13. 扎实的PHP编程基础,PHP的一些基础编程题
  14. 一文看懂:Android-Q版本在安全方面进行了哪些系统性改进
  15. IKEv2与IKEv1的差异
  16. 数学:它的内容、方法、意义的目录
  17. Node.js + Web Socket 打造即时聊天程序嗨聊(1)
  18. Drools7 动态更新规则
  19. What 引导的三种名词性从句
  20. 什么PDF在线压缩器好用,怎么操作?

热门文章

  1. 一篇文章全面了解监控知识体系
  2. maple 假设_Maple在假设检验中的应用.pdf
  3. 理想低通滤波器、Butterworth滤波器和高斯滤波器(matlab)1
  4. matlab学习矩阵1
  5. 最新CNC数控机床数据采集方案大全,数据采集大全,机床开发资料大全
  6. JAVA开发规范随笔
  7. 计算机上网记录怎么清除,如何清除浏览器缓存及上网痕迹 清除浏览器上网痕迹的方法...
  8. IT项目管理痛点和应对方法总结
  9. 拉马努金:“与神对话”的数学天才
  10. 《定时执行专家》更新日志 - [TimingExecutor] Full Change Log