redis持久化AOF和RDB的区别及解决各个场景问题示例

 更新时间:2023年08月24日 10:39:56   作者:jacheut  
这篇文章主要为大家介绍了redis持久化AOF和RDB的区别及解决各个场景问题示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

什么是Redis持久化?

redis是一种内存数据库。持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

Redis提供了两种持久化策略: RDB(默认) 和AOF 。

RDB是指在指定的时间间隔内,把内存中的数据集快照写入磁盘。也就是只保留某个时间点的数据。
而AOF持久化会记录服务器接收的所有写操作命令,并且把这些命令追加到一个文件里面,持久化到磁盘上,在服务器启动的时候,通过重新执行这些命令来还原数据。

RDB快照

rdb是Redis DataBase缩写。

功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数。

RBD持久化通过保存数据库中的键值对来记录数据库状态。

RBD配置文件的开启

save 900 1      // 900s内,有1条写入,则产生快照
save 300 1000   // 如果300秒内有1000次写入,则产生快照
save 60 10000  // 如果60秒内有10000次写入,则产生快照
(这3个选项都屏蔽,则rdb禁用)
stop-writes-on-bgsave-error yes  // 后台备份进程出错时,主进程是否停止写入
rdbcompression yes    // 导出的rdb文件是否压缩。建议没有必要开启,毕竟Redis本身就属于CPU密集型服务器,再开启压缩会带来更多的CPU消耗,相比硬盘成本,CPU更值钱。
rdbchecksum   yes //  导入rbd恢复数据时,是否验证rdb的完整性
dbfilename dump.rdb  //导出来的rdb文件名
dir ./  //rdb的放置路径

RDB原理

针对RDB方式的持久化,手动触发可以使用:

save:会阻塞当前Redis服务器,直到持久化完成,线上应该禁止使用。

bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。

而自动触发的场景主要是有以下几点:

  • 根据我们的 save m n 配置规则自动触发;
  • 从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 bgsave;
  • 执行 debug reload 时;
  • 执行 shutdown时,如果没有开启aof,也会触发。

由于 save 基本不会被使用到,我们重点看看 bgsave 这个命令是如何完成RDB的持久化的。

这里注意的是 fork 操作会阻塞,导致Redis读写性能下降。我们可以控制单个Redis实例的最大内存,来尽可能降低Redis在fork时的事件消耗。以及上面提到的自动触发的频率减少fork次数,或者使用手动触发,根据自己的机制来完成持久化。

BGSAVE命令执行时的服务器状态

首先,在BGSAVE命令执行期间,客户端发送的SAVE命令会被服务器拒绝,服务器禁止SAVE命令和BGSAVE命令同时执行是为了避免父进程(服务器进程)和子进程同时执行两个rdbSave调用,防止产生竞争条件。

其次,在BGSAVE命令执行期间,客户端发送的BGSAVE命令会被服务器拒绝,因为同时执行两个BGSAVE命令也会产生竞争条件。

最后, BGREWRITEAOF和BGSAVE两个命令不能同时执行:

  • 如果BGSAVE命令正在执行,那么客户端发送的BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行。
  • 如果BGREWRITEAOF命令正在执行,那么客户端发送的BGSAVE命令会被服务器拒绝。

因为BGREWRITEAOF和BGSAVE两个命令的实际工作都由子进程执行,所以这两个命令在操作方面并没有什么冲突的地方,不能同时执行它们只是一个性能方面的考虑-并
发出两个子进程,并且这两个子进程都同时执行大量的磁盘写入操作,这怎么想都不会是一个好主意。

AOF

Aof是Append-only file缩写。

AOF持久化通过保存redis服务器所执行的写命令来记录数据库状态。

AOF持久化的实现:

AOF持久化可分为命令追加、文件写入、文件同步三个步骤。

从持久化中恢复数据

RDB文件的载入工作是在服务器启动时自动执行的,所以Redis并没有专门用于载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入RDB文件。

服务器在载入RDB文件期间,会一直处于阻塞状态 ,直到载入完成。

另外值得一提的是,因为AOF文件的更新频率通常比RDB文件的更新频率高, 保存的数据更完整,AOF基本上最多损失1s的数据。所以:

  • 如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据阵状态。
  • 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。

每当执行服务器(定时)任务或者函数时flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作
aof写入保存:

WRITE:根据条件,将 aof\_buf 中的缓存写入到 AOF 文件

SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

那么这里为什么要先写入buf在同步到磁盘呢?如果实时写入磁盘会带来非常高的磁盘IO,影响整体性能。

aof重写是为了减少aof文件的大小,可以手动或者自动触发

手动触发: bgrewriteaof,自动触发 就是根据配置规则来触发,当然自动触发的整体时间还跟Redis的定时任务频率有关系。

下面来看看重写的一个流程图:

对于上图有四个关键点补充一下:

  • 在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失。
  • 为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据。
  • 重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。
  • AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高可认为修改修复。
  • 不管是RDB还是AOF都是先写入一个临时文件,然后通过 rename 完成文件的替换工作。

