写于:2019-05-20 22:05:30

Redis 中文网

Redis 英文网

# Introduce

Redis 是一款支持数据持久化的缓存中间件,在提供强大性能的同时支持数据持久化到内存。在人为的重启,或者服务宕机重启能够保证数据的恢复。这也使得 Redis 的应用个场景变得更加丰富。

Redis 有两种持久化方式

  • RDB
  • AOF。

其中 RDB 为默认持久化方式。

# RDB

触发 RDB 持久化数据有三种方式

  • 满足指定条件主动触发
  • 命令行手动触发
  • 被动触发

# 自动触发

Redis 默认采用的 RDB 持久化方案, 在配置文件 redis.conf 中 默认持久化配置如下


## save <seconds> <changes>
save 900 1   ## 在 900 s 内发生 1次修改,触发RDB操作,将DB数据刷入磁盘中
save 300 10  ## 在 300 s 内放生 10次修改,触发RDB操作,将DB数据刷入磁盘中
save 60 10000 ## 在 60 s 内放生 10000 次修改,触发 RDB 操作,将 DB 数据刷入磁盘中

自动触发 RDB 持久化方式:通过 指定的时间间隔 在满足配置的条件时,对 redis 内存中的数据进行快照操作并存储到 指定的磁盘路径中

Q1、如何进行 rdb 持久化策略的配置?

通过新增 save 策略,修改 save 策略,删除 save 策略,进行持久化策略配置。

Q2、如何关闭 rdb 持久化?

注释,或者删除所有 save 配置,相当于关闭 rdb 持久化。

# 手动触发

除了配置文件自动触发 RDB 持久化。

还可以通过命令行的方式手动触发 RDB 持久化。

  • 客户端执行命令、save
  • 客户端执行命令、bgsave

# 对比 save 和 bgsave

save 在执行的过程中,会把 Redis 阻塞,直到 RDB 持久化完成。在这个过程中 Redis 无法对外提供服务。

bgsave 在执行的过程中,由主进程 fork 操作创建子进程,由子进程进行持久化操作。除了在 fork 的时候 Redis 阻塞了一会儿,其他的操作都是在子进程中执行,不会影响 Redis 正常提供服务。

# 被动触发

除以上两种触发方式,RDB 持久化的触发方式还有被动触发的方式。

1、在主从架构中,从节点进行全量复制的时候,主节点会执行 bgsave 进行 RDB 持久化。

2、客户端执行命令 debug reload ,会触发 save 操作,进行 RDB 持久化。

3、客户端执行命令 shutdown ,当 redia 没有开启 aof ,并且 redis.conf 中配置有 save(相当于开启 rdb 持久化),会执行 bgsave 进行 RDB 持久化

# RDB 工作流程总结

RDB 持久化使用的是 save 或者 bgsave 进行持久化操作。而 save 一般只有在 debug reload 等场景,需要阻塞 Redis 服务保证持久化时,数据不会再被写入等场景会被使用到。大部分的场景为了保证 Redis 的高可用,都是使用的 bgsave。下面以 bgsave 为例简单的来看看 RDB 工作流程。

如图:触发 bgsave 命令,Redis 主进程 调用 fork 操作创建子进程。 子进程写数据到临时RDB文件中。

临时RDB文件写完成后,临时RDB文件覆盖并删除磁盘原有的RDB文件。

# 扩展:RDB 其他配置

## bgsave 执行失败无法进行RDB持久化 (yes 开启,no 关闭)
stop-writes-on-bgsave-error yes
## 持久化文件磁盘中前进行压缩,默认ZLF压缩。(yes 开启,no 关闭) 
rdbcompression yes
## 校验rdb文件
rdbchecksum yes
## rdb 文件名称
dbfilename dump.rdb
## rdb 存放路径
dir ./

# AOF

AOF 全称 append only file。AOF 原理和他的命名一样,以追加的方式,将 Redis 的每一条操作指令追加到指定的文件,并保存到磁盘中。

开启 AOF 有两种方式

  • 配置 redis.conf 文件
  • 动态开启

# AOF 开启方式

# 配置 redis.conf 文件

AOF 默认没有开启,可以通过配置 redis.conf 文件进行开启

 # 开启 AOF 默认:关闭
appendonly yes

通过配置的方式,即使服务重启,配置仍然有效

# 动态开启

可以通过命令 config set appendonly yes 动态开启 AOF。

命令行动态开启的方式在服务重启后失效,重启后只会以 redis.confg 中的配置为主。

# AOF 工作流程

Redis 客户端进行数据指令操作,同时指令操作会写入到 AOF 缓冲区中。 此时 数据仍然在缓冲区中未刷入本地磁盘的 AOF 文件中。 根据 AOF 策略,触发策略将AOF缓冲区的数据刷入本地磁盘 AOF 文件中进行持久化。 在持久化的时候,当 AOF 文件达到了指定的条件,会进行rewrite优化 AOF 文件,减少 AOF 文件大小。

