redis持久化

img

RDB

1. 是什么

RDB(Redis数据库):RDB持久性以指定的时间间隔执行数据集的时间点快照。

实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。这个快照文件就成为RDB文件(dump.rdb),其中,RDB就是Redis DataBase的缩写。

2. 能干嘛

(1)在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot内存快照,它恢复时再将硬盘快照文件直接读回到内存里
(2)一锅端:Redis的数据都在内存中,保存备份时它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中,一锅端。
(3)Rdb保存的是dump.rdp文件

3. 案例演示

(1)需求说明
img

自动触发 redis7.conf文件修改

  1. 本次案例5秒2次修改

img

  1. 修改dump文件保存路径,切记要创建好文件

img

  1. 修改dump文件名称

img

自定义修改的路径且可以进入redis里用CONFIG GET dir获取目录

127.0.0.1:6379> config get dir
1) "dir"
2) "/home/ops"
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "111111"
127.0.0.1:6379> config get port
1) "port"
2) "6379"
  1. 触发备份

a.查看rdb文件,此时没有数据

[ops@master2 /myredis/dumpfiles]$ pwd
/myredis/dumpfiles
[ops@master2 /myredis/dumpfiles]$ ll
total 0

b.添加数据

127.0.0.1:6379> get key*
(nil)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK

c. 再次查看rdb文件,此时有数据

[ops@master2 /myredis/dumpfiles]$ ll
total 4
-rw-rw-r--. 1 ops ops 107 Feb 12 10:41 dump7379.rdb

  1. 如何修复
    将备份文件(dump.rdb)移动到redis安装目录并启动服务即可
    !备份成功后故意用flushdb清空redis,看看是否可以恢复数据
    a.备份dump.rdb文件
[ops@master2 /myredis/dumpfiles]$ sudo cp dump7379.rdb dump7379.bak.rdb 

b.清空redis

127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)

c.模拟redis宕机

127.0.0.1:6379> shutdown
not connected> exit

d.删除宕机生成的dump文件,将备份的dump文件修改成dump.rdb

[ops@master2 /myredis/dumpfiles]$ ls
dump7379.bak.rdb  dump7379.rdb
[ops@master2 /myredis/dumpfiles]$ rm -rf dump7379.rdb 
[ops@master2 /myredis/dumpfiles]$ sudo mv dump7379.bak.rdb dump7379.rdb

e.重启redis服务,查看数据已恢复

[ops@master2 ~]$ redis-server /myredis/redis7.conf 
[ops@master2 ~]$ redis-cli 
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> 

手动触发

Redis提供了两个命令来生成RDB文件,分别是save和bgsave
img

1.save
在主程序中执行会阻塞当前redis服务器,直到持久化工作完成执行save命令期间,Redis不能处理其他命令,线上禁止使用

  • 案例:
127.0.0.1:6379> SAVE
OK

img

2.bgsave
Redis会在后台异步进行快照操作,不阻塞快照同时还可以响应客户端请求,该触发方式会forkk一个子进程赋值持久化过程。
Redis会使用bgsave对当前内存中的所有数据做快照,这个操作是子进程在后台完成的,这就允许主进程同时可以修改

127.0.0.1:6379> BGSAVE
Background saving started

优缺点

  1. 优点
  • 适合大规模的数据恢复
  • 按照业务定时备份
  • 对数据完整性和一致性要求不高
  • RDB文件在内存中的加载速度要比AOF快得多
  1. 缺点
  • 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失从当前至最近一次快照期间的数据,快照之间的数据会丢失
  • 内存数据的全量同步,如果数据量太大会导致I/O严重影响服务器性能
  • RDB依赖于主进程的fork,在更大的数据集中,这可能会导致服务请求的瞬间延迟。fork的时候内存中的数据被克隆了一份,大致2倍的膨胀性,需要考虑

RDB优化配置项详解

配置文件SNAPSHOTTING模块

  1. save

  2. dbfilename

  3. dir

  4. stop-wirtes-on-bgsave-error
    默认yes,如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求。
    建议配置yes。

  5. rdbcompression
    默认yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,Redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。

  6. rdbchecksum
    默认yes。在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

  7. rdb-del-sync-files
    在没有持久性的情况下删除复制中使用的RDB文件启用。默认情况下no,此选项是禁用的。

总结

img

  • RDB是一个非常紧凑的文件
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,所以RDB持久化方式可以最大化redis的性能。
  • 域AOF相比,在恢复大的数据集的时候,RDB方式会更快一些。
  • 数据丢失风险大
  • RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致reis在一些毫秒级不能响应客户端请求。

AOF

是什么

以日志的形式记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将指令从前到后执行一次以完成数据的恢复工作。
默认情况下,redis是没有开启AOF(append only file)的。开启AOF功能需要设置配置:appendonly yes。
AOF保存的是appendonly.aof文件

