关于redis:Redis持久化机制

1次阅读

共计 4523 个字符,预计需要花费 12 分钟才能阅读完成。

Redis 数据长久化

Redis 作为一个 内存 数据库,数据是以内存为载体存储的,即 断电即失(一旦 Redis 服务器过程退出,服务器中的数据也会隐没)。为了解决这个问题,Redis 提供了长久化机制,也就是把内存中的数据保留到磁盘当中,防止数据意外失落

Redis 提供了两种长久化计划:RDB 长久化 AOF 长久化,一个是快照的形式,一个是相似日志追加、历史记录的形式

一、RDB(Redis DataBase)

RDB 是快照长久化,即通过 快照 SnapShot的形式,在 指定的工夫距离内 将内存中的数据集 快照写入磁盘。在创立快照之后,用户能够备份该快照,能够将快照复制到其余服务器以创立雷同数据的服务器正本,或者在重启服务器后复原数据。RDB 是 Redis 默认的长久化形式

RDB 长久化会生成 rdb 文件,该文件是一个 压缩 过的 二进制文件 ,能够通过该文件还原快照时的数据库状态,即生成该 rdb 文件时的服务器数据。rdb 文件默认为当前工作目录下的dump.rdb,能够依据配置文件redis.conf 中 SNAPSHOTTING 局部的 dbfilenamedir设置 rdb 的文件名和文件地位。默认其实能够不须要改变。只有 dump.rdb 文件在 redis 的启动目录下,redis 启动的时候就会主动查看 dump.rdb 复原数据。

# 设置 dump 的文件名
dbfilename dump.rdb

# 工作目录
# 例如下面的 dbfilename 只指定了文件名,# 然而它会写入到这个目录下。这个配置项肯定是个目录,而不能是文件名。dir ./

获取 redis 装置目录

127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin" #如果在这个目录下存在 dump.rdb 文件,启动 redis 就会主动复原数据

1、快照触发机会:

  • 执行 savebgsave命令
  • 配置文件中 save <seconds> <changes> 规定,主动间隔性执行 bgsave 命令,如下图

示意在 seconds 秒内,至多有 changes 次变动,就会主动触发 gbsave 命令

  • 主从复制时,从库全量复制同步主库数据,主库会执行bgsave
  • 执行 flushall 命令清空服务器数据
  • 执行 shutdown 命令敞开 Redis 时,默认会执行 save 命令(能够手动 shutdown nosave 就不执行 save 命令)

2、save 和 bgsave 命令:

执行 savebgsave命令,能够手动触发快照,生成 rdb 文件,两者的区别如下

应用 save 命令 会阻塞 Redis 服务器过程,服务器过程在 rdb 文件创建实现之前是不能解决任何的命令申请

127.0.0.1:6379> save
OK
复制代码

而应用 bgsave 命令不同的是,bgsave命令会 fork 一个子过程,而后该子过程会负责创立 rdb 文件,而服务器过程会持续解决命令申请。

fork()是由操作系统提供的函数,作用是创立以后过程的一个正本作为子过程

fork一个子过程,子过程会把数据集先写入临时文件,写入胜利之后,再替换之前的 rdb 文件,用二进制压缩存储,这样能够保障 rdb 文件始终存储的是残缺的长久化内容

【补充】

在生产环境中,通常咱们会将 dump.rdb 文件进行备份。

3、优缺点

长处

  • 适宜大规模的数据恢复
  • 对数据完整性和一致性要求不高

毛病

  • 在肯定间隔时间做一次备份,如果 redis 意外宕机,会丢掉最初一次快照后的所有批改
  • RDB 应用 fork() 产生子过程进行数据的长久化,如果数据比拟大的话可能就会破费点工夫,造成 Redis 进行服务几毫秒。如果数据量很大且 CPU 性能不是很好的时候,进行服务的工夫甚至会到 1 秒。

二、AOF(Append Only File)

AOF 长久化会把被执行的写命令写到 AOF 文件的开端,记录数据的变动。默认状况下,Redis 是没有开启 AOF 长久化的,开启后,每执行一条更改 Redis 数据的命令,都会把该命令追加到 AOF 文件中,这就相当于是把 redis 执行过的所有指令记录下来(读操作不记录),有点相似历史记录,复原数据时将这个文件全副执行一遍。这会升高 Redis 的性能,但大部分状况下这个影响是可能承受的,另外应用较快的硬盘能够进步 AOF 的性能。AOF 保留的是 appendonly.aof 文件

在配置文件中 redis.conf 开启 AOF 和对于 AOF 的配置操作:

# appendonly 参数开启 AOF 长久化,默认是 no
appendonly no

# AOF 长久化的文件名,默认是 appendonly.aof
appendfilename "appendonly.aof"

# AOF 文件的保留地位和 RDB 文件的地位雷同,都是通过 dir 参数设置的
dir ./

# 同步策略
# appendfsync always 示意每次写入都执行 fsync,以保证数据同步到磁盘。appendfsync everysec #示意每秒执行一次 fsync,可能会导致失落这 1s 数据。# appendfsync no 示意不执行 fsync,由操作系统保证数据同步到磁盘,速度最快。# aof 重写期间是否同步, 默认 no 即可,保障数据安全
no-appendfsync-on-rewrite no

# 重写触发配置,设置重写的基准值
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载 aof 出错如何解决
aof-load-truncated yes

# RDB 和 AOF 的混合长久化
aof-use-rdb-preamble yes

# 文件重写策略
aof-rewrite-incremental-fsync yes

1、AOF 的实现

