Redis持久化策略详解

前言

Redis是基于内存的NoSQL数据库,但存储于内存的数据,会因为类似断电或者机器故障而导致内存数据丢失的问题。所以要将数据持久化存储到磁盘,以便Redis重启时,能够从磁盘中恢复原来的数据。

Redis持久化方式:

  1. 快照方式(RDB)Redis Database,在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。

  2. 文件追加方式(AOF)Append Only FIle,记录所有操作命令,并以文本形式追加到文件中。

  3. 混合持久化方式,Redis4.0之后新增的方式,结合了RDB和AOF的优势,先将数据以RDB的形式写入文件的开头,再将后续的操作命令以AOF的格式存入文件,既能保证Redis重启的速度,又能降低数据丢失的风险。

一、RDB(Redis Database)

1.1 概念

将某一时刻的内存快照(Snapshot)以二进制的方式写入磁盘的过程。

1.2 触发方式

1.手动触发RDB:

  • save命令:使Redis处于阻塞状态,直到RDB持久化完成,才会处理其他命令。
  • bgsave命令:会fork一个子进程执行持久化(只有在fork子进程时有短暂阻塞)当子进程创建成功,Redis主进程就可以处理其他请求。
    在这里插入图片描述

2.自动触发RDB:

  • save m n:在m秒内,有n个key发生改变,则触发持久化。Redis通过判断,满足触发条件,自动执行bgsave命令。当设置多个save m n时,满足任意一个,就会触发。

3.主从同步触发

  • 在Redis主从复制中,当从节点执行全量复制操作时,主节点会执行bgsave,并将RDB文件发送给从节点。

1.3 Fork 子进程

Redis使用操作系统的多进程 COW (Copy On Write )机制来实现快照持久化,防止单线程持久化阻塞客户端发送给过来的请求而影响Redis整体的系统性能。

Redis在持久化时会调用glib的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生时,它和父进程共享内存里面的代码段和数据段。这时你可以把父子进程想象成 个连体婴儿,它们在共享身体。这是Linux操作系统的机制,为了节约内存资源,所以尽可能让它们共享起来。在进程分离的瞬间,内存的增长几乎没有明显变化。

1.4 RDB持久化流程

在这里插入图片描述

二、AOF(Append Only File)

2.1 概念

把Redis的每个操作都以文件追加的方式记录到appendonly.aof文件中。

手动触发AOF命令:

bgrewriteaof

bgrewriteaof命令实现原理

  1. 在后台fork子进程执行文件重写操作。

  2. 遍历当前内存中数据集合,将写命令转换为新的写操作指令,生成一个新的AOF重写缓冲区。

  3. 将新的AOF重写缓冲区内容写入到临时文件中,形成新的AOF文件。

  4. 当重写完成,子进程通知主进程,将新的AOF文件重命名为原始的AOF文件名。

自动触发AOF:
需要满足AOF设置的策略触发和AOF重写触发。

flushall命令:
检查是否开启了AOF持久化,如果开启,Redis会在flushall之前,将AOF缓冲区中的指令写入到AOF文件中。flushall会对所有数据库执行flushdb命令,删除所有库中的所有数据。

2.2 AOF持久化策略

  1. always:每条操作都写入到磁盘,最多丢失一条数据

  2. everysec:每秒写入一次磁盘,最多丢失一秒数据

  3. no:不设置写入磁盘规则,根据当前操作系统决定何时写入磁盘(Linux默认30秒)

Redis 的配置文件(redis.conf)中设置

# 开启每秒写入一次的持久化策略
appendfsync everysec

2.3 AOF文件重写

为什么要重写?

  • AOF是通过记录Redis的执行命令持久化数据,所以AOF文件会越来越大,不仅增加了服务器的存储压力,也会造成Redis重启速度变慢,所以要重写AOF。

什么是重写?

  • 直接读取Redis服务器当前状态,压缩保存为AOF文件。例如,对数据进行了99次修改,如果不做重写,就会有100条记录执行命令的信息存入AOF文件;重写之后,只记录最终的操作信息,去除之前的无效信息。

2.4 触发条件

auto-aof-rewrite-min-size:允许AOF重写的最小文件容量,默认64MB。

auto-aof-rewrite-percentage:AOF文件重写的大小比例,默认值100(100%,当前AOF文件比上次的AOF文件大一倍时)

只有同时满足auto-aof-rewrite-min-size和auto-aof-rewrite-percentage的条件时,才会触发AOF重写。使用bgrewriteaof可自动触发AOF重写。

AOF文件重写原理

  1. Redis服务器创建一个新的AOF文件,代替现有的文件,新的AOF文件不会包含任何浪费空间的冗余命令。

  2. Redis会遍历当前内存中的数据集合,并将其中的写命令转换为一系列新的写操作指令。这些新的写操作指令可以是多个原始写操作指令的合并结果(多个 SET 指令可以合并为一个 MSET 指令,多个 LPUSH 指令可以合并为一个 RPUSH 指令等)

  3. 将这些写操作指令按照一定的格式写入到一个临时文件中,形成一个新的AOF缓冲区。

  4. 当遍历完整个数据集合后,Redis关闭旧的AOF文件,将新的AOF文件缓冲区内容写入到新的AOF文件中。

  5. 将新的AOF文件名重命名为旧的AOF文件名。

2.5 AOF配置说明

# 是否开启AOF,yes为开启,默认是关闭
appendonly no
 
# AOF默认文件名
appendfilename "appendonly.aof"
 
# AOF持久化策略配置
# appendfsync always
appendfsync everysec
# appendfsync no
 
# AOF文件重写的大小比例,默认值是100,表示100%,也就是只有当前AOF文件,比最后一次的AOF文件大一倍时,才会启动AOF文件重写。
auto-aof-rewrite-percentage 100
 
