当前位置: 首页 > article >正文

Redis的主从模式、哨兵模式、集群模式

最近学习了一下这三种架构模式,这里记录一下,仅供参考

目录

一、主从架构

1、搭建方式

2、同步原理

3、优化策略:

4、总结:

二、哨兵架构

1、搭建哨兵集群

2、RedisTemplate如何使用哨兵模式

三、分片集群架构

1,搭建分片集群

2、散列插槽

3、集群伸缩

4、故障转移

5、RedsiTemplate访问分片集群


一、主从架构

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。

1、搭建方式

如何开启主从关系呢:

我们可以使用salveof或者replicaof命令实现

假设现在在7001、7002、7003三个端口部署了三个redis

我们要想7002作为从7001作为主,需要先连接7002节点

#连接7002
redis-cli -p 7002
#执行slaveof
slaveof xxx.xxx.xxx 7001

另外一个节点也是如此,查询配置情况我们可以使用INFO replication命令

2、同步原理

全量同步:

主从的第一次同步是全量同步

1.1.首先从节点执行replicaof命令请求建立连接,向主节点发送请求数据同步

1.2.主节点判断是否是第一次同步

1.3.如果是第一次,返回主节点的数据版本信息

1.4.从节点保存版本信息

2.1.主节点执行bgsave操作时会生成RDB文件

2.1.1.生成RDB文件之后会将旗舰所有的命令记录到一个baklog文件当中

2.2.然后发送RDB文件向从节点

2.3.从节点接收到RDB会清空本地数据加载RDB文件

3.1.主节点发送repl_baklog中的命令

3.2.从节点执行repl_baklog中的命令

master如何判断slave是不是第一次来同步数据?

这里会用到两个很重要的概念:

  • Replication ld:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replidslave则会继承master节点的replid
  • offset:偏移量,随着记录在repl baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset.如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

因此slave做数据同步,必须向master声明自己的replicationid和offset,master才可以判断到底需要同步哪些数据

从节点向主节点发送链接请求会携带replication Id,主节点判断这个id是否一致,如果不一致说明是第一次连接需要全量同步,如果一致那么说明只需要增量同步既可

增量同步:

1.1.从节点向主节点发送同步请求,并携带relication id和偏移量offset

1.2.主节点判断relid是否和当前节点一致

1.3.如果不是第一次,恢复continue

2.1.主节点去repl_baklog中获取偏移量offset后的命令数据

2.2.主节点向从节点发送offset后的命令

2.3.从节点执行命令

注意:这里可能会出现一个问题,就是从节点如果因为一些原因很长时间没用做增量同步,主节点这边的repl_baklog如果出现了覆盖,这时候从节点再去根据命令做同步就会出现数据不一致,所以这时候只能通过全量同步

3、优化策略:

可以从以下几个方面来优化Redis主从就集群:

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘10。
  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘I0
  • 适当提高repl baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

4、总结:

简述全量同步和增量同步区别?

  • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl baklog,逐个发送给slave。
  • 增量同步:slave提交自己的offset到master,master获取repl baklog中从offset之后的命令给slave

什么时候执行全量同步?

  • slave节点第一次连接master节点时
  • slave节点断开时间太久,replbaklog中的offset已经被覆盖时

什么时候执行增量同步?

  • slave节点断开又恢复,并且在replbaklog中能找到offset时
二、哨兵架构

在主从模式当中,从节点宕机后可以找到主节点同步数据,但是主节点宕机就丸辣。

解决办法是什么呢?我们可以安排一个或多个哨兵去观察这个主节点,一但主节点出现问题,那我们哨兵就立刻取代掉主节点,重新选举出一个新的主节点。这就是哨兵(Sentinel)机制

Redis提供了哨兵(sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下:

  • 监控:S嗯停了 会不断检查你的master和slave是否按预期工作
  • 自动故障恢复:如果master故障,sentinel会将一个slave提升为master。当故障示例恢复后也以新的master为主
  • 通知:java客户端找主从地址不是直接去找,而是去哨兵sentinel集群中去找,由哨兵通知我们客户端需要去访问哪个地址,当飞机群发生故障转移时,会将最新消息推送个redis的客户端

sentinel的服务检测基于心跳机制检测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。
  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

一旦发现master故障,sentinel需要在salve中选择一个座位新的master,选择依据是这样:

  • 首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-miliseconds*10)则会排除该slave节点
  • 然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举
  • 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高
  • 最后是判断slave节点的运行id大小,越小优先级越高。

