1. 持久化方式

Redis提供的数据持久化方式主要有2种:

RDB:产生一个数据快照文件

AOF:实时追加命令的日志文件

它们分别对应了不同的使用场景。

2. RDB介绍

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。可以通过执行save或bgsave命令让Redis在本地生成RDB快照文件,这个RDB文件包含了整个实例接近完整的数据内容。

它的优点如下:

  1. RDB文件数据是被压缩写入的,因此RDB文件的体积要比整个实例内存要小
  2. 当实例宕机恢复时,加载RDB文件的速度很快,能够在很短时间内迅速恢复文件中的数据

它的缺点也很明显:

  1. 由于是某一时刻的数据快照,因此它的数据并不全
  2. 生成RDB文件的代价是比较大的,它会消耗大量的CPU和内存资源

因此RDB比较适用于以下场景:

  1. 主从全量同步数据
  2. 数据库备份
  3. 对于丢失数据不敏感的业务场景,实例宕机后快速恢复数据

Redis主从全量同步数据就是使用RDB文件进行的,由此可以看出,RDB非常适合做数据备份,可以定时让Redis生成RDB文件,然后备份这个快照文件即可。

2.1. 定时生成RDB

Redis也提供了定时触发生成RDB文件的配置项:

# 最近15分钟内 至少产生1次写入
save 900 1
# 最近5分钟内 至少产生10次写入
save 300 10
# 最近1分钟内 至少产生10000次写入
save 60 10000

如果达到以上任意条件,则Redis会自动生成新的RDB文件,降低RDB数据内容与实例数据的差异。

2.2. Copy On Write

在Redis上执行save和bgsave命令都可以生成RDB文件,但前者是在前台执行的,也就是说在生成RDB文件时,会阻塞整个实例,在RDB未生成之前,任何请求都是无法处理的,对于内存很大的实例,生成RDB文件非常耗时,显然这是不能接受的。

所以通常会选择执行bgsave让Redis在后台生成RDB文件,这样Redis依旧可以处理客户端请求,不会阻塞整个实例。

但不是说后台生成RDB就是没有代价的,Redis为了实现后台把内存数据的快照写入文件,采用了操作系统提供的Copy On Write技术,也就是fork系统调用。

fork系统调用会产生一个子进程,它与父进程共享相同的内存地址空间,这样子进程在这一时刻就能拥有与父进程的相同的内存数据。

虽然子进程与父进程共享同一块内存地址空间,但在fork子进程时,操作系统需要拷贝父进程的内存页表给子进程,如果整个Redis实例内存占用很大,那么它的内存页表也会很大,在拷贝时就会比较耗时,同时这个过程会消耗大量的CPU资源。

在完成拷贝之前父进程也处于阻塞状态,无法处理客户端请求。

fork执行完之后,子进程就可以扫描自身所有的内存数据,然后把全部数据写入到RDB文件中。

之后父进程依旧处理客户端的请求,当在处理写命令时,父进程会重新分配新的内存地址空间,从操作系统申请新的内存使用,不再与子进程共享,这个过程就是Copy On Write(写实复制)名字的由来。

这样父子进程的内存就会逐渐分离,父进程申请新的内存空间并更改内存数据,子进程的内存数据不受影响。

由此可以看出,在生成RDB文件时,不仅消耗CPU资源,还有需要占用最多一倍的内存空间。

在Redis执行info命令,可以看到fork子进程的耗时,可以通过这个耗时来评估fork时间是否符合预期。

同时应保证Redis机器拥有足够的CPU和内存资源,并合理设置生成RDB的时机。

3. AOF介绍

AOF全称为Append Only File(追加日志文件)。它与RDB不同的是,AOF中记录的是每一个命令的详细信息,包括完整的命令类型、参数等。只要产生写命令,就会实时写入到AOF文件中。

可以通过配置文件开启AOF:


# 开启AOF
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# 文件刷盘方式
appendfsync everysec

3.1. 刷盘方式

开启AOF后,Redis会把每个写操作的命令记录到文件并持久化到磁盘中,为了保证数据文件的安全性,Redis还提供了文件刷盘的时机:


appendfsync always:每次写入都刷盘,对性能影响最大,占用磁盘IO比较高,数据安全性最高
appendfsync everysec:1秒刷一次盘,对性能影响相对较小,节点宕机时最多丢失1秒的数据
appendfsync no:按照操作系统的机制刷盘,对性能影响最小,数据安全性低,节点宕机丢失数据取决于操作系统刷盘机制


以上可以看出AOF相对于RDB的优点是:

  1. AOF数据文件更新比较及时,比RDB保存更完整的数据,这样在数据恢复时能够恢复尽量完整的数据,降低丢失数据的风险。
  2. 如果同时存在RDB文件和AOF文件,Redis会优先使用AOF文件进行数据恢复。

但它的缺点也很易见:

  1. 随着时间增长,AOF文件会越来越大
  2. AOF文件刷盘会增加磁盘IO的负担,可能影响Redis的性能(开启每秒刷盘时)

