一、redis持久化介绍
Redis是个基于内存的数据库,服务一旦宕机,内存中的数据将全部丢失。通常的解决方案是从数据库来重新把这些数据写进redis, 但后端数据库有性能瓶颈,如果是大数据量的恢复,会对数据库带来巨大的压力,导致程序响应慢。所以对Redis来说,实现数据的持久化, 避免从后端数据库中恢复数据,是至关重要的。redis 支持三种持久化方式:
1、RDB:Redis DataBase,RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot),默认就是该方式。2、AOF:Append Only File,AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。
该方式默认关闭,需要手动开启。如果RDB和AOF同时开启,恢复数据时默认是使用AOF恢复数据,而不会使用RDB方式
3、RDB和AOF混合持久化(4.0之后才开始支持该方式),注意,这个不是简单的把RDB和AOF同时开启的意思,下面会介绍。
RDB和AOF优缺点:
RDB:优点:数据压缩、宕机后数据恢复速度快
缺点:非实时备份,可能会导致数据丢失
AOF:
AOF类似于mysql的binlog,可以设置为每秒/每次/操作系统自动决定何时刷盘等模式,写操作都以追加的形式,记录到日志里。
优点:非常安全,根据刷盘策略不同最多丢失1s的数据(生产上一般不设置成操作系统自己决定刷盘的模式),并且日志有可读性
缺点:文件较大,宕机后数据恢复较慢
二、RDB持久化方式
触发rdb持久化的方式有2种,分别是手动触发和自动触发。2.1、手动触发方式
手动触发有两种方式:save和bgsave命令
save命令:阻塞当前Redis服务器读写操作,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,不建议使用
bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。
当数据集非常大并且CPU性能不够强大的话,Redis可能会阻塞客户端几毫秒甚至一秒
bgsave原理图
具体流程如下:
1.redis客户端执行bgsave命令或者自动触发bgsave命令;
2.主进程判断当前是否已经存在正在执行的子进程,如果存在,那么主进程直接返回;
3.如果不存在正在执行的子进程,那么就fork一个新的子进程进行持久化数据,fork过程是阻塞的,fork操作完成后主进程即可执行其他操作;
4.子进程先将数据写入到临时的rdb文件中,待快照数据写入完成后再原子替换旧的rdb文件;
5.同时发送信号给主进程,通知主进程rdb持久化完成,主进程更新相关的统计信息(info Persitence下的rdb_*相关选项)。
2.2、自动触发方式
在以下几种情况时会自动触发1.redis.conf中配置save m n,即在m秒内有n次修改时,自动触发bgsave生成rdb文件;
2.主从复制时,从节点要从主节点进行全量复制时也会触发bgsave操作,生成当时的快照发送到从节点;
3.执行debug reload命令重新加载redis时也会触发bgsave操作;
4.默认情况下执行shutdown命令时,也会触发bgsave操作,这里要注意,关闭redis前要先备份老的rdb文件,不然会被覆盖;
5.执行flushdb、flushall命令是也会触发bgsave操作,但此时生成的rdb文件是空的
2.3、RDB持久化参数配置
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件(硬盘),可以多个条件配合
save 900 1
save 300 10
save 60 10000
# 设置持久化文件名,默认值为 dump.rdb,通常设置为 dump-端口号.rdb
dbfilename dump6379.rdb
# 设置读写文件过程是否进行RDB格式校验,默认 yes;若设置为 no,节约读写 10% 时间消耗,但存在数据损坏的风险
rdbchecksum yes
# 存储数据时是否压缩数据。默认是yes
rdbcompression yes
# 后台持久化过程中如果出现错误现象,是否停止保存操作,默认 yes
stop-writes-on-bgsave-error yes
# 指定文件存放目录
dir /opt/redis/data
三、AOF持久化
3.1、AOF持久化概述
快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。尽管对于某些程序来说, 数据的耐久性并不是最重要的考虑因素, 但是对于那些追求完全耐久能力(full durability)的程序来说, 快照功能就不太适用了。
从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。
注意:redis和传统数据库的wal预写日志不同,redis是先写数据,后写AOF日志。
3.2、AOF持久化原理
当AOF持久化功能打开之后,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器的 aof_buf 缓冲区,然后根据不同的策略再把缓冲区的数据同步(fsync)到磁盘AOF日志文件中。redis有三种不同的fsync策略: 1.no:操作系统自行决定何时刷盘 2.always:每次写入一条命令都会立即被刷新到磁盘 3.everysec:每秒进行一次 fsync 调用3.3、AOF重写机制
写操作不断执行的时候AOF文件会越来越大。例如,如果你增加一个计数器100次,你的数据集里只会有一个键存储这最终值,但是却有100条记录在AOF中。其中99条记录在重建当前状态时是不需要的。于是Redis支持一个有趣的特性:在后台重建AOF而不影响服务客户端。每当你发送BGREWRITEAOF时,Redis将会写入一个新的AOF文件,包含重建当前内存中数据集所需的最短命令序列。如果你使用的是Redis 2.2的AOF,你需要不时的运行BGREWRITEAOF命令。Redis 2.4可以自动触发日志重写,控制触发自动重写的参数为以下两个:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
AOF重写机制的流程
日志重写采用了和快照一样的写时复制机制。下面是过程:
1、Redis调用fork(),于是我们有了父子两个进程。
2、子进程开始向一个临时文件中写AOF。
3、父进程在一个内存缓冲区中积累新的变更(同时将新的变更写入旧的AOF文件,所以即使重写失败我们也安全)。
4、当子进程完成重写文件,父进程收到一个信号,追加内存缓冲区到子进程创建的文件末尾。
5、Redis原子性地重命名旧文件为新的,然后开始追加新数据到新文件。
3.4、AOF参数配置
# 指定是否在每次写操作后进行日志记录,也就是是否开启AOF,默认为no
appendonly yes
# 指定AOF日志文件名
appendfilename "appendonly.aof"
# 指定写AOF日志的方式 ,共有3个可选值:
# everysec:每秒写入一次,默认值
# no:表示由操作系统进行数据缓存同步到磁盘
# always:表示每次更新操作后都会自动调用fsync()将数据写到磁盘(慢,安全)
appendfsync always
# 此选项控制在进行 AOF 重写(AOF rewrite)过程中是否执行同步操作(fsync),默认为no,表示进行fsync操作
# AOF 重写是一个优化过程,它会生成一个新的、更紧凑的 AOF 文件,以便减少 AOF 文件的大小并提高效率。在重写过程中,Redis 会继续将新的写操作追加到当前的 AOF 文件中,同时在后台创建一个新的 AOF 文件
no-appendfsync-on-rewrite no
# 当 AOF 文件大小超过上次重写后 AOF 文件大小的百分比时自动触发,默认值为 100,也就是文件大小翻了一倍后会触发重写(bgrewriteaof)
auto-aof-rewrite-percentage 100
# 当 AOF 文件大小超过指定值时自动触发,默认值为 64 MB
auto-aof-rewrite-min-size 64mb
# 指定数据库存放目录,注意如果是redis7之前,AOF的目录和rdb的目录是在一起的(都是用dir这个参数来配置),
# 如果是7.0之后的版本,redis把AOF文件拆成了三个(7.0新特性Multi Part AOF,将单个 AOF 拆分为多个,该特性由阿里云数据库Tair团队贡献),
# 并且在这三个文件之上会新建一层目录(appendonlydir,这个目录是redis自动创建,),三个文件分别是appendonly.aof.1.base.rdb,appendonly.aof.1.incr.aof,appendonly.aof.manifest这个数字1每重写一次就会加1
dir /opt/redis/data
3.4、AOF文件出错了怎么办
服务器可能在程序正在对 AOF 文件进行写入时崩溃,如果是这样那AOF记录的数据就可能是不完整的, Redis在恢复数据时不会装载已破坏的AOF文件。当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:# 使用 Redis 附带的 redis-check-aof 程序,对原来的 AOF 文件进行修复
redis-check-aof --fix AOF文件名
注意:--fix参数一定要带上
四、AOF-RDB混合持久化方案
4.1、混合持久化概述
RDB 和 AOF 持久化各有利弊,RDB 可能会导致一定时间内的数据丢失,而 AOF 由于文件较大则会影响 Redis 的启动速度,为了能同时使用 RDB 和 AOF 各自的优点,Redis4.0之后新增了混合持久化的方式,但默认是关闭的,Redis 5.0之后默认是开启的。4.2、混合持久化原理
在 AOF 重写之前,RDB 和 AOF 都是按照它们各自的持久化策略工作的(RDB和AOF模式都要开启才行)。当 AOF 重写被触发时,混合持久化才开始发挥作用:当前的数据集会首先以RDB 格式写入新 AOF 文件的顶部,然后再追加新的命令到文件的末尾,如下图所示:4.3、混合持久化开启方式
首先RDB和AOF两种持久化模式都要开启
然后配置下面的参数:
aof-use-rdb-preamble yes
# 混合持久化的实现主要是靠主进程和子进程共同来完成的。
子进程进行AOF重写:
首先创建新的AOF文件 appendonly.rdb
将Redis当前的数据生成RDB快照写入 appendonly.rdb 文件的开始部分
主进程同时将新的写操作命令写入 AOF 重写缓冲区 ,然后主进程将 AOF 重写缓冲区的内容追加到 appendonly.rdb 文件的 RDB 数据的末尾
最后使用重写后的appendonly.rdb 文件替换旧的 AOF 文件
标签:AOF,持久,策略,文件,redis,rdb,Redis,RDB
From: https://www.cnblogs.com/sunjiwei/p/18470487