Redis 的主从复制与哨兵机制(redis主从复制如何实现)
mhr18 2024-11-12 11:24 14 浏览 0 评论
一、主从复制
1.1 什么是主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。
前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点
默认情况下,每台redis服务器都是主节点;且一个主节点可以有多个从节点(或者没有),但一个从节点只有一个主。
1.2 主从复制的作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
主从库采用的是读写分离的方式
1.3 主从复制原理
分为全量复制与增量复制
1.3.1 全量复制
发生在第一次复制时
第一阶段是主从库间建立连接、协商同步的过程。
第二阶段,主库将所有数据同步给从库。
第三个阶段,主库会把第二阶段执行过程中新收到的写命令,再发送给从库。
1.3.2 增量复制
只会把主从库网络断连期间主库收到的命令,同步给从库
1.3.3 同步流程
(1)、一个从数据库启动后,会向主数据库发送SYNC命令。
(2)、主数据库在接收到SYNC命令后会开始在后台保存快照(即RDB持久化的过程),并将保存快照期间接收到的命令缓存起来。在该持久化过程中会生成一个.rdb的快照文件。
(3)、在主数据库快照执行完成后, Redis 会将快照文件和所有缓存的命令以 .rdb 快照文件的形式发送给从数据库 。
(4)、从数据库收到主数据库的 .rdb 照文件后,载入该快照文件到本地。
(5)、从数据库执行载入后的 .rdb 照文件,将数据写入内存中。以上过程被称为复制初始化
(6)、在 制初始化结束后, 主数据库在每次收到写命令时都会将命令同步给从数据库,从而保证主从数据库的数据一致性。
二、哨兵机制
2.1 哨兵机制介绍
2.1.1 集群逻辑图
下图是一个典型的哨兵集群监控的逻辑图
Redis Sentinel包含了若个Sentinel节点,这样做也带来了两个好处:
1. 对于节点的故障判断是由多个Sentinel节点共同完成,这样可以有效地防止误判
2. 即使个别Sentinel节点不可用,整个Sentinel集群依然是可用的。
2.1.2 哨兵机制实现的功能
Redis-Sentinel是在master-slave机制上加入监控机制哨兵Sentinel实现的。Sentinel主要功能就是为Redis Master-Slave集群提供:
1)监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
2)提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
4)配置中心:在Redis Sentinel模式中,客户端在初始化的时候连接的是Sentinel节点集合,从中获取主节点信息。
其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置中心和通知功能,则需要在与客户端的交互中才能体现。
在Sentinel集群中,一个最小的Master-Slave单元包含一个master和一个slave服务器。当master失效后,sentinel自动将slave提升为master,从而可以减少管理员的人工切换slave的操作过程。
2.2 哨兵机制原理
2.2.1 监控
Sentinel节点需要监控master、slave以及其它Sentinel节点的状态。这一过程是通过Redis的pub/sub系统实现的。Redis Sentinel一共有三个定时监控任务,完成对各个节点发现和监控:
1)监控主从拓扑信息:每隔10秒,每个Sentinel节点,会向master和slave发送INFO命令获取最新的拓扑结构
2)Sentinel节点信息交换:每隔2秒,每个Sentinel节点,会向Redis数据节点的__sentinel__:hello频道上,发送自身的信息,以及对主节点的判断信息。这样,Sentinel节点之间就可以交换信息
3)节点状态监控:每隔1秒,每个Sentinel节点,会向master、slave、其余Sentinel节点发送PING命令做心跳检测,来确认这些节点当前是否可达。
2.2.2 下线
2.2.2.1 下线流程
1)每个Sentinel以每秒一次的频率向它所知的Master,Slave以及其他Sentinel实例发送一个PING命令
2)如果一个实例(instance)距离最后一次有效恢复PING命令的时间超过own-after-milliseconds选项所指定的值,则这个实例会被Sentinel标为主观下线(Sentinel Leader PING命令确认)
3)当有足够的Sentinel(大于等于文件配置的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线
2.2.2.2 主观下线
每个Sentinel节点,每隔1秒会对数据节点发送ping命令做心跳检测,当这些节点超过down-after-milliseconds没有进行有效回复时,Sentinel节点会对该节点做失败判定,这个行为叫做主观下线。
2.2.2.3 客观下线
客观下线,是指当大多数Sentinel节点,都认为master节点宕机了,那么这个判定就是客观的,叫做客观下线。
那么这个大多数是指多少呢?这其实就是分布式协调中的quorum判定了,大多数就是过半数,比如哨兵数量是5,那么大多数就是5/2+1=3个,哨兵数量是10大多数就是10/2+1=6个。
注:Sentinel节点的数量至少为3个,否则不满足quorum判定条件。
2.2.3 哨兵选举
如果发生了客观下线,那么哨兵节点会选举出一个Leader来进行实际的故障转移工作。Redis使用了Raft算法来实现哨兵领导者选举,大致思路如下:
1)每个Sentinel节点都有资格成为领导者,当它主观认为某个数据节点宕机后,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令,要求自己成为领导者;
2)收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinelis-master-down-by-addr命令,将同意该请求,否则拒绝(每个Sentinel节点只有1票);
3)如果该Sentinel节点发现自己的票数已经大于等于MAX(quorum, num(sentinels)/2+1),那么它将成为领导者;
4)如果此过程没有选举出领导者,将进入下一次选举。
2.2.4 故障转移
1)向被选中的从服务器发送slave of no one命令,让它转变为主服务器
2)通过发布/订阅功能,将更新后的配置传播给所有其他Sentinel,其他Sentinel对他们自己的配置进行更新。
3)向所有Slave下达slave of 命令,指向新的主
4)redis-slave 向master重新建立连接,master向所有slave节点发送rdb,保持数据同步
5)在上述转移过程中,伴随着Redis本地配置文件的自动重写,这样即便是实例重启配置也不会丢失
6)原有的master在恢复后降级为slave与新的master全量同步
注:Leader Sentinel节点,会从新的master节点那里得到一个configuration epoch,本质是个version版本号,每次主从切换的version号都必须是唯一的。其他的哨兵都是根据version来更新自己的master配置。
1)Sentinel自动故障迁移使用raft算法来选举Sentinel-leader
2)超过半数投票选出leader,Sentinel Leader用于下达故障转移的指令
3)如果某个Leader挂了,则使用raft从剩下的Sentinel中选出leader
2.3 redis哨兵主备切换的数据丢失问题
2.3.1 主从异步复制导致的数据丢失
Redis master 和slave 数据复制是异步的,这样就有可能会出现部分数据还没有复制到slave中,master就挂掉了,那么这部分的数据就会丢失了。
2.3.2 脑裂导致的数据丢失
脑裂其实就是网络分区导致的现象,比如,我们的master机器网络突然不正常了发生了网络分区,和其他的slave机器不能正常通信了,其实master并没有挂还活着好好的呢,但是哨兵可不是吃闲饭的啊,它会认为master挂掉了啊,那么问题来了,client可能还在继续写master的呀,还没来得及更新到新的master呢,那这部分数据就会丢失。
2.3.3 解决方案
上面的两个数据丢失的问题,那我们该怎么去解决呢?其实也很简单,只需要在配置中加两个配置就行了,如下:
min-slaves-to-write 1 # 要求至少一个slave
min-slaves-max-lag 10 # 数据复制和同步的延迟不能超过10s
我们不能只是去解决问题,我们要知道为什么这么做就可以解决问题,下面我们就来分析下,加上了这两个配置是怎么解决我们数据丢失问题的。
核心思想就是,一旦所有的slave节点,在数据复制和同步时延迟了超过10秒的话,那么master它就不会再接客户端的请求了,这样就会有效减少大量数据丢失的发生。
2.3.3.1 如何减少异步复制数据的丢失
现在当我们的slave在数据复制的时候,发现返回的ACK时延太长达到了 min-slaves-max-lag 配置,这个时候就会认为如果master宕机就会导致大量数据丢失,所以就提前进行了预测,就不再去接收客户端的任何请求了,来将丢失的数据降低在可控范围内。
2.3.3.2 如何减少脑裂数据的丢失
1)如果master出现了脑裂,和其他的slave失去了通信,不能继续给指定数量的slave发送数据。
2)slave超过10秒没有给自己返回ack消息。
3)master就会拒绝客户端的写请求
今天关于Redis 的主从复制与哨兵机制的相关内容就分享到这里!
如果对您有帮助,欢迎点赞+关注,也可以发表您宝贵的评论,和我一起互动!
相关推荐
- Docker集群管理之Docker Compose
-
前言:在上一篇《Docker集群管理之DockerMachine》中,我们通过源码分析了解了DockerMachine的工作原理,使用者可以通过DockerMachine的一条命令在任意支持的平...
- 使用Dockerfile build镜像
-
Docker映像可以看作是Docker容器的压缩包,包含了应用程序以及运行应用程序所需的依赖,容器是映像的运行时实例。一般构建镜像都是使用dockerfile进行构建而不是dockercommit,...
- 自建私有云相册:Docker一键部署Immich,照片视频备份利器
-
自建私有云相册:Docker一键部署Immich,照片视频备份利器前言随着人们手机、PC、平板等电子产品多样,我们拍摄和保存的照片和视频数量也在不断增加。如何高效地管理和备份这些珍贵的记忆成为了一个重...
- docker容器的使用以及部署mysql
-
首先什么是docker官方:翻译:Docker是一个用于开发、发布和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分离,以便您可以快速交付软件。使用Docker,您可以像管理应...
-
- 自建Docker镜像加速服务,免费且简单,服务器VPS、NAS皆可用
-
写在前面:流程十分简单,有手就行,还请耐心看完。本文的实例仅做演示用,不久后将会删除,有需要的各位请自行搭建。免费实例如果15分钟内未收到入站流量,Render会关闭实例的网络服务。Render会在下次收到处理请求时重新启动该服务。Ren...
-
2025-05-24 15:40 mhr18
- 用了8年的方式-用 Docker 瞬间搭建本地开发环境
-
有些时候我们需要在本地搭开发环境,比如平时学习新技术的时候。或者有时候公司的项目需要在本地建一套类似的,方便调试修改。开发环境可能包括MySQL、Redis、Nginx、MQ、Elasticsea...
- 使用dockerfile构建docker镜像
-
准备工作购买vps使用ssh工具连接上1、更新系统aptupdate-y2、一键安装Dockercurl-fsSLhttps://get.docker.com-oget-docker.sh...
- 快速搭建 SpringCloud 微服务开发环境的脚手架
-
本文适合有SpringBoot和SpringCloud基础知识的人群,跟着本文可使用和快速搭建SpringCloud项目。本文作者:HelloGitHub-秦人HelloGitHub推出...
- Docker Hub最全详解(图文全面总结)
-
DockerHubDockerHub是一个由Docker公司负责维护的公共注册中心,它包含了超过15000多个可用来下载和构建容器的Docker镜像。DockerHub作用Docker好比一个代...
- Docker 命令详解
-
dockerimages—查看本地镜像命令dockerimages说明列出本地已下载的所有镜像及其标签、ID、大小等信息。适用场景查看本地镜像资源、准备删除或管理镜像时。常见用法docker...
- Kylin安装Dify
-
cd/mntgitclonehttps://github.com/langgenius/dify.gitcp/mnt/dify/docker/.env.example/mnt/dif...
- kali下对Docker的详细安装
-
Docker是渗透测试中必学不可的一个容器工具,在其中,我们能够快速创建、运行、测试以及部署应用程序。如,我们对一些漏洞进行本地复现时,可以使用Docker快速搭建漏洞环境,完成复现学习。注:本教程仅...
- 银河麒麟V10使用Docker方式部署应用
-
现在越来越多的企业级应用需要运行在国产化环境中,而银河麒麟V10是目前我碰到的最常用的服务器,在银河麒麟上部署应用有两种方式:使用二进制文件编译部署和使用Docker。关于使用二进制文件的方式...
- Docker入门到精通超详细教程,Docker全家桶实战攻略
-
大家好,我是各位双生的武魂、随身老爷爷。从看到这篇内容开始,你就是被选定的天命骚年,将承担起学完docker教程的使命,本使命为单向契约,你可选择YES或者选择YES。正式学习之前,我先给大家做一下d...
- 【Docker 新手入门指南】第一章:前言
-
一、基本介绍Docker介绍Docker是基于Go语言开发的开源容器化平台,旨在实现“一次镜像,处处运行”。它通过将应用程序及其依赖环境(代码、运行时、系统工具、系统库等)打包成一个轻量级、可移...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 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)