[toc]

总体介绍

Redis数据安全问题

官网介绍:http://www.redis.io

前面我们提到,Redis是一个缓存中间件,它的最大特点是使用内存从而使其性能强悍。
但是使用内存的方式有一个致命的特点就是数据没办法持久化保存。
然而Redis持久化存储有两种持久化方案,RDB(Redis DataBase)和 AOF(Append-Only File)。
其中RDB是将内存中的数据进行快照存储到磁盘,AOF则为可回放的命令日志记录redis内的所有操作。它们各有特点也相互独立。
Redis4之后支持RDB-AOF混合持久化的方式,结合了两者的优点,可以通过 aof-use-rdb-preamble 配置项可以打开混合开关。

img

什么是持久化

将内存中的数据写入到磁盘,永久保存

持久化的模式

  • RDB模式
  • AOF模式

RDB模式

快照持久化(RDB)

概述

  • RDB(Redis DataBase)是将Redis内存中的数据进行Snaptshot快照存储在磁盘内,是Redis的默认持久化方案。使用RDB持久化默认有三种策略,该持久化策略在redis.conf中可配置,会以一段时间内有指定次数据修改的规则触发快照动作,快照文件名为dump.rdb,该文件默认使用LZF压缩算法 。每当Redis服务重启的时候会从该文件中加载数据进内存。
  • RDB持久化除了可以根据配置中的策略触发,也可以手动触发,使用save和bgsave命令即可。这两个命令的区别的save会阻塞服务器进程,在进行save的过程中,服务器不能处理任何请求,而bgsave会通过一个子进程在后台处理rdb持久化。事实上save和bgsave调用的都是rdbSave函数,因此Redis不允许save和bgsave同时运行,这也是为了避免出现竞争导致rdb文件数据不准确。
  • bgsave操作使用CopyOnWrite机制进行写时复制,是由一个子进程将内存中的最新数据遍历写入临时文件,此时父进程仍旧处理客户端的操作,当子进程操作完毕后再将该临时文件重命名为dump.rdb替换掉原来的dump.rdb文件,因此无论bgsave是否成功,dump.rdb都不会受到影响。
  • 另外在主从全量同步、debug reload以及shutdown的情况下也会触发RDB数据持久化。

img

RDB模式含义

可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)并写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里

RDB备份执行

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

Fork

  1. Fork的作用是复制一 个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
  2. 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,Linux中引入了“写时复制技术”
  3. 一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

RDB执行流程、配置方式

RDB持久化流程

  1. 默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。

    • 你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。
  2. 在上文中我们已经在配置文件中做过对应的配置:

    • 例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:
      save 60 1000
  3. 当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:

    • Redis 调用 fork() ,同时拥有父进程和子进程。
    • 子进程将数据集写入到一个临时的 RDB 文件中。
    • 当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
  4. 这种方式使得 Redis 可以从写时复制机制中获益。

    img

快照持久化快照相关配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 编辑配置文件
vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis_6379.pid
loglevel notice
logfile /service/redis/6379/redis_6379.log
requirepass 123
dir "/etc/redis"
dbfilename dump.rdb
stop-write-on-bgsave-error yes
rdbchecksum yes
rdbcompression yes
save 900 1
save 300 10
save 60 10000

# 配置解析
save m n
## 配置快照(rdb),格式:save <seconds> <changes>
## 关闭该规则使用svae ""

save 900 1
## 900秒内至少有1个key被改变则做一次快照

save 300 10
## 300秒内至少有300个key被改变则做一次快照

save 60 10000
## 60秒内至少有10000个key被改变则做一次快照

dbfilename dump.rdb
## rdb持久化存储数据库文件名,默认为dump.rdb

stop-write-on-bgsave-error yes
## yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件。推荐yes。

rdbchecksum yes
## 在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
## 在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
## 推荐yes。

dir "/etc/redis"
## rdb数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,也可以修改,默认为Redis启动时命令行所在的目录下,请确保有写权限。

rdbcompression yes
## 对于存储到磁盘中的快照,可以设置是否开启RDB文件压缩,该功能可以节约磁盘空间。
## 如果是的话,redis会采用LZF算法进行压缩。
## 如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。
## 推荐yes。

RDB的优势和劣势

RDB优势

  1. RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适合用于备份。例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
  2. RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。
  3. RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。
  4. RDB在重启保存了大数据集的实例时比AOF要快。

