我擦!Redis挂了,登录态没了,工作要丢了。别急看我操作一下Redis的备份恢复和数据迁移

300 阅读6分钟

昨晚老板突然在群里发了一张图片,说昨天才用的,怎么今天还要登录?相关人赶紧看看。

image.png

我心想让你登录就登录呗,哪来那么多事?本想洗洗睡了。老大突然微信问我说,是不是 Redis 出问题了?怎么用户的登录态没了?我们趁老板还没收到客户投诉之前把数据恢复一下。

没办法既然到找到我了,那就是对我的百分百信任,为公司赴汤蹈火在所不辞。更何况只是恢复一下数据呢,你说是吧?

image.png

Redis 恢复数据那就免不了和 RBD、AOF这俩老货打交道了。

简单来说:

  • RDB 是全量备份
  • AOF 是增量备份

image.png

别急,再通俗点:

  • RDB 就是在一个特定的时间点把全部数据备份一次
  • AOF 就是如果写入了,就把这次写操作记起来

image.png

别动手,举个栗子给你,包懂的:

我女朋友送了一盒乐高给我,打算和我在星期四的晚上点个KFC疯狂套餐。然后做一件疯狂的事情。

我把盒子拿出来一看,封面已经把乐高模型都画出来了。我说这不是洒洒水吗?10分钟搞定它。

1个小时后,装逼不成的我只能求女票把说明书给我,然后和我一起拼。

经过两个人近3个小时的鏖战,模型终于是拼好了。

image.png

把你的脚放下,我马上解释。在这个例子中,盒子封面就相当于RDB,它是乐高模型在某个时刻的样子,有一个词我相信你一定听过,快照。我可以在拼好底座的时候拍个照,这是一个快照。在底座的基础上再拼上主体,然后我再拍个照,这也是一个快照。

总之呢,只要能通过这张照片欢迎出原来的东西,那这张照片就是一个完美的快照。像我拆电脑前必须先拍张照片,不是怕忘记什么。只是我想记住写什么,免得多出来一两颗螺丝就不好了。

image.png

说了半天,AOF呢?你难道没发现我最后是靠什么拼好乐高模型的吗?没错说明书就相当于AOF。说明书记录了底座要怎么拼,主体要怎么拼,以及最后的封顶要怎么拼。每一步都给你写清楚,就怕你到时候没拼好找他退钱。

AOF 就是这样工作的,当我向 Redis 里面写入数据时,他就记起来,一直记一直记。只要记得足够多,那还原不是简简单单3小时的事吗?

拼完乐高之后,我女票说她累了,要我抱抱

image.png

咳咳,这篇文的主题是什么来着?Redis 数据迁移,差点忘了。接下来就是劲爆的数据迁移,请先去厕所,然后打开再看,我怕你们其他时间不看。

说回数据恢复,首先看一下 Redis 实例有没有开启备份

127.0.0.1:6379> CONFIG GET save
1) "save"
2) ""
127.0.0.1:6379> CONFIG GET appendonly
1) "appendonly"
2) "no"

哇哦,看到这个结果的时候我心都死了,这表示不会自动进行 RDB 备份,没有开启 AOF 备份。我嘞个豆,你让我做饭,但是不给我米,还说想吃香香的饭,那我怎么办?

我只能问运维有没有备份,意外的是运维说他昨晚刚备份完。确实挺意外的,果然这小伙之前被叼那么多次是有用的。

既然有备份文件了 ,那就直接恢复吧,数据丢点就丢点。总比全部丢了要强。突然发现我的Redis是部署在K8S里面的,那我就得先把文件给复制进去。

kubectl cp ./2406141123dump.rdb prod/redis-deploy-6764468fd6-lrkq7:/data/2406141123dump.rdb 

kubectl cp <local-file_name> <name-space>/<pod-name>:<pod-file-name>

然后执行恢复命令

# 先找到对应得pod
kubectl get pods -n prod | grep redis 

# 进入pod
kubectl exec -it <pod-name> bash -n <name-space>

# 通过redis-cli 恢复rdb
redis-cli -h localhost -p 6379 --rdb /data/2406141123dump.rdb

这时候我们就拥有群里的狗叫权了

image.png

数据恢复完之后的常规操作那当然是再备份一把了,我们可以选择开启RDB的自动备份和AOF,但是但是那是运维的事情。

秉承着别人的事情我坚决不做,自己的事情适当不做的原则,我们忽略它。然后手动触发一次RDB备份,给回运维保存,数据恢复就告一段落了。

# 先查一下现在的rdb最新备份时间
127.0.0.1:6379> lastsave
(integer) 1718779144

# 触发备份
127.0.0.1:6379> bgsave
Background saving started

#再查一遍最新备份时间,如果和上次不同就说明成了
127.0.0.1:6379> lastsave
(integer) 1719225459

127.0.0.1:6379> exit

别忘了,我们现在在 K8S 的pod里面,我们还得把备份文件复制到宿主机去

# 先看一下有没有备份文件 dump.rdb
ls -l /data

# 将k8s中pod的文件拷贝到宿主机
kubectl cp prod/redis-deploy-6764468fd6-lrkq7:/data/dump.rdb ./dump.rdb

发给运维,大功告成。

image.png

作为一个专业的前端后端运维测试工程师,我们解决了问题,还得解决提出问题的人(bushi)。 让我来看看怎么个事?问就是流量突增,毕竟这是所有人都喜欢的答案,当然是包括我的,这意味着我们只要加钱就行了。加钱就意味着是老板给的不够,不是我们前端后端运维测试工程师的问题。

这该死的世界啊,我究竟要为这个世界背负多少的秘密。我永远不会告诉别人,当时Redis所在的机器莫名重启了,而且Redis是单节点,没有挂载持久化盘。而且运维每天都是手动备份,我当时能拿到前一天的备份真的是好运,因为他想起来他好几天没备份了,就备份了一下子。

image.png

既然发现了问题那就解决问题吧,既然 Redis 单节点而且没有持久化,那我们就打一层反逻辑。在集群里面部署一个 多节点有持久化的 Redis,是不是就解决了。是的,答案往往就是这么的朴实无华。那有没有更好更简单的方法呢?必定是有的。给钱申请一个云Redis,然后把数据迁移过去,完美。

image.png

可用性和持久化解决了,那接下来就是数据迁移了,我找了挺多工具的,但最后只留下两个来尝试,因为很多工具都不维护了:

image.png

phpRedisAdmin 有图形页面,还能导入导出。看起来相当不错,但是有这几个问题让我放弃了它:

  • 导出结果是字符串格式的,有序列化问题
  • 导出结果没有过期时间
  • key 多的时候,页面很卡

image.png

这就是我导出内容的一部分截图,中间那一堆乱码是因为我用来默认了 RedisTemplate

然后是 Redis-Shake,这是一个go写的,专门用来做数据迁移的工具。支持多种方式从源Redis实例拉取数据同步到目标实例。

# 下载二进制文件
wget https://github.com/tair-opensource/RedisShake/releases/download/v4.1.0/redis-shake-linux-amd64.tar.gz

# 解压
tar -zxvf redis-shake-linux-amd64.tar.gz

# 修改配置文件 shake.toml,然后执行同步
./redis-shake shake.toml

image.png

靠谱