【Redis19】Redis进阶:持久化策略

这篇具有很好参考价值的文章主要介绍了【Redis19】Redis进阶:持久化策略。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Redis进阶:持久化策略

从最早接触 Redis 开始,我们就知道它是一个内存数据库,这是它的优势,也是它的劣势。为啥这么说呢?内存速度快,但是断电或者重启即丢。然而,要做为一个生产环境所能使用的数据库系统,将数据持久化就成为了一个必要的能力。毕竟我们可不想重启 Redis 之后,每个生产缓存都要从头重建一遍,最好是重启的时候直接就帮我们将之前已经保存的数据重新加载进来。这就是 Redis 持久化要干的事。

在 Redis 中,提供了两种持久化方案,一个叫 RDB ,一个叫 AOF 。

RDB

其实之前在基础相关的命令学习中,我们就已经接触过一点相关的知识了,比如说 SAVE 这个命令。当时我们测试的时候,在客户端执行 SAVE 马上就会把当前系统中的数据保存到一个 dump.rdb 的文件中。这个文件会保存在配置文件 dir 属性所配置的目录中。比如在我的电脑上是 dir "/usr/local/var/db/redis"这个目录。

➜  redis ll /usr/local/var/db/redis/dump.rdb
-rw-r--r--  1 zhangyue  admin   103B  6 13 12:52 /usr/local/var/db/redis/dump.rdb

同时,这个文件名也是可以修改的,在配置文件中的 dbfilename "dump.rdb" 就是用于修改 RDB 持久化的文件名。这个文件如果你直接打开,会是乱码的,也就是说,Redis 在对 RDB 进行持久化的时候进行了压缩编码(LZF压缩 rdbcompression 配置可以设置成不压缩)。这两个配置是可以通过 CONFIG SET 动态修改的,比如说磁盘满了或者有问题了,可以马上加一块新硬盘,然后动态修改,下次持久化时就会将数据保存到新修改的路径或文件名上了。RDB 的特点主要是:

  • RDB 的持久化是保存整个实例中所有的数据,如果我们的程序运行时间比较长,承担的业务也比较重的话,原样保存出来的文件就会非常大。因此,RDB 在保存的时候会进行压缩编码。

  • RDB 文件是一个单一的并且非常紧凑的文件,因此,它很好备份,拷贝走就好啦!同样的,相比于 AOF 来说,RDB 的恢复速度也更快一些。

  • RDB 在保存文件时会通过 Redis 实例 fork 出一个子进程来进行,是异步的,对应的是我们之前学习过的 BGSAVE 这个命令。如果我们在命令行使用 SAVE 命令,那么会产生阻塞,因此,最好不要直接使用 SAVE 命令,使用 BGSAVE 命令或者通过配置文件让应用实例自动备份就好了。

  • 在主从架构中,RDB 可以支持重新启动和故障切换后的部分重新同步。

有经验的小伙伴一定发现了,这货不就是 全量备份 嘛,或者换个更通俗点的名词 快照(snapshotting) 。既然是这样,那么全量备份的一些问题它也有。比如说:

  • 频繁的 fork 子进程,特别是数据量比较大的时候,fork 过程也是非常耗时的。虽说是一个子进程,但不可避免的也会对主进程产生影响,毕竟会抢占 CPU 时间。

  • 由上,包括 MySQL 也是类似的,我们不会一直总是做全量备份,往往是在一定的时间间隔内进行全量备份。而在时间间隔的中间如果发生了意外情况导致服务宕机的话,这中间的数据是会丢失的。

幸好,AOF 就是来弥补它的这两个问题的。下一小节我们再讲 AOF ,先来看看默认的 RDB 配置是怎样的,我们可以如何修改。

RDB 配置

在默认的配置文件中,你可以找到下面这样的配置信息。

save 3600 1
save 300 100
save 60 10000

这是啥意思,怎么有三条配置?这些数字又是啥意思?咱们一个一个来看。

save 时间 改动型命令执行次数

