Redis——Redis用作数据库(持久化/RDB/AOF)

Redis 用作数据库

Redis 用作缓存,其特点之一就是数据可以丢,只需要保证其响应急速,性能较高!

但是如果把 Redis 做数据库:数据绝对不能丢的,所以除了保证其速度之外,还必须保证其持久性,数据一定不可以丢失

而我们知道 Redis 处于内存,内存数据掉电易失!所以如果想要使用 Redis 作为数据库,必须要保证其持久性

只要是存储层,为了保证数据安全,都会有如下两个通用的功能:

  • 快照/副本:记录某一时刻数据库中所有的正确数据状况。可以保存在本地主机,也可以拷贝到另一台远程主机,一旦出现断电,甚至服务器瘫痪,也可以根据快照恢复某一时刻的正常数据
  • 日志:用户发生增删改的时候,所有的操作都会记录到一个日志文件。如果周一数据正常,周二系统上线新功能出现一个致命错误,造成大量资金损失,此时可以将系统紧急停服,根据日志将数据回滚到一个正常状态

官网持久化介绍:http://redis.cn/topics/persistence.html

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

  • RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.
  • AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.
  • 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
  • 你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.

最重要的事情是了解RDB和AOF持久化方式的不同,这也是面试高频,下面我们就来详细学习以下 RDB 和 AOF

一、持久化之RDB

RDB 全称 redis database,在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的 Snapshot 快照,它恢复时直接将快照文件直接读到内存里;

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,主进程是不进行任何 IO操作的,它就确保了极高的性能;RDB 文件是在硬盘上的二进制文件,是 Redis 在内存存储的数据在某一时刻的快照

1、时点性

系统中不可能每分每秒都进行快照存储,这样会大量占用系统资源且毫无意义,所以运维人员一般会定时保存快照

假设使用 RDB 每一小时进行一次快照存储,假设一个正常系统的快照文件大小有 10 G,肯定不可能瞬时就能保存到磁盘,那么快照存储该如何实现呢?我们最先想到的一种方式如下图:

在这里插入图片描述

阻塞保存快照:Redis 主进程阻塞,不再对外提供服务,只进行快照的持久化。这种方式能保证快照的时点性,但是会导致服务停用,这种情况生产环境不会允许发生。所以我们就想让 Redis 一边提供服务,一边进行快照的持久化,处理过程如下:

在这里插入图片描述

非阻塞保存快照:会导致时点混乱,无法保存正确的快照信息,导致数据不一致

那么 RDB 究竟是如何进行持久化呢?——主进程非阻塞继续提供服务,同时 fork 出子进程进行持久化,处理流程如下:

在这里插入图片描述

fork 子进程保存快照:Redis 主进程继续对外提供服务,同时 fork 出子进程进行快照持久化。在持久化期间,客户端对主进程的修改对于 fork 出的子进程是看不到的,所以能够保证快照的时点性,不会发生混乱


补充:fork 是怎么实现的?或者说使用 fork 有什么优势?

fork 创建子进程不会发生数据的复制,只是会创建引用指针,这样创建子进程的时候,速度特别快;

只有发生写操作时才会触发复制,即 copy on write (写时复制)机制,不会发生全量的数据修改

在这里插入图片描述

fork() 创建子进程优势:

  • 创建子进程时只需要创建指针引用,不需要数据复制,创建速度快
  • 并不是全量复制数据,占用空间小

RDB 流程:

在这里插入图片描述

2、RDB配置

上面理论学习完之后,Redis 是怎么完成以 RDB 进程持久化的呢?

  • 人为触发:可以通过两个指令人为触发
    • save:前台阻塞,不再提供服务,只进行快照持久化。较少使用,使用场景明确——只有明确什么时间会关机停服维护的时候才可能用到
    • bgsave:后台异步非阻塞,fork 创建子进程完成快照的持久化
  • 配置文件配置 bgsave 规则:
    • save 60 10000:时间达到 60 秒,或者写操作数达到 10000 次,两者满足其一,就会触发 RDB
    • save 300 10:时间达到 300 秒,或者写操作到达 10 次,两者满足其一,就会触发 RDB
    • save 900 1:时间达到 900 秒,或者写操作数达到 1 次,两者满足其一,就会触发 RDB
    • 根据系统的并发量、高峰时点等等灵活设置

3、优缺点

RDB的优点

  • RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时也可以每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
  • RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
  • 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.

RDB的缺点

  • 数据丢失:如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据
  • 耗时:RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.

总结:

在这里插入图片描述

二、持久化之AOF

AOF 即 Append-only file,使用追加写操作

如果说 RDB 是类似于快照/副本,那么 AOF 就是类似于日志。AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录。而且是以文本的方式记录,可以打开文件看到详细的操作记录

在这里插入图片描述

redis中,RDB和AOF可以同时开启,如果开启了AOF只会用AOF恢复

因为 AOF 是追加写,只要服务器不停,日志文件就会无限膨胀。假设 redis 服务运行了10年,AOF文件可能达到数十G,甚至数十T大小,此时可能导致内存溢出,而且根据这么大的文件中的指令一条一条的进行数据恢复,耗时将会很长

所以在 Redis 4.0 以后,AOF是一个混合体,将老的数据以 RDB 方式保存到 AOF 文件中,将增量的以指令的方式 Append 到AOF。既利用了 RDB 的快速,又保证了AOF日志的全量

1、AOF配置

既然作为数据库,那么每次的写操作都应该要保存下来,任何一条增删改操作都不能丢失。但是写操作都会触发IO,频繁的 IO 将会拖慢 redis 的速度,所以 Redis 中对于写操作有三种级别:

  • 无 fsync:不进行同步(不安全)
  • 每秒 fsync:每秒进行一次同步(默认方式,既保证数据丢失量少,而且速度不算慢,性能比较均衡)
  • 每次写的时候 fsync:每次写操作都进行一次同步(频率过高,拖慢速度)

2、优缺点

AOF 优点

  • 使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
  • AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.
  • Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
  • AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

AOF 缺点

  • 长期运行导致日志文件体积过大,有可能出现内存溢出,而且恢复起来也很慢
  • 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB

关联文章:

Redis入门–万字长文详解epoll

Redis——详解五种数据结构

Redis——Redis的进阶使用(管道/发布订阅/事务/布隆过滤器)

Redis——Redis用作缓存(内存回收/穿透/击穿/雪崩)

猜你喜欢

转载自blog.csdn.net/qq_42583242/article/details/108911646