首页 > 数据库 >redis的rdb与aof

redis的rdb与aof

时间:2022-11-06 23:56:12浏览次数:40  
标签:aof 快照 fsync AOF redis rdb Redis 文件 RDB

Redis持久化提供了多种不同级别的持久化方式:

  • RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
  • AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。你甚至可以关闭持久化功能,让数据只在服务器运行时存在。

RDB 的优点:

  • RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适合用于备份。例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
  • RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心,或者是Amazon S3(可能得加密)。
  • RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。
  • RDB在重启保存了大数据集的实例时比AOF要快。

RDB 的缺点

  • 当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。
  • RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。

AOF 的优点:

  • 使用AOF Redis会更具有可持久性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。
  • AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。
    当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。
  • AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。

AOF 的缺点

  • 对同样的数据集,AOF文件通常要大于等价的RDB文件。
  • AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。

RDB 和 AOF ,我应该用哪一个?

一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。

如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也较之快,还避免了AOF引擎的bug。

注意:基于这些原因,将来我们可能会统一AOF和RDB为一种单一的持久化模型(长远计划)。

RDB 快照

默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。

例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:

save 60 1000

这种策略被称为快照。

快照的运作方式:

当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  • Redis 调用 fork() ,同时拥有父进程和子进程。
  • 子进程将数据集写入到一个临时 RDB 文件中。
  • 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
    这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。

只追加文件 AOF

快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。尽管对于某些程序来说, 数据的耐久性并不是最重要的考虑因素, 但是对于那些追求完全耐久能力(full durability)的程序来说, 快照功能就不太适用了。

从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。

你可以通过修改配置文件来打开 AOF 功能:

appendonly yes

从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

日志重写

你可以猜得到,写操作不断执行的时候AOF文件会越来越大。例如,如果你增加一个计数器100次,你的数据集里只会有一个键存储这最终值,但是却有100条记录在AOF中。其中99条记录在重建当前状态时是不需要的。

于是Redis支持一个有趣的特性:在后台重建AOF而不影响服务客户端。每当你发送BGREWRITEAOF时,Redis将会写入一个新的AOF文件,包含重建当前内存中数据集所需的最短命令序列。如果你使用的是Redis 2.2的AOF,你需要不时的运行BGREWRITEAOF命令。Redis 2.4可以自动触发日志重写(查看Redis 2.4中的示例配置文件以获得更多信息)。

AOF持久性如何?

你可以配置 Redis 多久才将数据 fsync 到磁盘一次。有三个选项:

  • 每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
  • 每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
  • 从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
    推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。 总是(每次) fsync 的策略在实际使用中非常慢, 即使在 Redis 2.0 对相关的程序进行了改进之后仍是如此,频繁调用 fsync 注定了这种策略不可能快得起来。

如果 AOF 文件出错了,怎么办?

服务器可能在程序正在对 AOF 文件进行写入时崩溃(这个不应该破坏数据的一致性), Redis不会装载已破坏的AOF文件。当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:

为现有的 AOF 文件创建一个备份。
使用 Redis 附带的 redis-check-aof 程序,对原来的 AOF 文件进行修复。
$ redis-check-aof --fix
(可选)使用 diff -u 对比修复后的 AOF 文件和原始 AOF 文件的备份,查看两个文件之间的不同之处。
重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。

aof重写如何工作

日志重写采用了和快照一样的写时复制机制。下面是过程:

  • Redis调用fork()。于是我们有了父子两个进程。
  • 子进程开始向一个临时文件中写AOF。
  • 父进程在一个内存缓冲区中积累新的变更(同时将新的变更写入旧的AOF文件,所以即使重写失败我们也安全)。
  • 当子进程完成重写文件,父进程收到一个信号,追加内存缓冲区到子进程创建的文件末尾
    搞定!现在Redis原子性地重命名旧文件为新的,然后开始追加新数据到新文件。

AOF与RDB之间的相互作用

Redis2.4以上的版本会确保在RDB快照创建时不触发AOF重写或者在AOF重写时不允许BGSAVE操作,以避免Redis后台进程同时做繁重的磁盘I/O操作。

