Redis系列(1) — 单机版安装及数据持久化

1,511 阅读16分钟

系列专栏:Redis系列专栏

单机版 Redis 安装

注:本系列使用的 Redis 版本为 6.2.5,测试环境为本地Docker容器虚拟机,系统为 CentOS 7

先来搭建一个单机版的Redis,开始前需先下载两个安装包:

我本机虚拟机IP为 172.17.0.2,将这两个安装包上传到服务器 /usr/local/src 目录下。

解压安装

切到 /usr/local/src 目录下

# cd /usr/local/src

解压安装tcl,如果未先安装tcl,安装redis时会报错提示需要tcl。

# tar -zxvf tcl8.5.10-src.tar.gz

# cd tcl8.5.10/unix/

# ./configure

# make & make install

解压安装redis。

# cd /usr/local/src

# tar -zxvf redis-6.2.5.tar.gz

# cd redis-6.2.5

# make && make test

# make install

Redis启动方案

  • 1、启动脚本

utils 目录下有个 redis_init_script 脚本,这是 redis 的启动脚本,将其拷贝到 /etc/init.d 目录下,并重命名为 redis_6379,表明 redis 想要监听 6379 端口。

# cd /usr/local/src/redis-6.2.5/utils/

# cp redis_init_script /etc/init.d/

# cd /etc/init.d/

# mv redis_init_script redis_6379

在 redis_6379 脚本中,可以看到如下配置:

  • REDISPORT:Redis 端口,默认为 6379
  • EXEC:redis 服务端
  • CLIEXEC:redis 客户端
  • PIDFILE:redis 程序运行后会生成一个 PID 文件,就是 /var/run/redis_6379.pid
  • CONF:redis 配置文件位置,/etc/redis/6379.conf

image.png

  • 2、修改配置

CONF 指定了 redis 配置文件目录为 /etc/redis/,文件名称为 6379.conf

先创建配置文件目录、数据持久化目录、日志目录:

# mkdir -p /etc/redis

# mkdir -p /var/redis/6379

# mkdir -p /var/redis/log

将配置文件 redis.conf 复制到 /etc/redis 下,并重命名为 6379.conf,然后给读写权限:

# cp /usr/local/src/redis-6.2.5/redis.conf /etc/redis

# cd /etc/redis/

# mv redis.conf 6379.conf

# chmod +666 6379.conf

修改 6379.conf 中的配置,主要修改如下几项,其它保持默认即可:

配置说明
daemonizeyes让 redis 以 daemon 进程运行
bind本机IP(10.211.55.5)绑定本机IP,否则外部无法访问 redis
protected-modeno默认启用了保护模式,关闭后外部才能访问
pidfile/var/run/redis_6379.pid设置 redis 的 pid 文件位置
port6379设置redis的监听端口号
dir/var/redis/6379设置持久化文件的存储位置
logfile/var/redis/log/6379.log设置日志文件位置

注意修改了 bind 之后,还需修改 /etc/init.d/redis_6379 启动脚本,指定停止服务端的 IP:

image.png

  • 3、开机启动

修改 redis_6379 启动脚本,在上面添加如下两行注释:

# cd /etc/init.d/

# vim redis_6379

添加如下两行注释:

# chkconfig: 2345 90 10 
# description: Redis is a persistent key-value database

配置开机启动:

CentOS:

# chkconfig redis_6379 on
  • 4、启动 redis
# cd /etc/init.d

# ./redis_6379 start

验证 redis 是否启动成功:

# ps -ef|grep redis

image.png

  • 5、客户端连接

通过 redis-cli 命令连接服务端:

# redis-cli -h 172.17.0.2

并做一些简单的命令测试:

[root@centos-01 init.d]# redis-cli -h 172.17.0.2
172.17.0.2:6379> set name bojiangzhou
OK
172.17.0.2:6379> get name
"bojiangzhou"

数据持久化

持久化的意义

Redis 一般都是用来做缓存,数据都是在内存中的,一旦 Redis 宕机或者 Redis 所在服务器宕机等,就会导致内存中的数据可能全部丢失,这时可能就会费很大劲去恢复原来的数据。如果重新从数据库查数据再缓存到 Redis 中,这会给数据库带来巨大压力,而且会让使用这些缓存数据的应用程序也变慢。

所以对 Redis 来说,实现数据的持久化,避免从后端数据库中进行恢复,是至关重要的。如果没有持久化的话,Redis 遇到灾难性故障的时候,就会丢失所有数据。

