Redis 中的数据都是保存在内存中的,当Redis服务重启后,内存中的数据都会丢失,所以需要将内存中的数据保存到磁盘上,方便系统故障时,从磁盘上的备份数据恢复到内存中。
Redis 中的持久化方式有两种,RDB全量持久化和AOF增量持久化。在4.0及以后版本中,提供了一种混合持久化的功能,就是RDB和AOF结合的持久化模式。
分类如下:
RDB持久化方式是通过快照完成的。RDB程序将当前内存中的数据快照保存到磁盘中,在Redis重启时,RDB程序可以通过载入RDB文件来还原数据库的状态。
AOF(append only file),是以独立日志的方式记录每次的写命令,重启时在执行文件中的命令来达到恢复数据的目的。
混合模式就是同时结合了RDB持久化和AOF持久化混合写入AOF文件。这样就可以结合2者的优点了,快速的加载持久化文件,同时避免数据丢失过多。
RDB(Redis DataBase)是将某一个时刻的内存快照(Snapshot),以二进制的方式写入磁盘的过程。
触发方式
触发rdb持久化的方式有2种,分别是手动触发和自动触发。
(1)手动触发
手动触发分别对应save和bgsave命令:
bgsave流程图如下所示:
具体流程如下:
(2)自动触发
在以下4种情况时会自动触发:
快照周期:内存快照虽然可以通过技术人员手动执行SAVE或BGSAVE命令来进行,但生产环境下多数情况都会设置其周期性执行条件。
#周期性执行条件的设置格式为
save
#默认的设置为:
save 900 1 # 如果900秒内有1条Key信息发生变化,则进行快照;
save 300 10 # 如果300秒内有10条Key信息发生变化,则进行快照;
save 60 10000 # 如果60秒内有10000条Key信息发生变化,则进行快照。读者可以按照这个规则,根据自己的实际请求压力进行设置调整。
#以下设置方式为关闭RDB快照功能
save ""
其它相关配置
# RDB持久化数据库文件名,默认dump.rdb
dbfilename dump.rdb
# 数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,请确保有写权限
dir /home/work/app/redis/data/
# yes:代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no:表明忽略错误继续写文件。
stop-writes-on-bgsave-error yes
# 是否开启RDB文件压缩,yes默认开启压缩,no不开启
rdbcompression yes
# 在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动
rdbchecksum yes
配置查询
127.0.0.1:6379> config get dbfilename # 想要获取 RDB 文件的存储名称设置
127.0.0.1:6379> config get dir # 查询 RDB 的文件目录
优点
缺点
AOF(Append-Only File)记录Redis中每次的写命令,类似mysql中的binlog,服务重启时会重新执行AOF中的命令将数据恢复到内存中,RDB(按策略持久化)持久化方式记录的粒度不如AOF(记录每条写命令),因此很多生产环境都是开启AOF持久化。
AOF日志记录Redis的每个写命令,步骤分为:命令追加(append)、文件写入(write)和文件同步(sync)。
触发持久化
AOF 的触发条件分为两种:自动触发和手动触发。
(1)手动触发
在客户端执行 bgrewriteaof 命令就可以手动触发 AOF 持久化,如下图所示:
可以看出执行完 bgrewriteaof 命令之后,AOF 持久化就会被触发。
(2)自动触发
有两种情况可以自动触发 AOF 持久化,分为是:满足 AOF 设置的策略触发 和 满足 AOF 重写触发。其中,AOF 重写触发会在本文的后半部分详细介绍,这里重点来说 AOF 持久化策略,配置 Redis 多久才将数据 fsync(同步)到磁盘一次。
AOF 持久化策略,分为以下三种:
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
注:因为每次写入磁盘都会对 Redis 的性能造成一定的影响,所以要根据用户的实际情况设置相应的策略,一般设置每秒写入一次磁盘的频率就可以满足大部分的使用场景了。
# appendonly参数开启AOF持久化
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./
# 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
AOF持久化机制记录每个写命令,当服务重启的时候会复现AOF文件中的所有命令,会消耗太多的资源且重启很慢。因此为了避免AOF文件中的写命令太多文件太大,Redis引入了AOF的重写机制来压缩AOF文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。
把过期的,没有用的,重复的,可优化的命令简化为很小的aof文件。实际上是redis内存中的数据回溯成aof文件。
重写流程:
Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。
原理:混合持久化同样也是通过 bgrewriteaof 重写命令完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。
简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据。如图所示:
配置
#我们可以在appendonly yes命令 下面加上以下的配置,然后重启Reids
aof-use-rdb-preamble yes
本次实验redis版本由3.2.12升级到4.0.0,并开启混合持久化,迁移RDB数据,验证数据是否正常。
当Redis服务重启时数据恢复的顺序如下:
流程较为复杂,需要严格按照以下步骤:
# wget http://download.redis.io/releases/redis-3.2.12.tar.gz
# wget http://download.redis.io/releases/redis-4.0.0.tar.gz
tar -zxvf redis-3.2.12.tar.gz -C /data/
mv /data/redis-3.2.12 /data/redis
mkdir /data/redis/data
yum install -y gcc gcc-c++ make tcl-devel
cd /data/redis && make && # make负责编译,make install负责将二进制文件安装到/usr/local/bin
cd /data/redis/src && make install && make test # 测试确保编译无误
cp /data/redis/redis.conf /data/redis/redis.conf.bak
# redis-3.2.12.conf
supervised systemd
dir /data/redis/data
daemonize yes
pidfile /data/redis/redis.pid
port 6379
bind 0.0.0.0
requirepass w4RedisService
loglevel warning
maxclients 65535
tcp-backlog 10240
appendonly no
save 900 1
save 300 10
save 60 10000
maxmemory 50499420160
# /etc/systemd/system/redis.service
[Unit]
Description=Redis Single Service
After=network.target
[Service]
Type=notify
User=root
Group=root
TimeoutStartSec=120s
ExecStart=/data/redis/src/redis-server /data/redis/redis.conf
ExecStop=/data/redis/src/redis-cli shutdown -a w4RedisService
Restart=on-failure
RestartSec=30s
LimitNOFILE=100000
LimitNPROC=65535
[Install]
WantedBy=multi-user.target
插入数据
[root@localhost redis]# redis-cli -a w4RedisService
127.0.0.1:6379>set company1 huanle1
127.0.0.1:6379>set company2 huanle2
127.0.0.1:6379>set company3 huanle3
127.0.0.1:6379>bgsave
127.0.0.1:6379>exit
#重启服务
[root@localhost redis]#systemctl restart redis
tar -zxvf redis-4.0.0.tar.gz
cd redis-4.0.0
make
cd src && make install
make test
# # redis-4.0.0.conf
# 先不要开启aof相关配置,否则数据无法同步
supervised systemd
daemonize no
dir /data/redis/data
#pidfile /data/redis/redis.pid
port 6379
bind 0.0.0.0
requirepass w4RedisService
loglevel warning
maxclients 65535
tcp-backlog 10240
save 900 1
save 300 10
save 60 10000
maxmemory 50499420160
appendonly yes
aof-use-rdb-preamble yes
#重命名旧的目录和新版本目录
mv redis redis.bak
mv redis-4.0.0 redis
cd /data/redis/data
cp dump.rdb-bak dump.rdb
systemctl start redis
# 查看RDB数据是否已经恢复,命令行设置开启aof备份功能,执行命令后就会自动产生appendonly.aof这个文件,完成rdb和aof数据同步
[root@localhost redis]# redis-cli -a w4RedisService
127.0.0.1:6379> keys *
1) "company1"
2) "company2"
3) "company3"
127.0.0.1:6379> config set appendonly yes
127.0.0.1:6379> exit
# 接着关闭redis,配置文件中设置永久开启AOF持久化
[root@localhost redis]# systemctl stop redis
[root@localhost redis]# cat redis.conf
appendonly yes
[root@localhost redis]# systemctl start redis
# 配置混合持久化功能
[root@localhost redis]# redis-cli -a w4RedisService
127.0.0.1:6379> config set aof-use-rdb-preamble yes # 开启RDB+AOF混合持久化功能
OK
127.0.0.1:6379> bgrewriteaof # 手动触发AOF重写
Background append only file rewriting started
127.0.0.1:6379> set name hanjianjuan
OK
127.0.0.1:6379> quit
# 接着关闭reids,配置文件中设置永久开启混合持久化
[root@localhost redis]# systemctl stop redis
[root@localhost redis]# cat redis.conf
aof-use-rdb-preamble yes
[root@localhost redis]# systemctl start redis
结论:aof文件再经过bgrewriteaof之后,再次执行的命令会按照aof的方式进行存储,等下次再bgrewriteaof之后,再进行二进制存储。redis后台再进行bgrewriteaof的时候,这时候如果有客户端命令进来,会再后面进行追加。
redis详解之数据备份与恢复_redis备份和恢复_programmer_山风的博客-CSDN博客
Redis数据库备份、迁移、恢复实践_数据库_半隐退状态-华为云开发者联盟
Redis 数据备份和恢复_redis如何恢复数据_咸蛋黄派的博客-CSDN博客
Redis基本概念 - 简书
Redis-基本概念_redis定义_SeaDhdhdhdhdh的博客-CSDN博客
一文搞懂 Redis 架构演化之路
Redis设计与实现
redis架构_剑八-的博客-CSDN博客
Redis高可用方案—主从(masterslave)架构
Redis高可用架构—哨兵(sentinel)机制详细介绍
Redis高可用架构—Redis集群(Redis Cluster)详细介绍
Redis基本概念知识_redis 基本概念_Gatsby_codeLife的博客-CSDN博客
03 Redis 网络IO模型简介_redis的io模型_天秤座的架构师的博客-CSDN博客
Redis 详解_王叮咚的博客-CSDN博客