首页 > 数据库 >Redis

Redis

时间:2022-09-22 19:24:50浏览次数:44  
标签:AOF 快照 文件 Redis RDB 持久

Redis 持久化机制:怎么保证 Redis 挂掉之后再重启数据可以进行恢复?
很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后恢复数据),或者是为了防止系统故障而将数据备份到一个远程位置。

Redis 不同于 Memcached 的很重要一点就是,Redis 支持持久化,而且支持两种不同的持久化操作。Redis 的一种持久化方式叫快照(snapshotting,RDB),另一种方式是只追加文件(append-only file, AOF)。这两种方法各有千秋,下面我会详细这两种持久化方法是什么,怎么用,如何选择适合自己的持久化方法。

什么是 RDB 持久化?

Redis 可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis 创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis 主从结构,主要用来提高 Redis 性能),还可以将快照留在原地以便重启服务器的时候使用。

快照持久化是 Redis 默认采用的持久化方式,在 redis.conf 配置文件中默认有此下配置:

save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。

save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。

save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命令创建快照。

RDB 创建快照时会阻塞主线程吗?

Redis 提供了两个命令来生成 RDB 快照文件:

save : 主线程执行,会阻塞主线程;
bgsave : 子线程执行,不会阻塞主线程,默认选项。

什么是 AOF 持久化?

与快照持久化相比,AOF 持久化的实时性更好,因此已成为主流的持久化方案。默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以通过 appendonly 参数开启:

appendonly yes

开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入到内存缓存 server.aof_buf 中,然后再根据 appendfsync 配置来决定何时将其同步到硬盘中的 AOF 文件。

AOF 文件的保存位置和 RDB 文件的位置相同,都是通过 dir 参数设置的,默认的文件名是 appendonly.aof。

在 Redis 的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:

appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步一次,显式地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进行同步

为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec 选项 ,让 Redis 每秒同步一次 AOF 文件,Redis 性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis 还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。

相关 issue :

Redis 的 AOF 方式 #783
Redis AOF 重写描述不准确 #1439

AOF 日志是如何实现的?

关系型数据库(如 MySQL)通常都是执行命令之前记录日志(方便故障恢复),而 Redis AOF 持久化机制是在执行完命令之后再记录日志。

为什么是在执行完命令之后记录日志呢?

避免额外的检查开销,AOF 记录日志不会对命令进行语法检查;
在命令执行完之后再记录,不会阻塞当前的命令执行。

这样也带来了风险(我在前面介绍 AOF 持久化的时候也提到过):

如果刚执行完命令 Redis 就宕机会导致对应的修改丢失;
可能会阻塞后续其他命令的执行(AOF 记录日志是在 Redis 主线程中进行的)。

AOF 重写了解吗?

当 AOF 变得太大时,Redis 能够在后台自动重写 AOF 产生一个新的 AOF 文件,这个新的 AOF 文件和原有的 AOF 文件所保存的数据库状态一样,但体积更小。

AOF 重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有 AOF 文件进行任何读入、分析或者写入操作。

在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新的 AOF 文件保存的数据库状态与现有的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。

Redis 7.0 版本之前,如果在重写期间有写入命令,AOF 可能会使用大量内存,重写期间到达的所有写入命令都会写入磁盘两次。

如何选择 RDB 和 AOF?

关于 RDB 和 AOF 的优缺点,官网上面也给了比较详细的说明Redis persistence,这里结合自己的理解简单总结一下。

RDB 比 AOF 优秀的地方 :

RDB 文件存储的内容是经过压缩的二进制数据, 保存着某个时间点的数据集,文件很小,适合做数据的备份,灾难恢复。AOF 文件存储的是每一次写命令,类似于 MySQL 的 binlog 日志,通常会必 RDB 文件大很多。当 AOF 变得太大时,Redis 能够在后台自动重写 AOF。新的 AOF 文件和原有的 AOF 文件所保存的数据库状态一样,但体积更小。不过, Redis 7.0 版本之前,如果在重写期间有写入命令,AOF 可能会使用大量内存,重写期间到达的所有写入命令都会写入磁盘两次。
使用 RDB 文件恢复数据,直接解析还原数据即可,不需要一条一条地执行命令,速度非常快。而 AOF 则需要依次执行每个写命令,速度非常慢。也就是说,与 AOF 相比,恢复大数据集的时候,RDB 速度更快。