AOF 须要记录 Redis 的每个写命令,步骤为:命令追加(append)文件写入(write) 文件同步(sync)

命令追加(append)

开启 AOF 长久化性能后,服务器每执行一个写命令,都会把该命令 以协定格局 先追加到 aof_buf 缓存区的开端,而不是间接写入文件,防止每次有命令都间接写入硬盘,缩小硬盘 IO 次数

文件写入 (write) 和文件同步(sync)

对于何时把 aof_buf 缓冲区的内容写入保留在 AOF 文件中,Redis 提供了多种策略

  • appendfsync always:将 aof_buf 缓冲区的所有内容写入并同步到 AOF 文件,每个写命令都同步写入磁盘
  • appendfsync everysec:将 aof_buf 缓存区的内容写入 AOF 文件,每秒同步一次,该操作由一个线程专门负责
  • appendfsync no:将 aof_buf 缓存区的内容写入 AOF 文件,什么时候同步由操作系统来决定

appendfsync选项的默认配置为everysec,即每秒执行一次同步

对于 AOF 的同步策略是波及到操作系统的 write 函数和 fsync 函数的,在《Redis 设计与实现》中是这样阐明的

为了进步文件写入效率,在古代操作系统中,当用户调用 write 函数,将一些数据写入文件时,操作系统通常会将数据暂存到一个内存缓冲区里,当缓冲区的空间被填满或超过了指定时限后,才真正将缓冲区的数据写入到磁盘里。

这样的操作尽管进步了效率,但也为数据写入带来了平安问题:如果计算机停机,内存缓冲区中的数据会失落。为此,零碎提供了 fsyncfdatasync 同步函数,能够强制操作系统立即将缓冲区中的数据写入到硬盘里,从而确保写入数据的安全性。

从下面的介绍咱们晓得,咱们写入的数据,操作系统并不一定会马上同步到磁盘,所以 Redis 才提供了 appendfsync 的选项配置。

  • 当该选项时为 appendfsync always 时,数据安全性是最高的,然而会对磁盘进行大量的写入,Redis 解决命令的速度会受到磁盘性能的限度;
  • appendfsync everysec选项则兼顾了数据安全和写入性能,以每秒一次的频率同步 AOF 文件,即使呈现零碎解体,最多只会失落一秒内产生的数据;
  • 如果是 appendfsync no 选项,Redis 不会对 AOF 文件执行同步操作,而是有操作系统决定何时同步,不会对 Redis 的性能带来影响,但如果零碎解体,可能会失落不定数量的数据

2、AOF 重写

随着工夫的推移,Redis 执行的写命令会越来越多,AOF 文件也会越来越大,过大的 AOF 文件可能会对 Redis 服务器造成影响,如果应用 AOF 文件来进行数据还原所需工夫也会越长。因而为避免出现此种状况,新增了重写机制,当 AOF 文件的大小超过所设定的阈值时,Redis 就会启动 AOF 文件的内容压缩,只保留能够复原数据的最小指令集。

文件重写能够 主动触发 也能够 手动触发 执行bgrewriteaof 命令

主动触发会依据 auto-aof-rewrite-percentageauto-aof-rewrite-min-size 64mb配置来主动执行 bgrewriteaof 命令

# 示意当 AOF 文件的体积大于 64MB,且 AOF 文件的体积比上一次重写后的体积大了一倍(100%)时,会执行 `bgrewriteaof` 命令
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

手动触发执行 bgrewriteaof,该命令的执行跟bgsave 触发快照时相似的,都是先 fork 一个子过程做具体的工作

执行 bgrewriteaof 命令,重写的流程:

  • 重写会有大量的写入操作,所以服务器过程会 fork 一个子过程来创立一个新的 AOF 文件
  • 在重写期间,服务器过程持续解决命令申请,如果有写入的命令,追加到 aof_buf 的同时,还会追加到aof_rewrite_bufAOF 重写缓冲区
  • 当子过程实现重写之后,会给父过程一个信号,而后父过程会把 AOF 重写缓冲区的内容写进新的 AOF 临时文件中,再对新的 AOF 文件改名实现替换,这样能够保障新的 AOF 文件与以后数据库数据的一致性

3、Redis4.0 开始反对 RDB 和 AOF 的混合长久化

能够通过配置项 aof-use-rdb-preamble 开启,默认就是 yes 开启的

  • 如果是 redis 过程挂掉,那么重启 redis 过程即可,间接基于 AOF 日志文件复原数据
  • 如果是 redis 过程所在机器挂掉,那么重启机器后,尝试重启 redis 过程,尝试间接基于 AOF 日志文件进行数据恢复,如果 AOF 文件破损,那么用 redis-check-aof fix 命令修复
  • 如果没有 AOF 文件,会去加载 RDB 文件
  • 如果 redis 以后最新的 AOF 和 RDB 文件呈现了失落 / 损坏,那么能够尝试基于该机器上以后的某个最新的 RDB 数据正本进行数据恢复

4、优缺点

长处

  • 数据更残缺,安全性更高,秒级数据失落(取决 fsync 策略,如果是 everysec,最多失落 1 秒的数据)
  • AOF 文件是一个只进行追加的日志文件,且写入操作是以 Redis 协定的格局保留的,内容是可读的,适宜误删紧急复原

毛病

  • 对于雷同的数据集,AOF 文件的体积要大于 RDB 文件,数据恢复也慢于 rdb
  • 依据所应用的 fsync 策略,AOF 的速度可能会慢于 RDB。

参考:

1、https://juejin.im/post/684490… Redis 长久化机制:RDB 和 AOF TurboSnail

正文完
 0