Redis 主从复制集群及数据异常丢失恢复思路
mhr18 2024-11-23 19:28 20 浏览 0 评论
1.redis 主从复制原理
- 从库向主库发送同步请求
- 主库接收从库发送的同步请求
- 主库开始使用 bgsave 生成 rdb 文件
- 主库 rdb 文件生成后保存到磁盘,让将 rdb 文件发送给从库
- 从库接收主库发送的 rdb 文件,将 rdb 文件载入内存
从库在同步主库的时候,会把从库上的所有数据全部清空,因此在做 redis 主从的时候尽量选择没有任何数据的 redis
架构图
环境准备
2.部署两台 redis
2.1 192.168.81.210 配置
1.创建redis部署路径
[root@redis-1 ~]# mkdir -p /data/redis_cluster/redis_6379/{conf,pid,logs,data}
[root@redis-1 ~]# tree /data/redis_cluster/
/data/redis_cluster/
└── redis_6379
├── conf
├── logs
├── pid
└── data
2.下载redis
[root@redis-1 ~]# mkdir /data/soft
[root@redis-1 ~]# cd /data/soft
[root@redis-1 /data/soft]# wget https://repo.huaweicloud.com/redis/redis-3.2.9.tar.gz
3.编译安装redis
[root@redis-1 /data/soft]# tar xf redis-3.2.9.tar.gz -C /data/redis_cluster/
[root@redis-1 /data/soft]# cd /data/redis_cluster/
[root@redis-1 /data/redis_cluster]# ln -s redis-3.2.9/ redis
[root@redis-1 /data/redis_cluster]# cd redis/src
[root@redis-1 /data/redis_cluster/redis]# make && make install
4.准备配置文件
[root@redis-1 ~]# vim /data/redis_cluster/redis_6379/conf/redis_6379.conf
daemonize yes
bind 192.168.81.210 127.0.0.1
port 6379
pidfile /data/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /data/redis_cluster/redis_6379/logs/redis_6379.log
databases 16
dbfilename redis_6379.rdb
dir /data/redis_cluster/redis_6379/data/
save 900 1
save 300 100
save 60 10000
appendonly yes
appendfilename "appendonly.aof"
appendfsync always
appendfsync everysec
appendfsync no
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
5.启动redis
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
2.2 192.168.81.220 配置
由于 redis-1 已经部署好了一套 redis,我们可以直接复制过来使用
1.使用rsync将redis-1的redis目录拷贝过来你
[root@redis-1 ~]# rsync -avz /data root@192.168.81.220:/
2.查看拷贝过来的目录文件
[root@redis-2 ~]# ls /data/redis_cluster/
redis redis-3.2.9 redis_6379
[root@redis-2 ~]# ls /data/redis_cluster/redis_6379/
conf data logs pid
3.编译安装redis,使系统能使用redis命令
直接执行make install即可,因为编译步骤在redis-1已经做了
[root@redis-2 ~]# cd /data/redis_cluster/redis-3.2.9/
[root@redis-2 /data/redis_cluster/redis-3.2.9]# make install
4.修改redis配置文件
[root@redis-2 ~]# vim /data/redis_cluster/redis_6379/conf/redis_6379.conf
bind 192.168.81.220 127.0.0.1
5.启动redis
[root@redis-2 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
3.redis 主从复制配置
3.1.在主库批量创建 key
[root@redis-1 ~]# for i in {0..2000}; do redis-cli set k_${i} v_${i}; echo "k_${i} is ok"; done
127.0.0.1:6379> DBSIZE
(integer) 2001
3.2.配置从库连接主库
两种配置方式实现 Redis 主从复制:
- 配置文件实现
- 命令行执行命令实现
3.2.1.在配置文件中设置
1.修改配置文件
[root@redis-2 ~]# vim /data/redis_cluster/redis_6379/conf/redis_6379.conf
slaveof 192.168.81.210 6379 #指定主库的ip和端口
2.重启redis
[root@redis-2 ~]# redis-cli shutdown
[root@redis-2 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
3.2.2.在命令行热更新配置
[root@redis-2 ~]# redis-cli
127.0.0.1:6379> SLAVEOF 192.168.81.210 6379
OK
3.3.查看从库是否同步主库数据
1.在从库上执行keys查看数据是否相同
[root@redis-2 ~]# redis-cli
127.0.0.1:6379> keys *
2.在主库上新建一个key,查看从库是否存在
主:
127.0.0.1:6379> set name jiangxl
OK
从:
127.0.0.1:6379> get name
"jiangxl"
3.在主库删除k_114,查看从库是否也删除
主:
127.0.0.1:6379> del k_114
(integer) 1
从:
127.0.0.1:6379> get k_114
(nil)
3.4.在查看日志中主从同步的原理
主库从库有记录复制的详细日志
4.redis 主从复制危险操作
4.1.使用热更新配置误操作
redis 主从复制如果使用热更新配置,有时候会因为选错主机把从库误认为主库,结果在主库上执行了 slaveof,这样就会导致主库上的数据被清空,因为从库上是没有数据的
从库在同步主库的时候会把原本自己的数据全部清空
误操作过程
从库数据为0
127.0.0.1:6379> DBSIZE
(integer) 0
主库数据为2001
127.0.0.1:6379> DBSIZE
(integer) 2001
在主库上操作同步本该从库的数据
127.0.0.1:6379> SLAVEOF 192.168.81.220 6379
OK
再次查看数据,数据已经清空
127.0.0.1:6379> DBSIZE
(integer) 0
4.2.避免热更新配置误操作
- 不使用热更新,直接在配置文件里配置主从
- 在执行 slaveof 的时候先执行 bgsave,把数据手动备份一下,然后在数据目录,将 rdb 文件复制成另一个文件,做备份,这样即使出现问题也能即使恢复
bgsave 之后不用重启,直接备份 rdb 文件即可
1.手动持久化
127.0.0.1:6379> BGSAVE
Background saving started
2.备份rdb文件
[root@redis-1 ~]# cd /data/redis_cluster/redis_6379/
[root@redis-1 /data/redis_cluster/redis_6379]# cd data/
[root@redis-1 /data/redis_cluster/redis_6379/data]# cp redis_6379.rdb redis_6379.rdb.bak
3.再次同步错误的主库,造成数据丢失
127.0.0.1:6379> SLAVEOF 192.168.81.220 6379
OK
127.0.0.1:6379> keys *
(empty list or set)
4.还原备份的rdb文件,先停掉redis,在还原
[root@redis-1 ~]# redis-cli shutdown
[root@redis-1 /data/redis_cluster/redis_6379/data]# cp redis_6379.rdb.bak redis_6379.rdb
5.查看还原后的数据
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
127.0.0.1:6379> DBSIZE
(integer) 2001
5.模拟 redis 主从复制错误数据恢复
模拟 redis 主从同步误操作数据恢复
大致思路:
- 清空两台 redis 的数据
- 在主库上创建一些数据,然后使用 bgsave 命令,将数据保存到磁盘,再将磁盘的 rdb 文件备份
- 再将从库的数据同步过来,模拟主库数据丢失
- 从 rdb 备份文件还原数据库
这个实验的主要的目的是操作 redis 备份还原
5.1.清空数据
两台 redis 都需要操作
先关闭再删除数据再启动
[root@redis-1 ~]# redis-cli shutdown
[root@redis-1 ~]# rm -rf /data/redis_cluster/redis_6379/data/*
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
[root@redis-1 ~]# redis-cli
127.0.0.1:6379> keys *
(empty list or set)
5.2.在主库批量创建数据并备份
1.批量创建数据
[root@redis-1 ~]# for i in {0..2000}; do redis-cli set k_${i} v_${i}; echo "k_${i} is ok"; done
127.0.0.1:6379> DBSIZE
(integer) 2001
2.将近数据写入到
127.0.0.1:6379> BGSAVE
Background saving started
3.备份rdb文件
[root@redis-1 /data/redis_cluster/redis_6379/data]# cp redis_6379.rdb redis_6379.rdb.bak
[root@redis-1 /data/redis_cluster/redis_6379/data]# ll
总用量 56
-rw-r--r--. 1 root root 27877 1月 28 21:00 redis_6379.rdb
-rw-r--r--. 1 root root 27877 1月 28 21:01 redis_6379.rdb.bak
5.3.同步从库的数据造成数据丢失
这时从库的数据应该是空的
[root@redis-2 ~]# redis-cli
127.0.0.1:6379> keys *
(empty list or set)
主库同步从库的数据,同步完主库数据丢失,这样就模拟了主库数据丢失的情况
127.0.0.1:6379> SLAVEOF 192.168.81.220 6379
OK
127.0.0.1:6379> keys *
(empty list or set)
5.4.恢复主库的数据
先关掉 redis,还原,最后在开启 redis
1.关掉redis
[root@redis-1 ~]# redis-cli shutdown
2.还原rdb备份文件
[root@redis-1 /data/redis_cluster/redis_6379/data]# cp redis_6379.rdb.bak redis_6379.rdb
cp:是否覆盖"redis_6379.rdb"? y
3.启动redis
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
4.查看数据是否还原
[root@redis-1 ~]# redis-cli
127.0.0.1:6379> keys *
6.模拟线上环境主库宕机故障恢复
思路:
- 首先保证主从同步已经配置完成,主库从库都有数据
- 关闭 redis 主库,模拟 redis 主库宕机
- 查看 redis 从库是否还存在数据,是否可读可写(不能写,只能读)
- 关闭从库的 slaveof,停止主从同步,将应用连接 redis 的地址改成从库,保证业务不断
- 修复主库,主库上线后,与从库建立主从复制关系,原来的从库(redis-2)就变成了主库,现在的主库变成了从库(redis-1)这时 关掉应用程序,停止数据写入
- 然后将现在主库(redis-2)的数据同步到现在的从库(redis-1)
- 关闭现在从库(redis-1)的 slaveof,停止主从复制,然后将现在主库(redis-2)配置 salveof,同步原来的主库(redis-1)
- 数据同步完,原来的主库从库就恢复完毕了
简单明了的一句话:主库因为某种原因宕机无法提供服务了,直接将从库切换成主库提供服务,然后后原来的主库恢复后同步当前主库的数据,然后停掉所有线上运行的程序,将现在的主库去同步恢复后的主库,重新生成主从关系。
6.1.配置主从模拟线上环境
配置主从前先保证主库上面有数据
1.登陆主库redis-1查看是否有数据
[root@redis-1 ~]# redis-cli
127.0.0.1:6379> DBSIZE
(integer) 2001
2.登陆从库redis-2查看是否有数据
[root@redis-2 ~]# redis-cli
127.0.0.1:6379> keys *
(empty list or set)
3.从库没有数据的情况下在从库上配置主从,同步主库的数据
127.0.0.1:6379> SLAVEOF 192.168.81.210 6379
OK
数据已经同步
127.0.0.1:6379> DBSIZE
(integer) 2001
6.2.模拟主库宕机验证从库是否可读写
1.直接关掉主库,造成宕机
[root@redis-1 ~]# redis-cli shutdown
2.查看从库是否可读写
只能读,不能写
[root@redis-2 ~]# redis-cli get k_1
"v_1"
[root@redis-2 ~]# redis-cli set k999 k_1
(error) READONLY You can't write against a read only slave.
主库一宕机,从库就会一直输出日志提示连接不上主库
6.3.关闭从库的主从复制保证业务的不间断
现在主库是不可用的,从库也只能读不能写,但是数据只有这么一份了,我们只能关闭从库上的主从复制,让从库变成主库,再配置业务的 redis 地址,首先要保证业务的不中断
1.关闭从库redis-2的主从同步配置,使其成为主库
[root@redis-2 ~]# redis-cli slaveof no one
OK
2.将应用的redis地址修改为从库,只要从库关掉了主从配置,他自己就是一个可读可写的库了,库里有故障前的所有数据,可以先保证业务的不间断
6.4.修复故障的主库同步原来从库的数据
修复完主库,已经是有数据的了,为什么还要同步从库的数据呢,因为在主库挂掉的那一瞬间,从库去掉了主从配置,自己已经成了主库,并且也提供了一段时间的数据写入,这时从库的数据时最完整的
同步现在主库(原来的从库)的数据时,先要将应用关掉,不要在往里写数据了
在主库(原来的从库上)写入几个新的数据,模拟产生的新数据
[root@redis-2 ~]# redis-cli
127.0.0.1:6379> set zuixinshujv vvvvv
OK
在重新上线的主库上配置主从同步,使自己变成从库,同步主库的(原来的从库)数据
同步之后,现在从库(重新修复的主库已经有最新数据了)
同步之前先将应用停掉,不要再往redis中写数据
[root@redis-1 ~]# redis-cli
127.0.0.1:6379> SLAVEOF 192.168.81.220 6379
OK
127.0.0.1:6379> get zuixinshujv
"vvvvv"
6.5.从库重新上线为主库
这里的从库重新上线指的就是原来故障的主库,现在已经同步到最新数据了,因此要上线成为主库,之前选他作为主库就是因为他的性能比从库各方面都要高,避免将来因为性能再次发生故障,因此要切换
1.关闭从库(原来的主库)的主从配置
[root@redis-1 ~]# redis-cli
127.0.0.1:6379> SLAVEOF no one
OK
2.在主库(原来的从库)配置主从复制
[root@redis-2 ~]# redis-cli
127.0.0.1:6379> SLAVEOF 192.168.81.210 6379
OK
6.6.将应用的 redis 地址再次修改为主库的地址
目前主库已经恢复了,并且主从之前重新建立了主从同步关系,现在就可以把应用的 redis 地址修改为主库,启动应用就可以了
作者:jiangxl
链接:https://xie.infoq.cn/article/93a1f184446513a3ea1a5b019
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)