Redis 持久化是如何作的?一文聊聊 RDB和AOF对比分析

这篇文章咱们来介绍Redis高可用相关的机制。Redis要想实现高可用,主要有如下方面来保证:redis

  • 数据持久化
  • 主从复制
  • 自动故障恢复
  • 集群化

这篇文章咱们先介绍Redis的高可用保障的基础:数据持久化。由于Redis的主从复制和自动故障恢复,都须要依赖Redis持久化相关的东西。同时,Redis的数据持久化也能够用来作数据备份,用来保障数据的安全性。数据库

Redis是一个内存数据库,它的数据都保存在内存中,若是实例宕机,那么数据则所有丢失。如何保证数据的完整性和安全性也是提升服务高可用的重要机制之一。安全

Redis提供了完善的持久化机制,能够把内存中的数据持久化到磁盘上,方便咱们进行备份数据和快速恢复数据。app

这篇文章咱们就来分析Redis的数据持久化是如何实现的?咱们常常听的RDB和AOF有什么区别?以及它们不一样的使用场景。性能

持久化方式

Redis提供的数据持久化方式主要有2种:spa

  • RDB:产生一个数据快照文件
  • AOF:实时追加命令的日志文件

它们分别对应了不一样的使用场景,下面咱们就来依次分析。操作系统

RDB

介绍3d

RDB全称 Redis Database Backup file(Redis数据备份文件),也被叫作 Redis 数据快照。日志

咱们能够经过执行save或bgsave命令让 Redis 在本地生成RDB快照文件,这个RDB文件包含了整个实例接近完整的数据内容。它的优势以下:code

  • RDB文件数据是被压缩写入的,所以RDB文件的体积要比整个实例内存要小
  • 当实例宕机恢复时,加载RDB文件的速度很快,可以在很短期内迅速恢复文件中的数据

它的缺点也很明显:

  • 因为是某一时刻的数据快照,所以它的数据并不全
  • 生成 RDB 文件的代价是比较大的,它会消耗大量的 CPU 和内存资源

所以RDB比较适用于如下场景:

  • 主从全量同步数据
  • 数据库备份
  • 对于丢失数据不敏感的业务场景,实例宕机后快速恢复数据

Redis主从全量同步数据就是使用RDB文件进行的,咱们会在后面的文章详细讲到。

由此能够看出,RDB很是适合作数据备份,咱们能够定时让Redis生成RDB文件,而后备份这个快照文件便可。

定时生成RDB

Redis也提供了定时触发生成RDB文件的配置项:

# 最近15分钟内 至少产生1次写入
save 900 1
# 最近5分钟内 至少产生10次写入
save 300 10
# 最近1分钟内 至少产生10000次写入
save 60 10000

若是达到以上任意条件,则Redis会自动生成新的RDB文件,下降RDB数据内容与实例数据的差别。

Copy On Write

在Redis上执行save和bgsave命令均可以生成RDB文件,但前者是在前台执行的,也就是说在生成RDB文件时,会阻塞整个实例,在RDB未生成以前,任何请求都是没法处理的,对于内存很大的实例,生成RDB文件很是耗时,显然这是咱们不能接受的。

因此一般咱们会选择执行bgsave让Redis在后台生成RDB文件,这样Redis依旧能够处理客户端请求,不会阻塞整个实例。

但不是说后台生成RDB就是没有代价的,Redis为了实现后台把内存数据的快照写入文件,采用了操做系统提供的Copy On Write技术,也就是咱们熟知的fork系统调用。

fork 系统调用会产生一个子进程,它与父进程共享相同的内存地址空间,这样子进程在这一时刻就能拥有与父进程的相同的内存数据。

虽然子进程与父进程共享同一块内存地址空间,但在fork子进程时,操做系统须要拷贝父进程的内存页表给子进程,若是整个Redis实例内存占用很大,那么它的内存页表也会很大,在拷贝时就会比较耗时,同时这个过程会消耗大量的CPU资源。在完成拷贝以前父进程也处于阻塞状态,没法处理客户端请求。

fork执行完以后,子进程就能够扫描自身全部的内存数据,而后把所有数据写入到RDB文件中。

以后父进程依旧处理客户端的请求,当在处理写命令时,父进程会从新分配新的内存地址空间,从操做系统申请新的内存使用,再也不与子进程共享,这个过程就是Copy On Write(写实复制)名字的由来。这样父子进程的内存就会逐渐分离,父进程申请新的内存空间并更改内存数据,子进程的内存数据不受影响。

由此能够看出,在生成RDB文件时,不只消耗CPU资源,还有须要占用最多一倍的内存空间。

咱们在 Redis 执行info命令,能够看到fork子进程的耗时,能够经过这个耗时来评估fork时间是否符合预期。同时咱们应该保证Redis机器拥有足够的CPU和内存资源,并合理设置生成RDB的时机。

AOF

介绍

AOF全称为Append Only File(追加日志文件)。它与RDB不一样的是,AOF中记录的是每个命令的详细信息,包括完整的命令类型、参数等。只要产生写命令,就会实时写入到AOF文件中。

咱们能够经过配置文件开启AOF:

# 开启AOF
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# 文件刷盘方式
appendfsync everysec

刷盘方式

开启AOF后,Redis会把每一个写操做的命令记录到文件并持久化到磁盘中,为了保证数据文件的安全性,Redis还提供了文件刷盘的时机:

  • appendfsync always:每次写入都刷盘,对性能影响最大,占用磁盘IO比较高,数据安全性最高
  • appendfsync everysec:1秒刷一次盘,对性能影响相对较小,节点宕机时最多丢失1秒的数据
  • appendfsync no:按照操做系统的机制刷盘,对性能影响最小,数据安全性低,节点宕机丢失数据取决于操做系统刷盘机制

以上能够看出AOF相对于RDB的优势是,AOF数据文件更新比较及时,比RDB保存更完整的数据,这样在数据恢复时可以恢复尽可能完整的数据,下降丢失数据的风险。

若是同时存在RDB文件和AOF文件,Redis会优先使用AOF文件进行数据恢复。

但它的缺点也很易见:

  • 随着时间增加,AOF文件会愈来愈大
  • AOF文件刷盘会增长磁盘IO的负担,可能影响Redis的性能(开启每秒刷盘时)

AOF重写

针对第一种状况,Redis提供了AOF瘦身的功能,能够设置在AOF文件很大时,自动触发AOF重写,Redis会扫描整个实例的数据,从新生成一个AOF文件达成瘦身的效果。但这个重写过程也须要消耗大量的CPU资源。

# AOF文件距离上次文件增加超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb

因为AOF能够最大可能下降丢失数据的风险,因此它通常适用于对丢失数据很敏感的业务场景,例如涉及金钱交易的业务。

性能影响

若是AOF的刷盘时机设置为每次写入都刷盘,那么会大大下降Redis的写入性能,由于每次写命令都须要写入文件并刷到磁盘中才会返回,当写入量很大时,会增长磁盘IO的负担。性能与数据安全不能兼得,虽然Redis提供了实时刷盘的机制,可是在真正场景中使用的很少。

一般咱们会选择每秒刷盘这种方式,既能保证良好的写入性能,在实例宕机时最多丢失1秒的数据,作到性能和安全的平衡。

总结

咱们对RDB和AOF的总结以下表。咱们须要针对不一样的业务场景选择合适的持久化方式,也能够根据RDB和AOF的优势配合使用,保证Redis数据的安全性,又能够兼顾它的性能。

做者:Kaito
连接:http://kaito-kidd.com/2020/06...

image

相关文章
相关标签/搜索