看到这个注释就好理解了吧,在多长时间内,执行了多少命令,就执行一次 BGSAVE 保存 RDB 文件。注意,这个执行的命令一定是改动了数据的命令,比如 SET ,而 GET 这类的命令是不算在内的。为啥呢?查询类的命令没啥可保存的必要呀,我们要保存的是存在的数据以及被改动的数据。

然后,上面写了三条,就是这三条规则有一条触发了就会进行 RDB 持久化操作。

  • save 3600 1:表示1小时内有1条改动命令

  • save 300 100:表示300秒内有100条改动命令

  • save 60 10000:表示60秒内有10000条改动命令

好吧,来试试。现在新加一条规则,60秒内有1条命令就保存,然后重启 Redis 实例。现在去 SET 一条测试数据,看看 dump.rdb 文件有没有变化。

注意,CONFIG SET 是不能动态修改 save 配置的。要关闭 RDB 机制应该怎么配置呢?直接 save "" 就可以啦。

AOF

Append-only file ,这是 AOF 的全称,意思也很明显,只追加操作到文件去。也就是说,它会将 SET 之类的命令追加到一个文件的末尾,然后重启实例的时候,重放这个文件中的命令就可以了。

之前其实我们也已经用过了,直接在配置文件中打开 appendonly 并设置为 yes 就启用 AOF 功能了,不过默认情况下,它是关闭的。我们也可以通过 appendfilename "appendonly.aof" 来设置文件的名称,使用的路径也是 dir 的路径,所以一般情况下,这个文件会和 dump.rdb 文件放在一起。

开启之后,我们可以直接打开这个文件看看,它的内容是我们可以看懂的哦。

➜  redis redis-cli
127.0.0.1:6379> set bb 123123
OK
127.0.0.1:6379> lpush list 1 2 3 4 5
(integer) 5

先执行两条命令,然后查看 appendonly.aof 文件。

➜  redis vim /usr/local/etc/redis.conf
REDIS0009ú      redis-ver^E6.2.6ú
redis-bitsÀ@ú^EctimeÂìú§bú^Hused-mem°8^Q^@ú^Laof-preambleÀ^Aþ^@û^C^@^NÀ^A^A^Q^Q^@^@^@^N^@^@^@^C^@^@õ^Bô^Bóÿ^@^BaaÂóà^A^@^@^AbÁÞ^@ÿd´^\åØ^ßX*2^M
$6^M
SELECT^M
$1^M
0^M
*3^M
$3^M
set^M
$2^M
bb^M
$6^M
123123^M
*7^M
$5^M
lpush^M
$4^M
list^M
$1^M
1^M
$1^M
2^M
$1^M

上面乱码的不用管,我们后面再说,先看下面的。我们可以看到 set 、lpush 之类的内容,上面的数字表示执行的命令的字符长度。接着就是命令的参数,同样也是一个字符长度加上一个实际的值。这个就是 AOF 生成的持久化文件的内容。

上面的一堆乱码是啥呢?咱们先来说说这个。

AOF 重写

从上面的例子中可以看出,AOF 是原样保存数据的,这样会有一个问题那就是无用命令的增多。比如说多次执行 INCR ,但最后我们需要的其实是最后那次 INCR 的数据,在回放数据的时候其实只要 SET 到最后一次 INCR 的值就好了。

➜  redis redis-cli
127.0.0.1:6379> INCR cc
(integer) 1
127.0.0.1:6379> INCR cc
(integer) 2
127.0.0.1:6379> INCR cc
(integer) 3
127.0.0.1:6379> INCR cc
(integer) 4
127.0.0.1:6379>

// appendonly.aof
$4^M
INCR^M
$2^M
cc^M
*2^M
$4^M
INCR^M
$2^M
cc^M
*2^M
$4^M
INCR^M
$2^M
cc^M
*2^M
$4^M
INCR^M
$2^M
cc^M

现在使用 BGREWRITEAOF 命令,执行 AOF 文件重写,你就会发现上面的 INCR 命令合并成了一个 SET 命令。

// appendonly.aof
SET
$2
cc
$1
4

