redis数据恢复的坑

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会把服务器执行的所有写操作命令记录在一个日志文件里(类似于MySQLbinlog),并在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,防止以后重启redisAOF没有开启

[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 总结

  1. AOF 的优先级高于 RDB
  2. 如果 Redis 在运行一段时间后才开启AOF的话,请在redis的交互界面使用redis-cli -a 123456 config set appendonly yes临时开启
  3. redis的配置文件中也要设置appendonly yes,但是,此时切记不要重启 redis 服务
  4. 等一段时间后,确认数据已安全写入AOF,再遇到 Redis 机器故障之后才可启动 redis
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值