对于生产级 Redis 架构来说,持久化也是必不可少的,持久化主要就是做灾难恢复、数据恢复的,这样才能保证 Redis 的高可用性。这样在 Redis 变得不可用后,就能尽快让 Redis 恢复,变得可用,进而对外提供服务。

Redis 的持久化主要有两大机制:AOF(Append Only File) 日志和 RDB(Redis DataBase) 快照。如果我们想 redis 仅仅作为纯内存的缓存来用,那么可以禁止 RDB 和 AOF 的持久化机制。

AOF 日志

AOF 机制是把每条写入命令作为日志,以 append-only 的模式写入一个日志文件中,在 redis 重启的时候,可以通过回放 AOF 日志中的写入指令来重新构建整个数据集。

  • 1、写后日志

我们可能比较熟悉写前日志(WAL),就是先写日志,再写数据;AOF 则是写后日志,就是先执行命令,把数据写入内存,然后才记录日志。

这是因为 AOF 记录的是执行命令,先执行命令,只有命令执行成功后才记录日志,否则就直接向客户端报错。在记录日志的时候就不用去对这些命令进行语法检查,可以避免额外的检查开销。

不过这种写后日志机制也有一定风险,就是命令执行完,还没来得及记日志就宕机了,这个命令和数据就可能丢失了。不过这种影响一般来说也不大,还可以从数据库恢复数据。

  • 2、写回策略

打开 AOF 持久化机制之后,要知道日志并不是直接直接写入到磁盘的,会先写入AOF 缓冲区,就是操作系统缓冲区(os cache),然后每隔一定时间再 fsync 将缓冲区的数据同步到磁盘文件中。

这就涉及到 fsync 同步的三种时机了:

  • always:同步写回,每次写日志,立马调用 fsync 将日志写回磁盘。
  • everysec:每秒写回,每秒调用一次 fsync 把缓冲区的内容写入磁盘。这是默认值。
  • no:由操作系统决定何时将缓冲区内容写回磁盘。

三种写回策略的优缺点:

写回策略写回时机优点缺点
always同步写回可靠性高,数据基本不丢失每个写命令都要立即落盘,对性能影响很大,导致吞吐量很低
everysec每秒写回性能适中宕机时会丢失1秒内的数据
no操作系统控制性能好这种策略不由redis控制,可能会导致大量数据丢失

每种策略各有优缺点,所以我们需要根据系统对高性能和高可靠性的要求,来选择合适的写回策略。想要获得高性能,就选择 no 策略;如果想要得到高可靠性保证,就选择 always 策略;如果允许数据有一点丢失,又希望性能别受太大影响的话,那么就选择 everysec 策略。一般使用默认的 everysec 策略即可。

  • 3、AOF 重写机制

Redis 只会写一个 AOF 文件,所以如果不断往这个文件写日志,这个文件就会越来越大。

AOF 文件过大就会带来一些性能问题:

  • 文件系统本身对文件大小有限制,无法保存过大的文件
  • 文件太大,再往里面追加命令记录的话,效率也会变低
  • 如果要做灾难恢复,就要重放日志文件中的所有命令,整个恢复过程就会非常缓慢,会影响到 Redis 的正常使用

所以,在 AOF 文件大到一定程度时,Redis 就会做 AOF重写(rewrite)操作。

AOF 重写就是基于当时内存中的数据,创建一个新的 AOF 文件,读取数据库中的所有键值对,然后对每一个键值对用一条写入命令记录到新的AOF文件中。这样就能构造一个更小的 AOF 文件,然后将旧的很大的文件给删了。

那 AOF 重写时会阻塞主线程吗?

其实 AOF 重写过程是由后台子进程 bgrewriteaof 来完成的,这样主线程就可以继续处理命令请求了。每次执行重写时,主线程会 fork 出后台的 bgrewriteaof 子进程,并把主线程的内存拷贝一份给 bgrewriteaof 子进程。然后,bgrewriteaof 子进程就可以在不影响主线程的情况下,把数据读出来转成命令写入新的AOF文件。

不过,使用子进程有一个问题。在子进程在进行 AOF 重写期间,主线程还可以继续处理写命令请求,这就会使得服务器的数据库状态和重写后的AOF文件所保存的数据库状态不一致。

于是 redis 服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用。当主线程执行完一个写命令之后,它会同时将这个写命令发送给 AOF缓冲区AOF重写缓冲区

