1 RDB 和 AOF 介绍
Redis
的存储分为内存存储、磁盘存储和log文件三部分
持久化:就是将内存中的数据,写入到磁盘上,并且永久保存。
持久化两种方式:
-
RDB
(全量数据) -
AOF
(增量请求)
RDB:Redis Database
,二进制格式,按事先定制的策略,周期性(point-in-time snapshot
)地将 redis
存储的数据生成快照并存储到磁盘等介质上,数据文件默认为dump.rdb
(查看:strings dump.rdb
),即,Redis
默认采用 rdb
方式实现数据的持久化,以快照的形式将数据持久化到磁盘的一个二进制文件dump.rdb
AOF:append only file
只追加文件,redis
会把服务器执行的所有写操作命令记录在一个日志文件里(类似于MySQL
的binlog
),并在redis
服务器启动时,通过重新执行这些命令来还原数据集。AOF
文件中的命令全部以 Redis
协议的格式来保存,新命令会被追加到文件的末尾。
当 Redis
启动时,如果 RDB
持久化和 AOF
持久化都被打开了,那么程序会优先使用 AOF
文件来恢复数据集,因为 AOF
优先级高于 RDB,且文件所保存的数据通常是最完整的,但,RDB
的恢复速度高于 AOF
注意:如果 AOF
没有数据,RDB
有数据的情况下,执行bgsave
,会导致redis
数据清零,因为AOF
的优先级高于RDB
2 故障描述
我们最开始没有开启AOF
,后来出于安全考虑开启AOF
,直接修改配置文件后重启服务,但是,由于AOF
开始没有数据,而 AOF
的优先级又高于 RDB
,所以导致重启redis
后,数据全部丢失
部署环境
mkdir -p /apps/redis/{run,data,logs,conf}
# redis 配置
cat >/apps/redis/conf/redis.conf <<EOF
bind 0.0.0.0
protected-mode no
daemonize no
loglevel notice
port 6379
tcp-backlog 2048
databases 16
dir /data
requirepass 123456
maxclients 10000
timeout 600
tcp-keepalive 600
slowlog-log-slower-than 1000
slowlog-max-len 128
maxmemory 1gb
maxmemory-policy allkeys-lru
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
EOF
# 安装docker-ce
yum -y install docker-ce docker-ce-cli containerd.io
systemctl enable --now docker
systemctl status docker
# 加速 docker 访问
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors":["https://0cde955d3600f3000fe5c004160e0320.mirror.swr.myhuaweicloud.com"]
}
EOF
# 运行容器
docker run \
--privileged \
-p 6379:6379 \
-p 26379:26379 \
--name redis-node \
-v /apps/redis/data:/data \
-v /apps/redis/conf/redis.conf:/etc/redis/redis.conf \
--net host \
-d redis:5.0 \
redis-server /etc/redis/redis.conf
故障模拟
# 进入容器
[root@client ~]# docker exec -it redis-node /bin/bash
root@client:/data# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set port 80
OK
127.0.0.1:6379> get port
"80"
127.0.0.1:6379> set city beijing
OK
127.0.0.1:6379> get city
"beijing"
127.0.0.1:6379> keys *
1) "port"
2) "city"
127.0.0.1:6379>
默认没有开启 AOF
,我们现在开启AOF
进行故障模拟
vim /apps/redis/conf/redis.conf
# 启用aof持久化方式,默认是不开启的
appendonly yes
# aof持久化文件的名称
appendfilename "appendonly.aof"
# 每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
appendfsync everysec
# 重写期间,对新写的操作,不做fsync,而是暂存在内存中
no-appendfsync-on-rewrite yes
# 当前aof文件大小是上次重写aof文件大小的2倍时(增长率100%时重写),则自动启动日志重写,缺点:业务开始的时候,会重复重写多次
auto-aof-rewrite-percentage 100
# aof文件,至少达到64M才重写
auto-aof-rewrite-min-size 64mb
重启 redis
并登陆验证
[root@client ~]# docker restart redis-node
redis-node
[root@client ~]# docker exec -it redis-node /bin/bash
root@client:/data# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> bgsave # 执行 bgsave 进行数据保存
Background saving started
127.0.0.1:6379> keys * # 数据已丢失
(empty list or set)
127.0.0.1:6379>
3 正确的redis
恢复数据步骤
测试数据
[root@client ~]# docker exec -it redis-node /bin/bash
root@client:/data# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set port 80
OK
127.0.0.1:6379> set city beijing
OK
127.0.0.1:6379> get port
"80"
127.0.0.1:6379> get city
"beijing"
127.0.0.1:6379> keys *
1) "city"
2) "port"
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379>
1.停止redis
服务
[root@client data]# docker stop redis-node
redis-node
[root@client data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@client data]#
2.在配置文件中关闭appendonly
3.将备份数据拷贝到redis
数据目录下
4.开启redis
服务
[root@client data]# docker start redis-node
redis-node
[root@client data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
442f774378f2 redis:5.0 "docker-entrypoint..." About an hour ago Up 43 seconds redis-node
[root@client data]#
5.使用 config set
临时开启 AOF
[root@client ~]# docker exec -it redis-node /bin/bash
root@client:/data# redis-cli -a 123456 config set appendonly yes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
root@client:/data# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
127.0.0.1:6379> set https 443
OK
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379>
6.在配置文件中打开appendonly
,防止以后重启redis
,AOF
没有开启
[root@client ~]# docker exec -it redis-node /bin/bash
root@client:/data# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> keys *
1) "https"
2) "port"
3) "city"
127.0.0.1:6379> get city
"beijing"
127.0.0.1:6379>
4 总结
AOF
的优先级高于RDB
- 如果
Redis
在运行一段时间后才开启AOF
的话,请在redis
的交互界面使用redis-cli -a 123456 config set appendonly yes
临时开启 - 在
redis
的配置文件中也要设置appendonly yes
,但是,此时切记不要重启redis
服务 - 等一段时间后,确认数据已安全写入
AOF
,再遇到Redis
机器故障之后才可启动redis