该流程中有两个重要的点:

  • 1、AOF 缓冲什么时候持久化到AOF磁盘中
  • 2、AOF 进行 rewrite 的条件

下面针对这两点来聊一聊

# AOF 缓冲区数据刷入 本地磁盘 AOF 文件的策略

先来看看该策略在 redis.conf 中如何配置。

# appendfsync alway
# appendfsync no
appendfsync everysec

Redis 针对 AOF 缓冲区数据如何刷入磁盘进行持久化定义了3种策略:

  • alway fsync after every write to the append only log. Slow, Safest Redis 一次数据操作到 AOF 缓冲区中,就马上将缓冲区数据同步到本地磁盘 AOF 文件中。 优点:每一次数据操作都会马上同步到本地磁盘中,保证了数据的完整性。 缺点:该模式会导致Redis性能严重下降,这样做失去了我们使用 Redis 的初衷。 建议:不推荐使用该模式,Redis 性能严重下降。违背了我们使用 Redis 提供高并发,高性能的初衷。

  • no don't fsync, just let the OS flush the data when it wants. Faster. Redis 实例不进行 AOF 缓冲区数据到本地磁盘的同步操作,直接将该操作交给系统来进行。 优点:由于 Redis 较少了 fsync 的操作,能够使得 Redis 的性能得到一定的提高 缺点:AOF 缓冲数据的持久化完全交由操作系统来执行,我们无法控制该操作何时执行。 建议:如果对于数据的持久化无所谓,可以使用该模式。但是一般情况下不建议使用。

  • everysec fsync only one time every second. Compromise. Redis 实例每秒执行一次 AOF缓冲区数据持久化到 AOF 的操作。 always 能够保证数据的完全完整,但是使得 Redis 性能严重下降。no 能够是的 Redis 的性能得到提升,但是无法保证数据的完整性,而且是不可控的。 everysec 可以说是一种折中的策略。每秒进行一次持久化,保证了 Redis 的部分性能,同时保证最多丢失 1s 的数据。 建议:一般都是开启该模式。在保证性能的同时保证数据的相对完整。

# AOF 进行 rewrite,优化 AOF 文件大小

前面提到 AOF 是通过记录一条一条的操作指令来实现持久化的。而在 Redis 数据操作中,比如 set name WTF;set name Where_the_food;针对同一个key,进行了两次操作,而AOF 文件中,同样会记录有相同的两条操作记录,而 rewrite 就是将这类语句进行优化,保留最后一次有效的操作指令即可,以此达到 AOF 文件瘦身的目的。

AOF 触发 rewrite 有两种方式:

  • 通过配置文件的方式进行 rewrite 条件的设定

    ## 当前 AOF 文件 对比 上一次 AOF 文件 的增长比例,如:默认 100 ,表示 当前 AOF 文件对比上次 AOF 文件大小增长了一倍,触发 rewrite。
    auto-aof-rewrite-percentage 100
    ## 当 AOF 文件大小达到 64mb 进行一次 rewrite
    auto-aof-rewrite-min-size 64mb
    
  • 通过客户端命令行执行 BGREWRITEAOF 命令,触发 AOF rewrite 操作。

# 扩展:AOF 其他配置

## AOF 持久化文件名
appendfilename "appendonly.aof"

## AOF 文件重写的时候,不进行 aof 同步操作 (yes 开启,no 关闭:默认 :关闭)
no-appendfsync-on-rewrite no

## 数据回复时,出错进行 log ,然后继续执行恢复操作
aof-load-truncated yes

## 4.0 开始支持,aof rdb 混合持久化模型
aof-use-rdb-preamble no

# AOF 和 RDB

  • 对比 AOF 和 RDB 数据完整性 在 AOF 配置为 everysec 时,AOF 数据丢失只会丢失 1s。数据相对较完整。 RDB 数据的丢失根据 save 的配置,成周期的丢失。数据相对较不完整。

  • 对比 AOF 和 RDB 数据恢复 AOF 数据恢复需要一条条的执行 AOF 文件中的指令进行数据恢复,相对较慢。 RDB 文件中存储的是 Redis 的数据快照,所以数据恢复速度较快。

  • AOF 和 RDB 同时开启 1、如果 AOF 和 RDB 同时开启,重启数据恢复默认使用 AOF 进行数据恢复(AOF数据较 RDB完整)。 2、如果 AOF 和 RDB 同时开启,为了防止 Redis 对磁盘进行大量的 I/O 操作,bgsave 和 bagwriteaof 不能同时执行。在一个时间点,只能有一个在执行。

# AOF 和 RDB 如何选择

Redis 持久化的选择,也是选择。在成年人的世界里,从来没有选择2字,全部都要。 这不是我花心,Redis 官网也提出来了,

The general indication is that you should use both persistence methods if you want a degree of data safety comparable to what PostgreSQL can provide you.

官方提到了,要达到 postgreSQL 一样的数据安全性,最好两种持久化都要开启。

精彩内容推送,请关注公众号!
最近更新时间: 4/27/2020, 7:04:43 AM