当子进程完成 AOF 重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会阻塞主线程,接着将 AOF重写缓冲区 中的命令追加到新的AOF文件中,这时新AOF文件中的数据状态和主线程的数据状态就是一致的了。最后再删除原来的AOF文件,对新的AOF文件改名,就完成了新旧两个文件的替换。

也就是说在整个AOF后台重写过程中,只有收到信号后的阶段会对服务器进程造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。

对整个AOF非阻塞的重写过程画张图总结下:

AOF 重写机制.jpg

RDB 快照

用AOF日志文件进行故障恢复,需要逐一把日志中的命令都执行一遍,如果操作日志非常多,恢复就会很缓慢。

这时就有了另一种可以快速恢复的持久化机制:RDB 内存快照。

所谓内存快照,就是将内存中的数据在某一个时刻的状态写到磁盘文件中。和 AOF 相比,RDB 记录的是某一时刻的数据,而不是命令,所以,在做数据恢复时,可以直接把 RDB 文件读入内存,很快地完成恢复。

1、生成 RDB 快照

Redis 有两个命令可以用于生成 RDB 快照:

  • save:会阻塞redis主线程,服务器不能处理任何命令请求,直到RDB文件创建完毕为止。

  • bgsave:会 fork 出一个子进程,由子进程负责创建RDB文件,主线程继续处理命令请求。

生成 RDB 快照每次都是执行全量快照,全量数据越多,RDB 文件就越大,往磁盘上写数据的时间开销就越大。所以一般生成 RDB 快照时是使用 bgsave 在后台进行,这也是默认的配置。

生成快照时,数据会先写入到一个临时 RDB 文件中,当完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

另外,三个命令 savebgsavebgrewriteaof 不会同时执行,主要就是避免并发竞争或并发执行大量的磁盘写入影响主线程的性能。

2、写时复制

bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。

但主线程还可以接收写命令,在生成快照期间,内存的数据可能就被改变了,这就会破坏快照的完整性。

为了不阻塞主线程的写操作,Redis 借助了操作系统的写时复制(Copy-On-Write, COW)技术:

  • 如果主线程是读操作,那么主线程和 bgsave 子进程相互不影响。
  • 如果主线程要修改一块数据,那么这块数据就会被复制一份,生成该数据的副本。然后,主线程在这个数据副本上进行修改。bgsave 子进程则可以继续把原来的数据写入 RDB 文件。

写时复制技术使得在执行快照的同时,主线程可以正常处理写请求,这样既保证了快照的完整性,也不会影响主线程的性能。

3、快照时机

我们可以手动调用save或者bgsave命令,同步或异步执行 RDB 快照生成。

在 redis 配置文件中,可以通过 save 设置多个保存点,每到一个保存点,就会检查是否有指定数量的key发生了变更,如果有,就会生成一个新的 RDB 快照。

例如:

  • save 3600 1:3600 秒内有1个key变更
  • save 300 100:300秒内有100个key变更
  • save 60 10000:60秒内有一万个key变更

AOF 和 RDB 对比

1、AOF 优点

  • AOF 可以更好的保护数据不丢失,一般设置 AOF 每隔1秒执行 fsync 操作,最多丢失1秒钟的数据。

  • AOF 日志文件以 append-only 模式写入,写入性能非常高,而且文件不容易破损。

  • 当 AOF 文件变得很大时,Redis 会自动在后台进行重写,也不会影响主线程的性能。

  • AOF 记录的是一个个操作命令,文件内容很容易阅读和分析,这个特性非常适合做灾难性的误删除的紧急恢复。如果不小心错误地使用 FLUSHALL 命令清空一切,只要 AOF 文件未被重写,这时只需停止服务器,删除最后一条命令,然后重启 Redis 就可以恢复了。

2、AOF 缺点

  • 对于同一份数据来说,AOF 日志文件通常比 RDB 数据快照文件更大。而且恢复时要重放所有命令,恢复速度比 RDB 慢。

  • AOF 开启后,一般会配置成每秒执行 fsync,相比 RDB,AOF 对redis的性能影响更大。不过通常每秒执行一次 fsync 的性能仍然很高。

  • AOF 不适合做冷备,一是数据恢复比较慢,二是定期备份不太方便,可能要自己手写复杂的脚本去做。