是不是好很多了?不够不够,要知道,AOF 一般是做增量备份的,数据增加是很快的,能不能再压缩一些呢?这时你应该想到 RDB 的压缩格式了吧,去配置文件开启 aof-use-rdb-preamble yes ,启用 RDB+AOF 的混合模式,这时再执行 BGREWRITEAOF ,你就会发现数据被压缩成了和 RDB 一样的格式,体积再进一步缩小,恢复时的执行速度也更快了。

BGREWRITEAOF 对应的自动重写配置也在配置文件中。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

下面的 64mb 表示第一次 aof 文件重写的基准大小,上面的 100 表示的是当前日志文件与 64mb 这个基准进行比较的百分比。当文件达到了这个百分比后,自动进行重写,也就是文件到达 128mb 的时候进行重写。之后的重写就不会依赖于 64mb 这个数值了,而是变成一个动态值将当前压缩后的大小保存到实例中,下次只要超过这个值的 1 倍,就会再次进行重写。如果把百分比设置为 0 ,则相当于关闭了重写的机制。

AOF 写入时机

上面 RDB 的写入时机是多选的,默认三种情况下有一个触发就会写入。而 AOF 则只能配置一种,它的配置项是这样的。

# appendfsync always
appendfsync everysec
# appendfsync no

很明显,默认情况下是每秒写入,always 是一直写入,也就是只要有一个修改类的命令出现,马上就进行写入,一直有磁盘操作,大家就能想到,它多少会拖慢速度,但很安全,因为数据基本不会丢。最后一个是不直接写入,先把日志写到内存缓冲区,然后由操作系统决定何时将缓冲区内容写回磁盘。

不用多说了吧,always 会很耗性能,no 的主动权不在 Redis 手中但性能最好。所以,一般情况下走默认的就好了,但是,注意,这1秒内如果执行了命令,但 AOF 还没有自动写入就出问题崩溃了,这时的数据也会丢失的。

AOF 重写工作原理

和 RDB 一样,好像上面 RDB 的写入过程也没细说,那就一起说吧。它们俩都是使用的写时复制这种技术。都是 fork 子进程,将新的 AOF 内容写入临时文件。在写入时,父进程对新来的命令写入到缓存。当重写工作完成后,临时文件替换成正式文件,子进程向父进程发送信号,然后父进程将缓存中的数据写入到新的 AOF 文件。

AOF 的优劣

对于 AOF 的优劣来说,很明显就是和 RDB 的对比,相对于 RDB 来说,AOF 可以:

  • 更加安全,可以使用不同的策略,默认就是按秒的,要丢也是丢一秒内的数据

  • 只追加文件,没有别的操作,速度比较快

  • 自动重写 AOF 文件,优化文件体积

  • 保证有序写入,未重写前的数据是人类可读的

当然,它也会带来一些问题。

  • 一般来说,AOF 的文件大小会大于 RDB

  • 虽然写入文件的速度很快,但是,在巨量写入的情况下,肯定还是不如 RDB ,特别是设置 always 之后

  • 如果在重写过程中有新的写入,AOF 可能会使用大量内存,并且这些新的写入命令会被写入磁盘两次

  • awlays 会阻塞主进程不是异步的,而每秒 fsync 虽说是异步线程,但如果数据量非常大,会阻塞 fsync 子线程进而影响主线程,因此,AOF 总体来说是有阻塞问题的

用哪个?

这个嘛,要看具体的业务情况咯。如果说你想要可以媲美关系型数据库的存储安全性,那就把 AOF 和 RDB 都打开。不过官方更推荐的是,如果你只是将 Redis 当做缓存工具的话,那就都不要开。

当然,这是两种极端情况,大部业务场景下,其实我们保持默认,也就是 RDB 的默认持久化规则就好了。

另外,在服务实例启动的时候,如果开启了 AOF ,则优先根据 AOF 来进行数据还原。AOF 的优先级是要高于 RDB 的,毕竟它更安全,记录的数据更全面一些。

备份策略

对于 Redis 的这两个文件来说,备份相当的简单。为啥这么说呢?因为这两个文件即使在服务运行期间也是可以直接复制剪切走的。换句话说,你拿宝塔做个定时任务去备份这俩文件,然后再发送走就好了,本地硬盘存储也行,邮件也行,网盘也行,其它服务器直接 scp 也行,总之非常简单。