当选中一个slave为新的master之后(例如slave1:7002),会发生一个故障转移:

  • sentinel给备选的slave1节点发送slaveofnoone命令,让该节点成为master
  • sentinel给所有其它slave发送slaveof192.168.150.101:7002命令,让这些slave成为新master的从节点,开始从新的master上同步数据。
  • 最后,sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点

1、搭建哨兵集群

假设现在有三个redis实例,端口分别是27001、27002、27003,我们需要再每一个的实例文件目录下创建一个sentinel.conf文件,添加如下内容

port 27001(根据节点更改)
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmb/s1"(需要修改)

运行时要启动sentinel实例:

redis-sentinel ***.conf  #运行启动sentinel实例
2、RedisTemplate如何使用哨兵模式

三、分片集群架构

哨兵模式只能解决高并发读的问题,当有高并发写的需求的时候,主从和哨兵模式就会有大量的IO操作,造成效率的底下。对于这个问题,解决办法就是搭建分片集群架构。

使用分片集群可以解决上述问题,分片集群特征:

  • 集群中有多个master,每个master保存不同数据
  • 每个master都可以有多个slave节点master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点\\

1,搭建分片集群

现假设有六个redis节点7001、7002、7003、8001、8002、8003搭建redis集群,三个主节点,三个从节点

在每个文件目录下准备一个redis.conf文件:内容如下,端口要改

通过命令一键运行六个目录文件下的.conf文件

部署成集群的命令如下:

redis-cli --cluster create -cluster-replicas 1 
192.168.150.101:7001 192.168.150101:7002 
192.168.150.101:7003 492.168.150.101:8001 
192.168.150.101:8002 192.168.150.101:8003

2、散列插槽

Redis会把每一个master节点映射到0~16383共16383(hash slot)上,查看集群信息时就能看到:

Redis如何判断某个key应该在哪个实例?

  • 将16384个插槽分配到不同的实例
  • 根据key的有效部分计算哈希值,对16384取余,余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个Redis实例?

  • 这一类数据使用相同的有效部分,例如key都以{typeld}为前缀
3、集群伸缩

也就是向集群中添加或删除新节点

先添加一个节点,然后将节点添加到集群当中,并且把插槽分配给新的节点

4、故障转移

这里可以通过watch命令监控集群状态

我们通过shutdown命令讲一个主节点强制下线,会发现有其他的节点成为了主节点,这时候重启该节点,会发现变成了从节点

利用cluster failover命令可以手动让集群中的某个master容机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。其流程如下:

手动的Failover支持三种不同模式:

  • 缺省:默认的流程,如图1~6步
  • force:省略了对offset的一致性校验
  • takeover:直接执行第5步,忽略数据一致性、忽略master状态和其它master的意见
5、RedsiTemplate访问分片集群


记录不易,点个赞吧


http://www.kler.cn/a/316535.html

相关文章:

  • asp.net core webapi项目中 在生产环境中 进不去swagger
  • 虚幻引擎结构之ULevel
  • MongoDB 常用操作指南(Docker 环境下)
  • uniapp Native.js原生arr插件服务发送广播到uniapp页面中
  • Linux网络——网络基础
  • K8S 黑魔法之如何从 Pod 拿到节点的命令行
  • 电子电气架构 --- 基于ISO 26262的车载电子软件开发流程
  • 基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue
  • 快速下载Imagenet数据集
  • Python模块和包:标准库模块(os, sys, datetime, math等)②
  • CVE-2024-2389 未经身份验证的命令注入
  • LeetCode --- 139双周赛
  • STM32篇:开发环境安装
  • 基于微信小程序的科创微应用平台设计与实现+ssm(lw+演示+源码+运行)
  • MongoDB 双活集群在运营商的实践
  • 利用mybatis拦截器完成入库加密出库解密
  • 算法之搜索--最长公共子序列LCS
  • leetcode746. 使用最小花费爬楼梯,动态规划
  • Uniapp低版本的安卓不能用解决办法
  • Qt_窗口界面QMainWindow的介绍
  • Deep Guided Learning for Fast Multi-ExposureImage Fusion
  • 对接空号检测平台可以降低成本吗
  • 动手学深度学习(pytorch)学习记录32-稠密连接网络(DenseNet)[学习记录]
  • Vue | watch监听
  • IDEA Project不显示/缺失文件
  • 手机在网状态查询接口如何用PHP进行调用?