3、RDB 优点

  • RDB 是一个非常紧凑的文件,它保存了过去某个时刻的数据集,每隔一段时间就会生成一个新的 RDB 文件。这种特性非常适用于数据的冷备份灾难恢复,比如可以每个小时保存一下过去24小时内的数据,每天保存过去30天的数据,然后可以将这些文件发送到一些远程的安全存储上去,在出问题时就可以根据需求恢复到不同时间点的数据集。

  • RDB 快照是在 fork 的子进程中完成的,对 redis 主线程对外提供读写服务的性能影响非常小。而 AOF 在每次执行写命令都会写磁盘,虽然是先写入缓存,再 fsync 到磁盘,但速度肯定比 RDB 略慢一点。

  • 当要恢复的数据集很大的时候,直接基于 RDB 文件来重启和恢复比基于 AOF 恢复更快速。

4、RDB 缺点

  • 一般 RDB 快照文件,都是每隔5分钟,或者更长时间生成一次,一旦 redis 宕机,那么就可能丢失最近5分钟的数据。如果依赖 RDB 做第一优先恢复方案,会导致丢失的数据比较多。

  • 执行 RDB 需要 fork 子进程,当数据比较大时,fork 的过程会比较耗时,就可能会导致对客户端提供的服务暂停数毫秒,甚至数秒。所以 RDB 的频率也不宜多大。

5、如何选择

如果我们想要 redis 仅仅作为纯内存的缓存来用,可以禁止 RDB 和 AOF 的持久化机制。

当然在生产环境中,一般都是同时使用 AOF 和 RDB 两种持久化机制:

  • 如果只使用 RDB,那样可能会导致丢失很多数据。

  • 如果只使用 AOF,它不适合做冷备,灾难恢复时也没有 RDB 恢复速度快。

  • 所以要综合使用 AOF 和 RDB 两种持久化机制:

    • AOF 用来保证数据不丢失,作为恢复数据的第一选择方案。

    • RDB 用来做周期性的冷备,在 AOF 文件丢失或不可用的时候,可以用 RDB 来进行快速的数据恢复。

如果同时使用 RDB 和 AOF 两种持久化机制,在 redis 重启的时候,会使用 AOF 来重新构建数据,因为 AOF 中的数据更加完整。

AOF 持久化

1、开启 AOF

AOF 持久化默认是关闭的,默认是打开的是 RDB 持久化。

AOF 相关有如下几项配置:

配置默认值说明
appendonlyno是否开启AOF
appendfilename"appendonly.aof"AOF文件名称
appendfsynceverysecfsync 策略,可选值有:always/everysec/no

只需要设置 appendonly yes 就可以开启 AOF。

2、验证 AOF 恢复数据

配置修改后,停止 redis,删除数据目录下的文件,然后再重启 redis:

# cd /etc/init.d/

# ./redis_6379 stop

# rm -rf /var/redis/6379/*

# ./redis_6379 start

此时就可以看到数据目录下已经生成一个 appendonly.aof 文件了:

# cd /var/redis/6379/ && ls
appendonly.aof

连接 redis 客户端,写入一条命令:

# redis-cli -h 172.17.0.2

# 172.17.0.2:6379> set name bojiangzhou

查看AOF文件,可以看到命令已经写入:

[root@centos-01 /]# cat /var/redis/6379/appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$11
bojiangzhou

此时再 kill -9 杀掉 redis 进程(模拟redis故障宕机),并删除 pid 文件,再重启 redis:

[root@centos-01 /]# ps -ef|grep redis
root     21781     1  0 06:28 ?        00:00:01 /usr/local/bin/redis-server 172.17.0.2:6379
root     21800   157  0 06:33 pts/0    00:00:00 grep --color=auto redis

[root@centos-01 /]# kill -9 21781

[root@centos-01 /]# rm -rf /var/run/redis_6379.pid

[root@centos-01 /]# ./etc/init.d/redis_6379 start
Starting Redis server...

再用客户连接redis,验证数据还在,这就是从AOF恢复的数据:

[root@centos-01 /]# redis-cli -h 172.17.0.2 
172.17.0.2:6379> get name
"bojiangzhou"

3、AOF 重写

可以手动发送 bgrewriteaof 命令去执行 AOF 重写,不过一般都是由 redis 后台自动执行 AOF 重写。

AOF 重写有如下几项参数:

配置默认值说明
auto-aof-rewrite-percentage100相比上一次重写文件大小的增长比例
auto-aof-rewrite-min-size64mbAOF 重写时文件的最小大小,默认为 64MB
no-appendfsync-on-rewriteno执行重写时,AOF不要执行 fsync
  • 重写时机