当创建RDB快照时对于用户使用BGREWRITEAOF明确发起的日志重写操作server会立刻回应一个ok状态码告知用户操作将回被执行,当且仅当快照创建完成后重写操作开始被执行。

在同时使用了AOF和RDB方式的情况下,Redis重启后会优先使用AOF文件来重构原始数据集。

备份Redis数据

开始这一部分之前,请务必牢记:一定要备份你的数据库。磁盘损坏,云中实例丢失,等等:没有备份意味着丢失数据的巨大风险。

Redis对数据备份非常友好,因为你可以在数据库运行时拷贝RDB文件RDB文件一旦生成就不会被修改,文件生成到一个临时文件中,当新的快照完成后,将原子性地使用rename(2)修改文件名为目标文件。

这意味着,在服务器运行时拷贝RDB文件是完全安全的。以下是我们的建议:

  • 创建一个定时任务(cron job),每隔一个小时创建一个RDB快照到一个目录,每天的快照放在不同目录。
  • 每次定时脚本运行时,务必使用find命令来删除旧的快照:例如,你可以保存最近48小时内的每小时快照,一到两个月的内的每天快照。注意命名快照时加上日期时间信息。
  • 至少每天一次将你的RDB快照传输到你的数据中心之外,或者至少传输到运行你的Redis实例的物理机之外。

标签:aof,快照,fsync,AOF,redis,rdb,Redis,文件,RDB
From: https://www.cnblogs.com/lygin/p/16864687.html

相关文章

  • 史上最详细Docker安装Redis (含每一步的图解)实战
    不仅教你安装,还教你删除。每一行命令都带图解,绝对能懂。大家对搭建RedisClustr(Redis集群)感兴趣的,可以看看这篇文章Docker搭建RedisCluster集群环境希望对大家有所......
  • Redis集群介绍
    什么是集群能够对外提供相同服务的多台服务器组成的集合。为什么要建立集群1.从可用性角度考虑,如果只有一台机器提供服务,一旦出现故障,那么整个服务不可用。2.从容量角......
  • OpenEuler2203 基于容器和本地文件部署Redis Cluster的过程以及简单性能测试
    背景其实文件搭建和集群搭建没有任何区别这次用先用容器搭建出来,然后测试一下性能想着再使用本地部署的方式搭建一下.两项验证容器和基于文件的搭建的性能差异部分资......
  • docker实战教程(十五):docker上安装redis
    简单版从dockerhub上拉取redis镜像到本地(指定版本为6.0.8)运行redis容器进入redis环境这样安装同样存在数据和配置文件的问题复杂版在Centos宿主机下新建目录/app......
  • pycharm操作redis
    安装在终端环境下输入:pipinstallredispycharm操作redis之普通连接#1.导入模块fromredisimportRedis#2.实例化产生链接对象conn=Redis()#连接本地的redi......
  • redis介绍和安装
    redis介绍redis是一种在内存进行存储数据的数据库,当然,它也支持将数据存储到硬盘上redis的存储方式是通过key-value的形式,value可以是很多数据类型,分别是:string(字符串)、li......
  • redis rdb与snapshot的关系
    关系RDB是Redis用来进行持久化的一种方式,在指定的时间间隔内将当前内存中的数据集快照写入磁盘,也就是Snapshot快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到......
  • 使用jwt,redis,实现登录
    jwt是无状态的,不需要服务端存储登录用户信息,一次性生成token后,除非过期,不然是都可以用的。但是这样就产生了token续期、用户注销等问题。token续期怎么解决呢?1、使用......
  • Springboot2.x 结合 redis 实现ip请求次数限制
    参考https://cloud.tencent.com/developer/article/1607647SpringBoot整合Redis代码详解,四步搞定!https://blog.csdn.net/jinyangbest/article/details/98205802sprin......
  • Windows版的Redis安装
    到官网下载:​​​https://github.com/MicrosoftArchive/redis/releases​​​如果没有到如下网盘下载:​更改配置文件​Windows版的Redis有2个配置文件,一个是:redis.windows.c......