# 允许AOF重写的最小文件容量
auto-aof-rewrite-min-size 64mb
 
# 是否开启启动时加载AOF文件效验,默认值是yes,表示尽可能的加载AOF文件,忽略错误部分信息,并启动 Redis服务。
# 如果值为no,则表示,停止启动Redis,用户必须手动修复AOF文件才能正常启动Redis服务。
aof-load-truncated yes

三、混合持久化

3.1 概念

RDB可能会导致一段时间内数据丢失,AOF文件较大会影响Redis启动速度,为了解决该问题,Redis4.0新增了混合持久化。

开启混合持久化后,AOF重写时,会把Redis持久化数据,以RDB的格式写入到AOF文件开头,之后的数据再以AOF格式追加到文件末尾。

在这里插入图片描述

3.2 开启混合持久化

命令行开启(重启Redis失效)

config set aof-use-rdb-preamble yes

修改配置文件(重启Redis永久生效)

aof-use-rdb-preamble yes

数据恢复:把appendonly.aof放到Redis根目录,并开启AOF持久化,在Redis启动时,会自动加载并恢复数据。

3.3 加载流程

  1. 判断是否开启了AOF持久化,未开启加载RDB文件流程,开启继续执行后续流程。

  2. 判断appendonly.aof文件是否存在,存在继续执行后续流程。

  3. 判断AOF文件开头是RDB格式,先加载RDB内容再加载剩余AOF内容。

  4. 判断AOF文件开头不是RDB格式,直接以AOF格式加载文件。

在这里插入图片描述

Redis判断AOF文件的开头是否是RDB格式,通过关键字REDIS判断;是否是AOF格式,通过关键字*判断。

3.4 混合持久化优劣势

优势:

  1. 开头是RDB格式,Redis启动速度更快;结合了AOF,减低了数据丢失的风险。

劣势:

  1. AOF文件中添加了RDB格式内容,可读性变差。

  2. 兼容性差,如果开启混合持久化,那么该AOF文件,不能用在Redis4.0之前版本。

四、总结

4.1 RDB和AOF各自有什么优缺点?

RDB优点

  1. 只有一个紧凑的二进制文件dump.rdb,非常适合备份、全量复制的场景。
  2. 容灾性好,可以把RDB文件拷贝到远程机器或者文件系统,用于容灾恢复。
  3. 恢复速度快,RDB恢复数据的速度远远快于AOF的方式。

RDB缺点

  1. 实时性低,RDB是间隔一段时间进行持久化,没法做到实时持久化/秒级持久化。如果在这一间隔事件发生故障,数据会丢失。
  2. 需要fork子进程执行持久化操作,如果数据集很大,fork会很耗时,影响Redis的整体性能。

AOF优点

  1. 实时性好,保存的数据更完整,aof持久化可以配置appendfsync属性,有always,每进行一次命令操作就记录到aof文件中一次。
  2. 通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。

AOF缺点

  1. AOF文件比RDB文件大,且恢复速度慢。
  2. 数据集大的时候,比RDB启动效率低。

4.2 RDB和AOF如何选择?

  1. 一般来说, 如果想达到足以媲美数据库的数据安全性,应该同时使用两种持久化功能。在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
  2. 如果可以接受数分钟以内的数据丢失,那么可以只使用RDB持久化。
  3. 有很多用户都只使用AOF持久化,但并不推荐这种方式,因为定时生成RDB快照(snapshot)非常便于进行数据备份, 并且RDB恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使用RDB还可以避免AOF程序的Bug。
  4. 如果Redis只用缓存服务器,对数据库查询的数据做缓存,可以关闭持久化,因为缓存服务器失效,还能从数据库获取恢复。

4.3 持久化方案建议

本文介绍了Redis的三种持久化机制:RDB持久化、AOF持久化和混合持久化。 RDB持久化通过定期生成数据快照实现持久化,具有快速恢复和更小的存储空间等优点,但可能存在数据丢失和子进程占用内存等缺点。 AOF持久化通过记录所有写操作命令实现持久化,具有更高的数据安全性和更好的容错性等优点,但可能存在较大的存储空间和数据加载速度较慢等缺点。 混合持久化结合了RDB持久化和AOF持久化的优点,适用于对数据安全性和性能要求较高的场景。 在选择Redis持久化方案时,需要根据实际业务需求和场景权衡各个方案的优缺点。

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis持久化是为了避免进程退出导致数据的永久丢失而设计的。由于Redis是基于内存的数据库,数据存储在内存中,关闭服务或者断电会导致数据丢失。为了解决这个问题,Redis提供了两种持久化方式:AOF(Append Only File)和RDB(Redis Database File)。 AOF持久化是通过将写操作追加到AOF文件中来实现的。AOF文件是一个只追加的日志文件,记录了写操作的命令。当Redis重启时,Redis会根据AOF文件中的命令重新执行一遍,从而恢复数据。AOF文件的大小会随着写操作的增加而增大,因此可能会占用较大的磁盘空间。为了避免AOF文件过大,Redis提供了AOF重写机制,可以定期地将AOF文件重写为紧凑格式,只保留可以恢复数据库状态的最小命令集合。 RDB持久化是通过将当前数据库状态快照保存到一个二进制文件中来实现的。RDB文件是一个经过压缩的二进制文件,包含了数据库的数据和键值对的过期时间等信息。RDB持久化是通过fork子进程来实现的,它会将当前数据库状态保存到一个临时文件中,然后替换原来的RDB文件。RDB持久化适用于数据备份和灾难恢复。 除了持久化之外,Redis还支持快照机制。快照是将当前数据库状态保存到一个RDB文件中,可以手动触发或者通过配置选项定期触发。快照只保存了数据库的最新状态,而不是增量的写操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值