AOF持久化工作流程

img

1.Client作为命令的来源,会有多个源头以及源源不断的请求命令。
2.在这些命令到达Redis Server以后并不是直接写入AOF文件,会将其这些命令先放入AOF缓存中进行保存。这里的AOF缓冲区实际上是内存中的一片区域,存在的目的是当这些命令达到一定量以后再写入磁盘,避免频繁的磁盘IO操作。
3.AOF缓冲会根据AOF缓冲区同步文件的三种写回策略将命令写入磁盘上的AOF文件。
4.随着写入AOF内容的增加为避免文件膨胀,会根据规则进行命令的合并(又称AOF重写),从而启动AOF文件压缩的目的。
5.当Redis Server服务器重启的时候会从AOF文件载入数据

AOF缓冲区三种写回策略

img

  1. Always
    同步写回,每个写命令执行完立刻同步地将日志写回磁盘
  2. everysec
    每秒写回,每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔1秒把缓冲区中的内容写入磁盘
  3. no
    操作系统控制的写回,每个写命令执行完,只是先把日志写到AOF文件的内存缓冲决定何时将缓冲区内容写回磁盘
  4. 总结
配置项 写回时机 优点 缺点
Always 同步写回 可靠性高,数据基本不丢失 每个写命令都要落盘,性能影响较大
Everysec 每秒写回 性能适中 宕机时丢失1秒内的数据
No 操作系统控制的写回 性能好 宕机时丢失数据较多

案例演示和说明

AOF配置/启动/修复/恢复

  1. 如何开启aof
    img

  2. 使用默认写回策略,每秒钟
    img

  3. aof文件-保存路径
    img

  4. aof文件-保存名称
    img

顾名思义,MP-AOF就是将原来的单个AOF文件拆分成多个AOF文件。在MP-AOF中,我们将AOF分成三种类型,分别为:

BASE:表示基础AOF,它一般由子进程通过重写产生,该文件最多只有一个。
INCR:表示增量AOF,它一般会在AOFRW开始执行时被创建,该文件可能存在多个。
HISTORY:表示历史AOF,它由BASE和INCR AOF变化而来,每次AOFRW成功完成时,本次AOFRW之前对应的BASE和INCR AOF都将变为HISTORY类型的AOF会被Redis自动删除。

为了管理这些AOF文件,我们引入了一个manifest(清单)文件来跟踪、管理这些AOF。同时,为了便于AOF备份和拷贝,我们将所有的AOF文件和manifest文件放入了一个单独的文件目录中,目录名由appenddirname配置。

  1. Redis7.0 config中对应的配置项
// 几种类型文件的前缀,后跟有关序列和类型的附加信息
appendfilename "appendonly.aof"

// 新版本增加的目录配置项目
appenddirname "appendonlydir"

// 如有下的aof文件存在
1. 基本文件
   appendonly.aof.1.base.rdb
2. 增量文件
   appendonly.aof.1.incr.aof
   appendonly.aof.2.incr.aof
3. 清单文件
   appendonly.aof.manifest

测试

  1. 写入数据
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
  1. 查看aof文件
[ops@master2 ~]$ cd /myredis/
[ops@master2 /myredis]$ ll
total 112
drwxr-xr-x. 2 ops ops    103 Mar  4 16:03 appendonlydir
drwxr-xr-x. 2 ops ops      6 Feb 12 10:28 dumfiles
-rw-rw-r--. 1 ops ops    107 Mar  4 16:04 dump7379.rdb
drwxr-xr-x. 2 ops ops     26 Feb 14 17:16 dumpfiles
-rw-r--r--. 1 ops ops 106587 Mar  4 15:21 redis7.conf
[ops@master2 /myredis]$ cd appendonlydir/
[ops@master2 /myredis/appendonlydir]$ ll
total 12
-rw-rw-r--. 1 ops ops  88 Mar  4 16:03 appendonly.aof.1.base.rdb
-rw-r--r--. 1 ops ops 110 Mar  4 16:04 appendonly.aof.1.incr.aof
-rw-r--r--. 1 ops ops  88 Mar  4 16:03 appendonly.aof.manifest
  1. 正常恢复
  • 删除dump文件
[ops@master2 /myredis]$ rm -rf dum*
[ops@master2 /myredis]$ ll
total 108
drwxr-xr-x. 2 ops ops    103 Mar  4 16:03 appendonlydir
-rw-r--r--. 1 ops ops 106587 Mar  4 15:21 redis7.conf
  • 备份dir文件
[ops@master2 /myredis]$ cp -r appendonlydir/ appendonlydir.bak
[ops@master2 /myredis]$ ll
total 108
drwxr-xr-x. 2 ops ops    103 Mar  4 16:03 appendonlydir
drwxr-xr-x. 2 ops ops    103 Mar  4 16:12 appendonlydir.bak
-rw-r--r--. 1 ops ops 106587 Mar  4 15:21 redis7.conf
  • 删除数据
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> shutdown
not connected>
  • 重新连接Redis,数据为空