要还原的话,直接拷贝回配置文件中 dir 指定的目录位置就好了。

RDB 和 AOF 修复工具

根据上面的内容,我们知道 AOF 和 RDB 文件都是可以直接拷贝、删除、修改的,那么这两个文件就很容易就会不小心被修改或者篡改。于是,Redis 顺道便提供了两个修复工具。我们先拿 AOF 文件试试,直接乱写一些内容。

$3^M
setdfdfsdf^M
$3^M
ddd^M
$3^M
123^M

把 set 命令给随便加了些字符,这样的话如果重启服务,直接就会报出错误信息。

39166:M 15 Jun 2022 09:53:51.755 * Reading the remaining AOF tail...
39166:M 15 Jun 2022 09:53:51.755 # Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

从提示中就可以看出,它让我们尝试用修复工具去修复 AOF 文件。那么我们就来试试。

➜  redis redis-check-aof --fix appendonly.aof
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file --fix
[offset 26] AUX FIELD redis-ver = '6.2.6'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1655177336'
[offset 67] AUX FIELD used-mem = '1128240'
[offset 83] AUX FIELD aof-preamble = '1'
[offset 85] Selecting DB ID 0
[offset 103] Checksum OK
[offset 103] \o/ RDB looks OK! \o/
[info] 1 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble is OK, proceeding with AOF tail...
0x              86: Expected \r\n, got: 6466
AOF analyzed: size=164, ok_up_to=126, ok_up_to_line=8, diff=38
This will shrink the AOF from 164 bytes, with 38 bytes, to 126 bytes
Continue? [y/N]: y
Successfully truncated AOF

修复成功之后再看看,它会直接把我们刚刚乱改的命令给删掉,也就是无效的内容会被清理掉,保证其它数据的正常加载。(重启之后的实例中 ddd 这条数据也就没有了)

同样的,对于 RDB 文件来说,也有一个 redis-check-rdb 命令用于修复 RDB 文件,这个命令不需要使用参数,直接就可以对指定的文件进行修复。

Redis7 的变化

在 Reids7 中,AOF 产生了比较多的变化,来自官方文档,我这里没有安装 Redis7 所以没有进行详细的测试,大家可以了解下。

  • 采用多部分 AOF 机制,原始的单个 AOF 被分为一个基本文件和可能有多个的增量文件

  • 基本文件是重写 AOF 时存在的初始数据,也就是 RDB 那种格式的,增量文件包含上次创建基本文件以来的增量数据,它们会放在一个目录中并由另外一个清单文件来进行跟踪

  • 通过临时清单文件跟踪基本文件和增量文件,当它们就绪时,执行原子替换操作

  • 加入重写限制机制,确保重试失败的重写会产生过多的增量文件的问题

总结

这一把学完,相信你对 Redis 的持久化策略应该有了比较深入的印象了吧。还是那句话,大部分情况下,用默认的配置就好了,有特殊需求的时候,至少你得知道这两种策略可以应用在什么场景下。另外就是应付面试了,这些内容也是非常容易出现在面试题中的。

参考文档:

https://redis.io/docs/manual/persistence/文章来源地址https://www.toymoban.com/news/detail-437880.html