3.2. AOF重写

针对第一种情况,Redis提供了AOF瘦身的功能,可以设置在AOF文件很大时,自动触发AOF重写,Redis会扫描整个实例的数据,重新生成一个AOF文件达成瘦身的效果。但这个重写过程也需要消耗大量的CPU资源。

# AOF文件距离上次文件增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb

由于AOF可以最大可能降低丢失数据的风险,所以它一般适用于对丢失数据很敏感的业务场景,例如涉及金钱交易的业务。

3.3. 性能影响

如果AOF的刷盘时机设置为每次写入都刷盘,那么会大大降低Redis的写入性能,因为每次写命令都需要写入文件并刷到磁盘中才会返回,当写入量很大时,会增加磁盘IO的负担。

性能与数据安全不能兼得,虽然Redis提供了实时刷盘的机制,但是在真正场景中使用的不多。

通常我们会选择每秒刷盘这种方式,既能保证良好的写入性能,在实例宕机时最多丢失1秒的数据,做到性能和安全的平衡。

4. 总结

描述 RDB AOF
持久化方式 生成某一时刻的数据快照文件 实时记录每一个写命令到文件
数据完整性 不完整,取决于备份周期 相对完整性高,取决于文件刷盘方式
文件大小 压缩二进制写入,文件较小 原始的操作命令,文件大
宕机恢复时间
恢复优先级
持久化代价 高,消耗大量CPU和内存 低,只占用磁盘IO资源
使用场景 数据备份、主从全量复制、对丢数据不敏感的业务场景快速数据恢复 对于丢失数据敏感的场景,例如涉及金钱交易相关的业务

5. 高可用对比

描述   客户端分片 Codis  Tweproxy Redis Cluster
集群模式 无中心化 中心化 中心化 无中心化
使用方式 客户端编写路由规则代码,直连Redis 通过Proxy访问 通过Proxy访问 使用Smart Client直连Redis,Smart Client内置路由规则
性能 有性能损耗 有性能损耗
支持的数据库数量 多个 多个 多个 一个
Pipeline 支持 支持 支持 仅支持单个节点Pipeline,不支持跨节点
需升级客户端SDK?
支持在线水平扩容? 不支持 支持 不支持 支持
Redis版本 支持最新版 仅支持3.2.8,升级困难 支持最新版 支持最新版
可维护性 运维简单,开发人员使用成本高 组件较多,部署复杂 只有Proxy组件,部署简单 运维简单,官方持续维护
故障自动恢复 需部署哨兵 需部署哨兵 需部署哨兵 内置哨兵逻辑,无需额外部署





6. Redis 数据备份原理

RDB 持久化

RDB(Redis DataBase)持久化将 Redis 内存中的数据以快照形式保存到磁盘上。 适用于需要快速备份和恢复 Redis 数据库状态的场景,如数据迁移、备份和恢复。

优点:实现全量备份,数据恢复速度快。

缺点:可能会造成一定程度的数据丢失。

工作原理:通过 fork () 函数创建子进程,将数据库状态写入临时文件,然后替换原有 RDB 文件。

可以在 Redis 运行期间定期执行,也可以手动执行。

AOF 持久化

AOF(Append-Only File)持久化将所有写操作以追加方式记录到文件中。    适用于对数据完整性要求较高的场景,如实时性要求高的缓存场景。

优点:可以实现增量备份,保证数据的完整性。

缺点:数据恢复较慢,可能占用较多磁盘空间,影响 Redis 性能。

工作原理:记录 Redis 执行的每个写操作到 AOF 文件中,通过重放这些操作来恢复数据库状态。

6.1. RDB 备份和恢复

以下以集群模式部署的 Redis 为例,介绍 RDB 备份和恢复步骤。

Redis Cluster 备份

 1.生成备份文件:

 可以使用 redis-cli 手动执行 BGSAVE:

redis-cli -h <host> -p <port> -a <password> bgsave

 或在 redis.conf 中设置定期自动执行 BGSAVE:

save <seconds> <changes>

 2.收集备份文件:

  • 从每个 master 节点收集生成的 RDB 文件(dump.rdb)
  • 将文件保存在安全位置
注意:执行备份时,确保集群处于低负载状态,以免影响性能。 

Redis Cluster 恢复

1.停止每个节点的 Redis 服务:

systemctl stop redis

2.放置备份文件:

  • 将 RDB 文件复制到每个节点的 Redis 数据目录
  • 文件名应为 dump.rdb

2.修改 redis.conf 配置文件:

dbfilename dump.rdb
dir /AppHome/redis

4.启动每个节点的 Redis 服务:

systemctl start redis

5.验证数据恢复:

  • 使用 redis-cli 连接到 Redis Cluster
  • 检查数据是否存在并正确恢复

通过以上步骤可以成功地备份和恢复 Redis 集群中的数据。记得根据数据量大小预留足够的时间进行这些操作。 

  • 无标签
写评论...