img

RDB劣势

  1. 当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。
  2. RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。

RDB优缺点总结

  • 优点:对数据完整性和一致性要求不高更适合使用、适合大规模的数据恢复、节省磁盘空间、恢复速度快、主从复制也是基于RDB持久化功能实现的。
  • 缺点:会有数据丢失、导致服务停止几秒、消耗性能较高

img

AOF模式

AOF概述

  • AOF(Append-Only File)记录Redis中每次的写命令,类似mysql中的binlog,服务重启时会重新执行AOF中的命令将数据恢复到内存中,RDB(按策略持久化)持久化方式记录的力度不如AOF(记录每条写命令),因此很多生产环境都是开启AOF持久化。
  • AOF中记录了操作和数据,在日志文件中追加完成后才会将内存中的数据进行变更。
  • AOF(append only file)只追加文件,记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。
  • AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。

AOF执行流程、配置方式

AOF持久化流程

  • 客户端的请求写命令会被append追加到AOF缓冲区内;
  • AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
  • AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
  • Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

img

AOF持久化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
开启了AOF之后,RDB就默认不使用了。使用下面的配置开启AOF以及策略。(如果使用AOF,推荐选择always方式持久化,否则在高并发场景下,每秒钟会有几万甚至百万条请求,如果使用everysec的方式的话,万一服务器挂了那几万条数据就丢失了)。

# 开启AOF持久化
appendonly yes

# AOF文件名
appendfilename "appendonly.aof"

# AOF文件存储路径 与RDB是同一个参数
dir "/opt/app/redis6/data"

# AOF策略,一般都是选择第一种[always:每个命令都记录],[everysec:每秒记录一次],[no:看机器的心情高兴了就记录]
appendfsync always
# appendfsync everysec
# appendfsync no

# aof文件大小比起上次重写时的大小,增长100%(配置可以大于100%)时,触发重写。[假如上次重写后大小为10MB,当AOF文件达到20MB时也会再次触发重写,以此类推]
auto-aof-rewrite-percentage 100

# aof文件大小超过64MB时,触发重写
auto-aof-rewrite-min-size 64mb

# 是否在后台写时同步单写,默认值no(表示需要同步).这里的后台写,表示后台正在重写文件(包括bgsave和bgrewriteaof.bgrewriteaof网上很多资料都没有涉及到。其实关掉bgsave之后,主要的即是aof重写文件了).no表示新的主进程的set操作会被阻塞掉,而yes表示新的主进程的set不会被阻塞,待整个后台写完成之后再将这部分set操作同步到aof文件中。但这可能会存在数据丢失的风险(机率很小),如果对性能有要求,可以设置为yes,仅在后台写时会异步处理命令.
no-appendfsync-on-rewrite no

# 指redis在恢复时,会忽略最后一条可能存在问题的指令。默认值yes。即在aof写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes会log并继续,而no会直接恢复失败.
aof-load-truncated yes

AOF持久化策略

AOF分别有三种备份策略,分别是:

  • always:每个命令都记录
  • everysec:每秒记录一次
  • no:看机器的心情高兴了就记录

针对这三种策略给出如下说明。

策略说明

策略 说明 优点 缺点
Always 每次执行,都会持久化到AOF文件中 不丢失数据 IO开销大
Everysec 每秒持久化一次 减少IO 丢1秒钟的数据
No 根据服务器性能持久化 全自动 不可控

AOF重写机制

AOF重写机制概述

因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。
举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。
然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。
为了处理这种情况, Redis 支持一种有趣的特性:

  • 可以在不断服务客户端的情况下,对 AOF 文件进行重建。
  • 执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件包含重建当前数据集所需的最少命令。

AOF重写配置

配置名 含义
appendonly 开启AOF持久化功能
auto-aof-rewrite-min-size 触发重写的最小尺寸
auto-aof-rewrite-percentage AOF文件增长率
aof_current_size AOF当前尺寸
aof_base_size AOF上次启动和重写的尺寸(单位:字节)

AOF重写触发机制