AOF 重写的时机由前两个参数来控制,首先 AOF 文件要大于 auto-aof-rewrite-min-size,其次 AOF 文件大小相比上一次 AOF 重写后的文件大小,要超过 auto-aof-rewrite-percentage 这个比例,才会执行重写。

比如一个 AOF 文件达到 64mb 后就可以执行重写,之后会接着重写后的 AOF 文件继续追加日志,达到 128mb 后,文件大小超过 64mb,且 (128-64)/64 * 100% = 100%,增量比例也达到 100% 了,就可以执行重写了。

  • no-appendfsync-on-rewrite

bgrewriteaof 往往会涉及大量磁盘操作,这样就会造成主线程在写 AOF 文件的时候出现阻塞的情形,这时就可以调整 no-appendfsync-on-rewrite 参数:

① 设置为 no:AOF 重写时,主线程还是按照 appendfsync 既定的策略执行 fsync 操作。这样不会丢失数据,但需要忍受一定的阻塞。

② 设置为 yes:这就相当于在重写时将 appendfsync 设置为 no,这样就不会造成磁盘IO阻塞,但可能会丢失一些数据。

如果应用系统无法忍受延迟,可以容忍少量的数据丢失,则设置为 yes。如果应用系统无法忍受数据丢失,则设置为no

4、AOF 破损文件修复

Redis 在 append 数据到 AOF 文件时,可能服务器正好停机了,这可能会导致 AOF 文件破损。Redis 重启时就会拒绝载入这个破损的 AOF 文件。

发生这种情况时,先备份下 aof 文件,然后用 redis-check-aof --fix 命令来修复破损的 AOF 文件,它可能就是把有问题的命令删掉。然后再重启 Redis 即可。

RDB 持久化

1、RDB 配置

RDB 快照有如下几项配置:

配置默认值说明
savesave 3600 1
save 300 100
save 60 10000
RDB 快照检查点
stop-writes-on-bgsave-erroryesRDB 保存数据失败后,Redis 是否停止接收数据
rdbcompressionyes是否对RDB文件进行压缩存储
rdbchecksumyes是否对快照文件进行校验
dbfilenamedump.rdbRDB 文件名称

2、快照时机

可以通过 savebgsave 两个命令来手动生成 RDB 快照,不过一般也是由 redis 后台自动自行。

RDB 机制默认开启,如果想关闭,可对 save 配置一个空字符串:

save ""

RDB 默认执行快照的检查点:

save 3600 1
save 300 100
save 60 10000
  • 60 秒内有 10000 个 key 发生变更,就生成 RDB 快照
  • 300 秒内有 100 个 Key 发生变更,就生成 RDB 快照
  • 3600 秒内有 1 个 key 发生变更,就生成 RDB 快照

我们可以根据实际的需求设置多个检查点,或者调整生成 RDB 快照的频率。

3、验证 RDB 恢复数据

只有在 AOF 机制关闭时,服务器才会使用 RDB 文件来还原数据状态,所以先将 AOF 关闭:

appendonly no

然后设置一个检查点:10秒内有1个key发生变更就生成 RDB 文件

save 10 1

然后停止 redis、删除数据目录下的文件,重启 redis:

# cd /etc/init.d/

# ./redis_6379 stop

# rm -rf /var/redis/6379/*

# ./redis_6379 start

接着客户端连接redis,写入一条数据:

# redis-cli -h 172.17.0.2
172.17.0.2:6379> set name bojiangzhou
OK
172.17.0.2:6379> get name
"bojiangzhou"

之后在 10 秒内 kill -9 杀掉 redis 进程,这时会发现数据目录下没有任何文件。

# ps -ef|grep redis
root       5829      1  0 20:30 ?        00:00:00 /usr/local/bin/redis-server 172.17.0.2:6379

# kill -9 5829

# rm -rf /var/run/redis_6379.pid

# cd /etc/redis/6379 && ls

注意:通过 redi-cli shutdown 这种方式一种安全退出的模式,redis 在退出的时候会将内存中的数据立即生成一份完整的 RDB 快照。

再重启 redis,就会发现数据丢失了。这就说明还没来得及生成RDB快照,redis宕机,就丢失了这 10 秒的数据了。

# ./redis_6379 start

# redis-cli -h 172.17.0.2
172.17.0.2:6379> get name
(nil)