[ops@master2 ~]$ redis-server /myredis/redis7.conf 
[ops@master2 ~]$ redis-cli -a 111111
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> keys *
(empty array)
  • 再关机恢复数据
127.0.0.1:6379> shutdown
not connected> exit
[ops@master2 /myredis]$ ll
total 112
drwxr-xr-x. 2 ops ops    103 Mar  4 16:03 appendonlydir
drwxr-xr-x. 2 ops ops    103 Mar  4 16:12 appendonlydir.bak
-rw-rw-r--. 1 ops ops     88 Mar  4 16:16 dump7379.rdb
-rw-r--r--. 1 ops ops 106587 Mar  4 15:21 redis7.conf
[ops@master2 /myredis]$ rm -rf dump7379.rdb 
[ops@master2 /myredis]$ rm -rf appendonlydir
[ops@master2 /myredis]$ mv appendonlydir.bak appendonlydir
[ops@master2 /myredis]$ ll
total 108
drwxr-xr-x. 2 ops ops    103 Mar  4 16:12 appendonlydir
-rw-r--r--. 1 ops ops 106587 Mar  4 15:21 redis7.conf
  • 再连接Redis发现数据已恢复
[ops@master2 ~]$ redis-server /myredis/redis7.conf 
[ops@master2 ~]$ redis-cli -a 111111
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
  1. 异常恢复
  • 故意乱写正常的AOF文件,模拟网络闪断文件写error
[ops@master2 /myredis/appendonlydir]$ vim appendonly.aof.1.incr.aof 

img

127.0.0.1:6379> shutdown
not connected> exit
  • 重启Redis之后就会进行AOF文件的载入,发现启动都不行
[ops@master2 ~]$ redis-server /myredis/redis7.conf 
[ops@master2 ~]$ redis-cli -a 111111
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> 
[ops@master2 ~]$ ps -ef | grep redis
ops      19185 14228  0 16:41 pts/0    00:00:00 grep --color=auto redis
[ops@master2 ~]$ lsof -i:6379
-bash: lsof: command not found
  • 异常修复命令:redis-check-aof --fix 进行修复
[ops@master2 /myredis/appendonlydir]$ redis-check-aof --fix appendonly.aof.1.incr.aof 
Start checking Old-Style AOF
AOF appendonly.aof.1.incr.aof format error
AOF analyzed: filename=appendonly.aof.1.incr.aof, size=130, ok_up_to=110, ok_up_to_line=27, diff=20
This will shrink the AOF appendonly.aof.1.incr.aof from 130 bytes, with 20 bytes, to 110 bytes
Continue? [y/N]: y
Successfully truncated AOF appendonly.aof.1.incr.aof
  • 重启OK
[ops@master2 ~]$ redis-server /myredis/redis7.conf 
[ops@master2 ~]$ redis-cli -a 111111
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"

优势

更好的保护数据不丢失、性能高、可做紧急恢复

劣势

相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb
aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同

AOF重写机制

是什么

启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。

触发机制

  1. 自动触发
    满足配置文件中的选项中,Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时
    img

注意,同时满足,且的关系才会触发

  1. 根据上次重写后的aof大小,判断当前aof大小是不是增长了1倍
  2. 重写时满足的文件大小
  1. 手动触发
    客户端向服务器发送bgrewriteaof命令

案例说明

1. 需求说明
举个例子:比如有个key
一开始你 set k1 v1
然后改成 set k1 v2
最后改成 set k1 v3
如果不重写,那么这3条渔区都在aof文件中,内容占空间不说启动的时候都要执行一遍,共计3条命令;但是,我们实际效果只需要set k1 v3这一条,所以,开启重写后,只需要保存 set k1 v3就可以了,只需要保留最后一次修改值,相当于给aof文件瘦身减肥,性能更好。
AOF重写不仅降低了文件的占用空间,同时更小的AOF也可以更快地被Redis加载。
2. 需求验证
启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集
步骤一:前期配置准备
(1)开启aof
img

(2)重写峰值修改为1K

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 1k

(3)关闭混合,设置为no
img
(4)删除之前的全部aof和rdb,清除干扰项

[ops@master2 /myredis]$ ll
total 112
drwxr-xr-x. 2 ops ops    103 Mar  4 16:36 appendonlydir
-rw-rw-r--. 1 ops ops    114 Mar  4 16:45 dump7379.rdb
-rw-r--r--. 1 ops ops 106584 Mar  4 17:31 redis7.conf
[ops@master2 /myredis]$ rm -rf dump7379.rdb 
[ops@master2 /myredis]$ cd appendonlydir/
[ops@master2 /myredis/appendonlydir]$ rm -rf *
[ops@master2 /myredis/appendonlydir]$ ll
total 0