1
2
3
# 根据配置,AOF持久化触发机制如下:
1.aof_current_size > auto-aof-rewrite-min-size
2.(aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage

AOF重写流程

  1. bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
  2. 主进程fork出子进程执行重写操作,保证主进程不会阻塞。
  3. 子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
  4. 子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。
  5. 主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
  6. 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

img

AOF的优点和缺点

AOF优点

img

  1. 使用AOF Redis会更具有可持久性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。
  2. AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。
  3. 当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。
  4. AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。

总结:

  1. 备份机制更稳健,丢失数据概率更低。
  2. 可读的日志文本,通过操作AOF稳健,可以处理误操作。

AOF缺点

  1. 对同样的数据集,AOF文件通常要大于等价的RDB文件。
  2. AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。
  3. 在过去,我们经历了一些针对特殊命令(例如,像BRPOPLPUSH这样的阻塞命令)的罕见bug,导致在数据加载时无法恢复到保存时的样子。这些bug很罕见,我们也在测试套件中进行了测试,自动随机创造复杂的数据集,然后加载它们以检查一切是否正常,但是,这类bug几乎不可能出现在RDB持久化中。为了说得更清楚一点:Redis AOF是通过递增地更新一个已经存在的状态,像MySQL或者MongoDB一样,而RDB快照是一次又一次地从头开始创造一切,概念上更健壮。
  4. 注意
    1. 要注意Redis每次重写AOF时都是以当前数据集中的真实数据从头开始,相对于一直追加的AOF文件(或者一次重写读取老的AOF文件而不是读内存中的数据),对bug的免疫力更强。
    2. 我们还没有收到一份用户在真实世界中检测到崩溃的报告。

总结:

  1. 比起RDB占用更多的磁盘空间。
  2. 恢复备份速度要慢。
  3. 每次读写都同步的话,有一定的性能压力。
  4. 存在个别Bug,造成恢复不能。

AOF持久化优缺点总结

  • 优点:可以最大程度保证数据不丢失
  • 缺点:日志记录量级比较大

img

RDB与AOF抉择

RDB与AOF比较

命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 丢数据 根据策略的不同,丢数据的情况也不同
轻重

官网建议

  1. RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
  2. AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.
  3. Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
  4. 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
  5. 同时开启两种持久化方式
  6. 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
  7. RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?
    建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份), 快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
  8. 性能建议
    因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
    如果使用AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。
    代价,一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。
    只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。
    默认超过原大小100%大小时重写可以改到适当的数值。

img

个人建议

  1. 一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
  2. 如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
  3. 有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也较之快,还避免了AOF引擎的bug。
  4. 个人感触:在企业中,通常都使用RDB来做持久化,因为一般redis是在做MySQL的缓存,就算缓存数据丢失,真实的数据还是在MySQL中,之所以用缓存是为了速度,性能而考虑,所以还是建议使用RDB持久化,相对来说会好一些,除非专门用redis来做一个key:value的数据库,而且数据很重要,那么可以考虑使用AOF
  5. 注意:基于这些原因,将来我们可能会统一AOF和RDB为一种单一的持久化模型(长远计划)。

RDB与AOF之间的优劣势

  • RDB

    • 优点
      1. 压缩后的二进制文件,速度快,适合于用作备份、全量复制及灾难恢复。
      2. 主从复制也是基于RDB持久化功能实现的
      3. RDB恢复数据性能优于AOF方式。
    • 缺点
      1. 无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
      2. 保存后的二进制文件,不同版本直接存在兼容性问题
      3. 会有数据丢失、导致服务停止几秒
  • AOF

    • 优点
      1. 以文本形式保存,易读
      2. 记录写操作保证数据不丢失
    • 缺点
      1. 存储所有写操作命令,且文件为文本格式保存,未经压缩,文件体积高。
      2. 恢复数据时重放AOF中所有代码,恢复性能弱于RDB方式。
  • RDB 和 AOF 之间的相互作用

    1. 在版本号大于等于 2.4 的 Redis 中, BGSAVE 执行的过程中,不可以执行 BGRWRITEAOF 。反过来说,在 BGRWRITEAOF 执行的过程中,也不可以执行 BGSAVE 。
    2. 这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。如果 BGSAVE 正在执行,并且用户显示地调用 BGRWRITEAOF 命令,那么服务器将向用户回复一个 OK 状态,并告知用户,BGRWRITEAOF 已经被预定执行; 一旦 BGSAVE 执行完毕, BGRWRITEAOF 就会正式开始。
    3. 当 Redis 启动时,如果 RDB 持久化和 AOF 持久化都被打开了,那么程序会优先使用 AOF 文件来恢复数据集,因为 AOF 文件所保存的数据通常是最完整的。