AOF 比 RDB 优秀的地方 :

RDB 的数据安全性不如 AOF,没有办法实时或者秒级持久化数据。生成 RDB 文件的过程是比繁重的, 虽然 BGSAVE 子进程写入 RDB 文件的工作不会阻塞主线程,但会对机器的 CPU 资源和内存资源产生影响,严重的情况下甚至会直接把 Redis 服务干宕机。AOF 支持秒级数据丢失(取决 fsync 策略,如果是 everysec,最多丢失 1 秒的数据),仅仅是追加命令到 AOF 文件,操作轻量。
RDB 文件是以特定的二进制格式保存的,并且在 Redis 版本演进中有多个版本的 RDB,所以存在老版本的 Redis 服务不兼容新版本的 RDB 格式的问题。
AOF 以一种易于理解和解析的格式包含所有操作的日志。你可以轻松地导出 AOF 文件进行分析,你也可以直接操作 AOF 文件来解决一些问题。比如,如果执行FLUSHALL命令意外地刷新了所有内容后,只要 AOF 文件没有被重写,删除最新命令并重启即可恢复之前的状态。

Redis 4.0 对于持久化机制做了什么优化?

Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。

如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。

标签:AOF,快照,文件,Redis,RDB,持久
From: https://www.cnblogs.com/wanFengYx/p/16720592.html

相关文章

  • springboot中重写RedisTemplate
    1、引入jar包<!--引入redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>......
  • 如何优雅实现分布式锁-Redisson
    1、引入jar包<!--引入redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>......
  • helm部署redis-culster集群
    helm部署redis-culster集群安装helmwgethttps://repo.huaweicloud.com/helm/v3.8.0/helm-v3.8.0-linux-amd64.tar.gztar-zxfhelm-v3.8.0-linux-amd64.tar.gzmvlin......
  • Windows中使用Docker安装Redis
    1、拉取Redis以管理员身份运行CMD,执行如下命令拉取Redisdockerpullredis2、在D盘新建目录D:\Net_Program\Net_Docker\Redis 在D盘新建D:\Net_Program\Net_Doc......
  • 第二十章 Redis面试总结
    一、Redis持久化1.RDB与AOF的区别RDB可以理解为是一种全量数据更新机制,AOF可以理解为是一种增量的更新机制,AOF重写可以理解为是一种全量+增量的更新机制(第一次是全量,后面......
  • redis分布式锁,redis中set和setnx的区别
    转自:https://www.zhangshilong.cn/work/320344.html Redis命令SETNX的使用(包含Java分布式锁实现)可以参考Redis官网对SETNX命令的介绍:https://redis.io/commands/setnx......
  • spring-session-data-redis解决多redis的问题
    1:参考这篇文章就好了https://github.com/yugabyte/redis-code-samples/blob/69fe87302de0c9524036c8476cbc5ed90e988165/spring-session/spring-session-data-redis/src/t......
  • Redis与Python连接实例
    2022-09-221、Redis与Python建立连接之前需要先安装“Redis”安装包:在ubantu中,打开终端,输入命令:sudopipinstallredis此时,是安装Python2.0的版本。一般来说,是将3......
  • CTO 说了:谁再用 Redis 过期监听实现定时任务,立马滚蛋!
    作者:Finley来源:https://www.cnblogs.com/Finley/p/16395466.html前言日前拜读阿牛老师的大作《领导:谁再用定时任务实现关闭订单,立马滚蛋!》发现其方案有若干瑕疵,特此抛......
  • 如何远程访问 Redis
    一、修改配置文件.conf1、将配置文件里面的bind127.0.0.1注释掉,改成#bind127.0.0.1 2、将配置文件里面的protected-modeyes改成protected-modeno 3、在redi......