Aof 的配置

appendonly no # 是否打开 aof日志功能
# 文件名称
appendfilename "appendonly.aof"
appendfsync always   # 每1个命令,都立即同步到aof. 安全,速度慢
#appendfsync everysec # 折衷方案,每秒写1次
#appendfsync no      # 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof. 同步频率低,速度快,
no-appendfsync-on-rewrite  yes: # 正在导出rdb快照的过程中,是否停止同步aof
auto-aof-rewrite-percentage 100 #aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb #aof文件,至少超过64M时,才重写

AOF和RDB比较

  • aof文件比rdb更新频率高,优先使用aof还原数据。—— 更加稳定,数据的完整性更好。
  • aof比rdb更安全也更大。—— 记录了每一个写操作,但是随着文件越来越大,可能会影响到redis的写性能。
  • rdb性能比aof好:恢复大数据集的速度比AOF快,对CPU和内存的影响比较小。更加适用于需要做冷备份或者对数据恢复要求不高的场景,因为它是间隔一段时间进行持久化。如果在这个时间断内发生宕机,那么这些数据就会丢失。
  • 如果两个都配了优先加载AOF。
  • AOF适用于对数据安全性较高的场景,比如购物车/订单等关键性业务。

定时任务执行的频率可以在配置文件中通过 hz 10 来设置(这个配置表示1s内执行10次,也就是每100ms触发一次定时任务)。该值最大能够设置为:500,但是不建议超过:100,因为值越大说明执行频率越频繁越高,这会带来CPU的更多消耗,从而影响主进程读写性能。
定时任务使用的是Redis自己实现的 TimeEvent,它会定时去调用一些命令完成定时任务,这些任务可能会阻塞主进程导致Redis性能下降。因此我们在配置Redis时,一定要整体考虑一些会触发定时任务的配置,根据实际情况进行调整。

以上就是redis持久化AOF和RDB的区别及解决各个场景问题示例的详细内容,更多关于redis持久化AOF RDB的资料请关注脚本之家其它相关文章!

相关文章

  • redis不能访问本机真实ip地址的解决方案

    redis不能访问本机真实ip地址的解决方案

    这篇文章主要介绍了redis不能访问本机真实ip地址的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Redis 单节点部署的实现

    Redis 单节点部署的实现

    本文主要介绍了Redis 单节点部署的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Redis实战之Lettuce的使用技巧详解

    Redis实战之Lettuce的使用技巧详解

    Lettuce 是 Redis 的一款高级 Java 客户端,与 Jedis 并列成为最热门的客户端之一,目前已成为 SpringBoot 2.0 版本默认的 redis 客户端。本文主要和大家讲讲Lettuce的使用技巧,感兴趣的可以了解一下
    2022-12-12
  • redis中数据类型命令整理

    redis中数据类型命令整理

    在本篇文章里小编给大家整理的是关于redis中5种数据类型基本命令介绍,需要的朋友们可以学习下。
    2020-03-03
  • 基于Redis位图实现用户签到功能

    基于Redis位图实现用户签到功能

    这篇文章主要介绍了基于Redis位图实现用户签到功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • 浅谈分布式锁的几种使用方式(redis、zookeeper、数据库)

    浅谈分布式锁的几种使用方式(redis、zookeeper、数据库)

    这篇文章主要介绍了浅谈分布式锁的几种使用方式(redis、zookeeper、数据库),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • Redis实战之Jedis使用技巧详解

    Redis实战之Jedis使用技巧详解

    Jedis 是老牌的 Redis 的 Java 客户端,提供了比较全面的 Redis 命令的操作支持,也是目前使用最广泛的客户端。这篇文章主要为大家详细介绍了Jedis的使用技巧,需要的可以参考一下
    2022-12-12
  • 使用拦截器+Redis实现接口幂思路详解

    使用拦截器+Redis实现接口幂思路详解

    这篇文章主要介绍了使用拦截器+Redis实现接口幂等,接口幂等有很多种实现方式,拦截器/AOP+Redis,拦截器/AOP+本地缓存等等,本文讲解一下通过拦截器+Redis实现幂等的方式,需要的朋友可以参考下
    2023-08-08
  • Redis中主键失效的原理及实现机制剖析

    Redis中主键失效的原理及实现机制剖析

    这篇文章主要介绍了Redis中主键失效的原理及实现机制剖析,本文讲解了失效时间的控制、失效的内部实现、Memcached 删除失效主键的方法与 Redis 有何异同、Redis 的主键失效机制会不会影响系统性能等内容,需要的朋友可以参考下
    2015-06-06
  • 详解如何发现并解决Redis热点Key问题

    详解如何发现并解决Redis热点Key问题

    Redis 热点 Key 是指在某一时间段内,被大量的读写操作命中的 Key,这种情况可能会导致性能瓶颈,数据一致性问题,缓存击穿等问题,所以本文给大家介绍了如何发现并解决Redis热点Key问题,需要的朋友可以参考下
    2024-05-05

最新评论