按上面同样的操作,在 10 秒后再 kill 掉 redis 进程,会发现数据目录下就生成了 dump.rdb 文件了。

# cd /var/redis/6379/ && ls
dump.rdb

此时再重启,会发现数据也还在,这就验证了使用 RDB 文件来恢复数据。

验证完成之后,还是开启AOF:appendonly yes

再将设置的检查点 save 10 1 删掉 。

数据备份

前面说过,RDB 快照适合做冷备份,为了防止 AOF 和 RDB 文件损坏或丢失,一般生产环境中还会对 RDB 文件做一些定时备份。一般就是每个小时保存一下过去24小时内的数据,每天保存过去30天的数据。

可以将这些文件发送到一些远程的安全存储上去,简单点也可以放到本机的其它目录,例如我下面将RDB文件备份到本地 /usr/local/redis/snapshot 目录下。

1、每小时备份

每小时备份一次 dump.rdb,然后删除24小时以前的数据。

/etc/redis 下 创建 redis_rdb_hourly_backup.sh 脚本文件:

#!/bin/sh

# 备份目录
dir=/usr/local/redis/snapshot

# 当前日期时间(yyyyMMddHH)
cur_date=`date +%Y%m%d%H`

# 创建新的目录
rm -rf $dir/$cur_date
mkdir -p $dir/$cur_date

# RDB文件拷贝到备份目录
cp /var/redis/6379/dump.rdb $dir/$cur_date

# 删除24小时以前的目录
del_date=`date -d -24hour +%Y%m%d%k`
rm -rf $dir/$del_date

可以执行一次脚本做验证,可以看到目录下已经创建了当前小时的目录,且 dump.rdb 也复制过去了。

# sh redis_rdb_hourly_backup.sh

# ls /usr/local/redis/snapshot/
2021090100

# ls /usr/local/redis/snapshot/2021090100/
dump.rdb

然后创建 crontab 调度,每小时运行一次这个脚本:

# crontab -e

0 * * * * sh /etc/redis/redis_rdb_hourly_backup.sh

2、每天备份

每小时备份一次 dump.rdb,然后删除一个月以前的数据。

/etc/redis 下创建 redis_rdb_daily_backup.sh 脚本文件:

#!/bin/sh

# 备份目录
dir=/usr/local/redis/snapshot

# 当前日期时间
cur_date=`date +%Y%m%d`

# 创建新的目录
rm -rf $dir/$cur_date
mkdir -p $dir/$cur_date

# RDB文件拷贝到备份目录
cp /var/redis/6379/dump.rdb $dir/$cur_date

# 删除一个月以前的目录
del_date=`date -d -1month +%Y%m%d`
rm -rf $dir/$del_date

执行一次脚本做验证,可以看到目录下已经创建了当前天的目录,且 dump.rdb 也复制过去了。

# ls /usr/local/redis/snapshot/
20210901  2021090100

# ls /usr/local/redis/snapshot/20210901
dump.rdb

创建 crontab 调度,每天运行一次这个脚本:

# crontab -e

0 0 * * * sh /etc/redis/redis_rdb_daily_backup.sh

3、RDB 恢复数据

如果是 redis 进程或服务器挂掉了,只需重启 redis 进程,然后基于 AOF 日志文件恢复数据即可,如果同步策略是 appendfsync everysec,最多就丢失一秒的数据。

如果 redis 当前的 AOF 和 RDB 文件出现了损坏或丢失,这时就可以用最近备份的 RDB 副本来恢复数据。

如果因为某些原因把线上的缓存数据污染了,我们也可以选择某一个小时的备份数据来进行恢复。

然后按照下面的步骤来恢复数据即可:

  • 首先停止 redis

  • 修改配置文件 /etc/redis/6379.conf 关闭 AOF:appendonly no。因为 redis 启动时默认会用 AOF 来恢复数据,所以需要关闭 AOF

  • 删除 /var/redis/6379 下的 appendonly.aofdump.rdb 文件

  • 拷贝备份的 dump.rdb/var/redis/6379

  • 启动 redis,会发现数据就基于 dump.rdb 恢复了

  • 在 redis-cli 中热修改打开 AOF:config set appendonly yes,这时内存中的数据就会同步到 appendonly.aof 文件中,此时 AOF 和 RDB 两份文件的数据就同步了

  • 再手动修改 /etc/redis/6379.conf 文件,打开 AOF:appendonly yes

  • 可再次重启 redis