AOF与RDB混合

看了上面的RDB和AOF的介绍后,我们可以发现,使用RDB持久化会有数据丢失的风险,但是恢复速度快,而使用AOF持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从Redis4之后新增了混合AOF和RDB的模式,先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB何AOF两部分恢复数据,即保证了数据完整性,又提高了恢复的性能。

开启混合模式后,每当bgrewriteaof命令之后会在AOF文件中以RDB格式写入当前最新的数据,之后的新的写操作继续以AOF的追加形式追加写命令。当redis重启的时候,加载 aof 文件进行恢复数据:先加载 rdb 的部分再加载剩余的 aof部分。

混合配置

1
2
# 修改下面的参数即可开启AOF,RDB混合持久化
aof-use-rdb-preamble yes

混合模式示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
开启混合持久化模式后,重写之后的aof文件里和rdb一样存储二进制的快照数据,继续往redis中进行写操作,后续操作在aof中仍然是以命令的方式追加。因此重写后aof文件由两部分组成,一部分是类似rdb的二进制快照,另一部分是追加的命令文本。

# step1: 进入Redis, 写入数据
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set name alvin
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> set add 上海
OK
127.0.0.1:6379> exit

# Step 2: 查看备份文件
[root@alvin-test-os redis]# ll data/
总用量 8
-rw-r--r--. 1 root root 121 1124 15:39 appendonly.aof
-rw-r--r--. 1 root root 116 1124 15:39 dump.rdb

[root@alvin-test-os redis]# cat data/appendonly.aof | grep add
add
[root@alvin-test-os redis]# cat data/appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$5
alvin
*3
$3
set
$3
age
$2
18
*3
$3
set
$3
add
$6
上海

# Step 3: 启动备份
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379> exit

# Step 4: 查看配置文件发现AOF备份文件变成了二进制文件
[root@alvin-test-os redis]# cat data/appendonly.aof
REDIS0009� redis-ver6.0.9
�edis-bits�@�ctime��_used-mem��4
aof-preamble���namealvinadd上海age���6����&
[root@alvin-test-os redis]#

# Step 5: 再次写入文件
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set company 上海
OK
127.0.0.1:6379> exit

# Step 6:再次查看备份文件发现被分成了两份,一份二进制,一份AOF备份
[root@alvin-test-os redis]# cat data/appendonly.aof
REDIS0009� redis-ver6.0.9
�edis-bits�@�ctime��_used-mem��4
aof-preamble���namealvinadd上海age���6����&*2
$6
SELECT
$1
0
*3
$3
set
$7
company
$15
上海

RDB备份

Redis如何备份

  1. Redis 对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建,就不会进行任何修改。
  2. 当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。
  3. 这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。

建议:

  1. 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
  2. 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
  3. 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。

执行步骤

  • 备份
    1. 先通过config get dir 查询rdb文件的目录
    2. 将*.rdb的文件拷贝到别的地方
  • 恢复
    1. 先停止redis
    2. 将rdb文件放到指定目录下
    3. 启动redis

停止备份

在配置文件中就设置save ""或在命令行中config set save ""

手动开始备份

  • save:会立即生成dump.rdb,但是会阻塞往redis内存中写入数据。
  • bgsave:后台异步备份。
  • 如果是使用flushdb命令,会把之前的快照更新成当前的空状态,所以执行了flushdb后更新的快照是没有数据的。

save与bgsave对比

命令 save bgsave
IO类型 同步 异步
是否阻塞 否(阻塞发生在fork)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 创建fork,消耗内存

高级配置

RDB持久化高级配置

1
2
3
4
5
6
7
8
9
10
11
# 编辑配置文件
vim /etc/redis/6379/redis.conf

# 后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致
stop-writes-on-bgsave-error yes

# 导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做
rdbcompression yes

# 导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致
rdbchecksum yes

AOF持久化高级配置

1
2
3
4
5
6
7
8
9
10
11
# 编辑配置文件
vim /etc/redis/6379/redis.conf

# 正在导出rdb快照的过程中,要不要停止同步aof
no-appendfsync-on-rewrite yes

# aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次
auto-aof-rewrite-percentage 100

# aof文件,至少超过64M时,重写
auto-aof-rewrite-min-size 64mb