步骤二: 自动触发案例01
(1)完成上述正确配置,重启Redis服务器,执行 set k1 1 查看aof文件是够正常

127.0.0.1:6379> shutdown
not connected> exit
[ops@master2 ~]$ redis-server /myredis/redis7.conf 
[ops@master2 ~]$ redis-cli -a 111111
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 1
OK
[ops@master2 /myredis/appendonlydir]$ ll
total 8
-rw-rw-r--. 1 ops ops  0 Mar  4 17:37 appendonly.aof.1.base.aof
-rw-r--r--. 1 ops ops 51 Mar  4 17:37 appendonly.aof.1.incr.aof
-rw-r--r--. 1 ops ops 88 Mar  4 17:37 appendonly.aof.manifest
[ops@master2 /myredis/appendonlydir]$ cat appendonly.aof.1.incr.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$1
1

(2)k1不停11111暴涨,涨到appendonly.aof.1.incr.aof达到1K会变为0

127.0.0.1:6379> set k1 11111111111111
OK
127.0.0.1:6379> set k1 11111111111111
OK
127.0.0.1:6379> set k1 11111111111111
OK
127.0.0.1:6379> set k1 11111111111111
OK
....
[ops@master2 /myredis/appendonlydir]$ ll
total 8
-rw-rw-r--. 1 ops ops   0 Mar  4 17:37 appendonly.aof.1.base.aof
-rw-r--r--. 1 ops ops 923 Mar  4 17:40 appendonly.aof.1.incr.aof
-rw-r--r--. 1 ops ops  88 Mar  4 17:37 appendonly.aof.manifest
[ops@master2 /myredis/appendonlydir]$ ll
total 8
-rw-rw-r--. 1 ops ops 111 Mar  4 17:41 appendonly.aof.2.base.aof
-rw-r--r--. 1 ops ops   0 Mar  4 17:41 appendonly.aof.2.incr.aof
-rw-r--r--. 1 ops ops  88 Mar  4 17:41 appendonly.aof.manifest

(3)查看base文件,发现只记录最后一条k1数据,达到瘦身效果

[ops@master2 /myredis/appendonlydir]$ cat appendonly.aof.2.base.aof 
*2
$6
SELECT
$1
0
*3
$3
SET
$2
k1
$60
111111111111111111111111111111111111111111111111111111111111

步骤三: 手动触发案例02
img

结论:
也就是说AOF文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对的多条命令,生成一个新的文件后区替换原来的AOF文件。
AOF文件重写触发机制:通过redis.conf配置文件中的auto-aof-rewrite-percentage:默认值为100,以及auto-aof-rewrote-min-size:64mb配置,也就是说默认redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
重写原理:

  1. 在重写开始前,redis会创建一个“重写子进程”,这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
  2. 与此同时,主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
  3. 当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中
  4. 当追加结束后,redis就会用新的AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中
  5. 重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似

AOF优化配置项详解

配置文件APPEND ONLY MODE模块

配置指令 配置含义 配置示例
Appendonly 是否开启aof appendonly yes
Appendfilename 文件名称 appendfilename "appendonly.aof"
Appendfsync 同步方式 everysec/always/no
No-appendfsync-on-rewrite aof重写期间是否同步 no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage/auto-aof-rewrite-min-size 重写触发配置、文件重写策略 auto-aof-rewrite-percentage 100/auto-sof-rewrite-min-size 64mb

img

RDB+AOF混合持久化

img

数据恢复顺序和加载流程

在同时开启rdb 和aof 持久化时,重启时只会加载 aof 文件,不会加载 rdb文件
img

区别

RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾。

同时开启两种持久化方式

在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢。建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),留着rdb作为一个万一的手段。

RDB+AOF混合模式

结合两者的优点,既能快速加载又能避免丢失过多的数据。

  1. 开启混合方式设置
    设置aof-use-rdb-preamble的值为yes (yes表示开启,设置为no表示禁用)
  2. RDB+AOF的混合方式------>结论:RDB镜像做全量持久化,AOF做增量持久化
    先试用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB和AOF两部分恢复数据,既保证了数据完整性,又提高了恢复数据的性能。简单来说:混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。---> AOF包括了RDB头部+AOF混写。
    img

纯缓存模式

同时关闭RDB+AOF

  1. 禁用rdb
save ""

禁用rdb持久化模式下,我们仍然可以使用命令save、bgsave生成rdb文件

  1. 禁用aof
appendonly no

禁用aof持久化模式下,我们仍然可以使用命令bgrewriteaof生成aof文件

posted @ 2025-02-10 17:28  小肚腩吖  阅读(16)  评论(0)    收藏  举报