到了这里,关于【Redis19】Redis进阶:持久化策略的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Redis的三种持久化策略及选取建议

    Redis是一个基于内存的高性能的键值型数据库,它支持三种不同的持久化策略:RDB(快照)、AOF(追加文件)、混合。这三种策略各有优缺点,需要根据不同的场景和需求进行选择和配置。本文将介绍这三种策略 RDB 持久化策略是指在 一定的时间间隔内 ,将 Redis 内存中的数据

    2024年02月04日
    浏览(11)
  • 【Redis从入门到进阶】第 8 讲:Redis 持久化之 —— AOF

    【Redis从入门到进阶】第 8 讲:Redis 持久化之 —— AOF

    本文已收录于专栏 🍅《Redis从入门到进阶》🍅    本专栏开启,目的在于帮助大家更好的掌握学习 Redis ,同时也是为了记录我自己学习 Redis 的过程,将会从基础的数据类型开始记录,直到一些更多的应用,如缓存击穿还有分布式锁等。希望大家有问题也可以一起沟通,欢

    2023年04月25日
    浏览(10)
  • 【Java 进阶篇】Redis持久化之RDB:数据的安全守护者

    【Java 进阶篇】Redis持久化之RDB:数据的安全守护者

    Redis,作为一款高性能的键值存储系统,支持多种持久化方式,其中RDB(Redis DataBase)是其最常用的一种。RDB可以将当前时刻的数据快照保存到磁盘,以便在Redis重启时快速恢复数据。本文将深入探讨RDB的原理、配置和实际应用,帮助初学者更好地理解和使用Redis的持久化机制

    2024年02月05日
    浏览(12)
  • Redis追本溯源(三)内核:线程模型、网络IO模型、过期策略与淘汰机制、持久化

    Redis追本溯源(三)内核:线程模型、网络IO模型、过期策略与淘汰机制、持久化

    Redis在处理客户端请求时,通常使用单线程来进行读取、解析、执行和响应返回,因此被称为单线程应用。在4.0版本之前,这一描述是准确的。 单线程: 读取、解析、执行和响应返回。 从4.0版本开始,Redis开始使用后台线程来处理一些耗时的操作,如清理脏数据、释放超时连

    2024年02月15日
    浏览(16)
  • Redis(概述、应用场景、线程模式、数据持久化、数据一致、事务、集群、哨兵、key过期策略、缓存穿透、击穿、雪崩)

    Redis(概述、应用场景、线程模式、数据持久化、数据一致、事务、集群、哨兵、key过期策略、缓存穿透、击穿、雪崩)

    目录 Redis概述 应用场景 Redis的线程模式 数据持久化 1.Rdb(Redis DataBase) 2.Aof(Append Only File) mysql与redis保持数据一致 redis事务 主从复制(Redis集群) 哨兵模式 key过期策略 缓存穿透、击穿、雪崩 1.缓存穿透:缓存中没有,在mysql中也没有 2.缓存击穿:数据在数据库中存在,某个

    2024年01月16日
    浏览(18)
  • Redis两种持久化方案RDB持久化和AOF持久化

    Redis两种持久化方案RDB持久化和AOF持久化

    Redis持久化 Redis有两种持久化方案: RDB持久化 AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为RDB文件

    2024年02月14日
    浏览(13)
  • redis持久化【RDB+AOF】持久化双雄

    redis持久化【RDB+AOF】持久化双雄

    这是redis系列文章之《redis持久化【RDB+AOF】持久化双雄》,上一篇文章【redis基础】redis的十大数据类型_努力努力再努力mlx的博客-CSDN博客 感谢大家的支持~ 目录 RDB 什么是RDB RDB的作用 配置文件关于RDB部分  6vs7 操作步骤 修改配置文件(本案例设置5s修改2次) 修改dump文件的保

    2024年02月08日
    浏览(33)
  • 全面解析 Redis 持久化:RDB、AOF与混合持久化

    前言: 每次你在游戏中看到玩家排行榜,或者在音乐应用中浏览热门歌单,有没有想过这个排行榜是如何做到实时更新的?当然,依靠 Redis 即可做到。 在技术领域,我们经常听到 「键值存储」 这个词。但在 Redis 的世界里,这只是冰山一角。Redis 的对象,不仅仅是简单的数据

    2024年03月10日
    浏览(15)
  • 【Redis】Redis 持久化

    【Redis】Redis 持久化

    Redis有两种持久化方案: RDB持久化 AOF持久化 RDB 全称 Redis Database Backup file(Redis数据备份文件),也被叫做 Redis 数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为 RDB文件,默认是保存在当

    2024年02月05日
    浏览(14)
  • Redis系列--redis持久化

    Redis系列--redis持久化

    redis本身运行时数据保存在内存中,如果不进行持久化,那么在redis出现非正常原因宕机或者关闭redis的进程或者关闭计算机后数据肯定被会操作系统从内存中清掉。当然,redis本身默认采用了一种持久化方式,即RDB (Redis DataBase),可以在redis的目录中找到dump.rdb文件,这就是

    2024年02月05日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包