百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

讲讲Redis Cluster原理及通信协议?Key如何选择Master及主备切换?

mhr18 2024-11-14 16:26 22 浏览 0 评论

主从架构及哨兵架构都是一主多从,可读写分离,不用考虑Key存那一天机器上,但redis cluster是多主多从的,那在设置值的时候,key是如何选主的呢?

1、Redis Cluster的hash slot(哈希槽)算法

redis cluster有固定的16384个hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot。

redis cluster中每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hash slot。任何一台宕机,不影响另外两个节点,因为key找的是hash slot不是机器。

hash slot让node的增加和移除很简单,增加一个master,就将其他master的hash slot移动部分过去,减少一个master,就将它的hash slot移动到其他master上去,移动hash slot的成本是非常低的。

客户端的api,可以对指定的数据,让他们走同一个hash slot,通过hash tag来实现。

2、HashTags

通过分片手段,可以将数据合理地划分到不同的节点上,这本来就是一件好事。但是有的时候,我们希望对相关联的业务以原子的方式进行操作。

举个简单的例子:

我们在单节点上执行MSET , 它是一个原子性的操作,所有给定的key会在同一时间内被设置,不可能出现某些指定的key被更新另一些指定的key没有改变的情况。但是在集群环境下,我们仍然可以执行MSET命令,但它的操作不在是原子操作,会存在某些指定的key被更新,而另外一些指定的key没有改变,原因是多个key可能会被分配到不同的机器上。

这个也是在面试的时候会容易被问到的内容。怎么解决呢?

在redis中引入了HashTag的概念,可以使得数据分布算法可以根据key的某一个部分进行计算,然后让相关的key落到同一个数据分片举个简单的例子,加入对于用户的信息进行存储, user:{user1}:id、user:{user1}:name那么通过hashtag的方式,表示当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。

3、槽迁移的过程

槽迁移的过程中有一个不稳定状态,这个不稳定状态会有一些规则,这些规则定义客户端的行为,从而使得Redis Cluster不必宕机的情况下可以执行槽的迁移。下面描述了我们迁移编号为1、2、3的槽的过程中,他们在MasterA节点和MasterB节点中的状态。

简单的工作流程:

1. 向MasterB发送状态变更命令,把Master B对应的slot状态设置为importing。

2. 向MasterA发送状态变更命令,将Master对应的slot状态设置为migrating。

当MasterA的状态设置为migrating后,表示对应的slot正在迁移,为了保证slot数据的一致性,MasterA此时对于slot内部数据提供读写服务的行为和正常状态下是有区别的。

migrating状态

1. 如果客户端访问的Key还没有迁移出去,则正常处理这个key。

2. 如果key已经迁移或者根本就不存在这个key,则回复客户端ASK信息让它跳转到MasterB去执行。

importing状态

当MasterB的状态设置为importing后,表示对应的slot正在向MasterB迁入,及时Master仍然能对外提供该slot的读写服务,但和正常状态下也是有区别的。

1. 当来自客户端的正常访问不是从ASK跳转过来的,说明客户端还不知道迁移正在进行,很有可能操作了一个目前还没迁移完成的并且还存在于MasterA上的key,如果此时这个key在A上已经被修改了,那么B和A的修改则会发生冲突。所以对于MasterB上的slot的所有非ASK跳转过来的操作,MasterB都不会一一去护理,而是通过MOVED命令让客户端跳转到MasterA上去执行。这样的状态控制保证了同一个key在迁移之前总是在源节点上执行,迁移后总是在目标节点上执行,防止出现两边同时写导致的冲突问题。

2. 而且迁移过程中新增的key一定会在目标节点上执行,源节点也不会新增key,使得整个迁移过程既能对外正常提供服务,又能在一定的时间点完成slot的迁移。

4、redis cluster节点间采取gossip协议进行通信

gossip协议包含多种消息,包括ping,pong,meet,fail,等等。

ping: 每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据。

当然如果发现某个节点通信延时达到了cluster_node_timeout / 2,那么立即发送ping,避免数据交换延时过长,落后的时间太长。

pong: 返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新。

fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。

当我们在集群下用redis-cli set mykey1 v1设置KEY时,会发现这个key对应的hashslot如果就在自己本地,那么自己就处理掉了,但是如果计算出来的hashslot在其他master上,那么就会给客户端返回一个moved error,告诉你,你得到哪个master上去执行这条写入的命令,那当前的master是如何知道这个KEY的hashslot是在那台机器上的呢?

所以节点间通过gossip协议进行数据交换,就知道每个hash slot在哪个节点上了。

所以命令用redis-cli的时候,可以加入-c参数,支持自动的请求重定向,redis-cli接收到moved之后,会自动重定向到对应的节点执行命令。

5、redis cluster主备切换原理(Redis Cluster集群如何选主的?)

1、判断节点宕机

如果一个节点认为另外一个节点宕机,那么就是pfail,主观宕机。

如果多个节点都认为另外一个节点宕机了,那么就是fail,客观宕机,跟哨兵的原理几乎一样,sdown,odown。

在cluster-node-timeout内,某个节点一直没有返回pong,那么就被认为pfail。

如果一个节点认为某个节点pfail了,那么会在gossip ping消息中,ping给其他节点,如果超过半数的节点都认为pfail了,那么就会变成fail。

2、从节点过滤

对宕机的master node,从所有的slave node中,选择一个切换成master node,检查每个slave node与master node断开连接的时间,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那么就没有资格切换成master。

3、从节点选举

对所有从节点进行排序,slave priority,offset,run id。

每个从节点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举。

所有的master node开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 + 1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master。



6、与哨兵比较

1、Cluster实现了主从复制及哨兵的所有功能,并增加了多主多从的高可用架构。

2、在选举方面,整个流程跟哨兵相比,非常类似,哨兵是sdown odown ?式先授权哨兵作为切换者,并根据save同步相关数据比对来进行选主,而cluster是pfail fail对save之间进行广播授权,通过对epoch大小及判断master来进行选举投票选主。

3、在通信上,redis cluster采用的是gossip的方式通信,而哨兵是通过redis的pub/sub系统实现的,每个哨兵都会往sentinel这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在并进行通信。

到此,redis的主从架构、哨兵架构之前有分享过及redis cluster架构我们都讲了,但redis还会问到这些问题,你都会回答么?

redis如何实现分布式锁以及有哪些不同的实现方式?

redis分布式锁与ZK分布式锁的区别?

redis缓存穿透?缓存击穿?缓存雪崩?

等一系列问题我们下节讲分享。

相关推荐

一文读懂Prometheus架构监控(prometheus监控哪些指标)

介绍Prometheus是一个系统监控和警报工具包。它是用Go编写的,由Soundcloud构建,并于2016年作为继Kubernetes之后的第二个托管项目加入云原生计算基金会(C...

Spring Boot 3.x 新特性详解:从基础到高级实战

1.SpringBoot3.x简介与核心特性1.1SpringBoot3.x新特性概览SpringBoot3.x是建立在SpringFramework6.0基础上的重大版...

「技术分享」猪八戒基于Quartz分布式调度平台实践

点击原文:【技术分享】猪八戒基于Quartz分布式调度平台实践点击关注“八戒技术团队”,阅读更多技术干货1.背景介绍1.1业务场景调度任务是我们日常开发中非常经典的一个场景,我们时常会需要用到一些不...

14. 常用框架与工具(使用的框架)

本章深入解析Go生态中的核心开发框架与工具链,结合性能调优与工程化实践,提供高效开发方案。14.1Web框架(Gin,Echo)14.1.1Gin高性能实践//中间件链优化router:=...

SpringBoot整合MyBatis-Plus:从入门到精通

一、MyBatis-Plus基础介绍1.1MyBatis-Plus核心概念MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提...

Seata源码—5.全局事务的创建与返回处理

大纲1.Seata开启分布式事务的流程总结2.Seata生成全局事务ID的雪花算法源码3.生成xid以及对全局事务会话进行持久化的源码4.全局事务会话数据持久化的实现源码5.SeataServer创...

Java开发200+个学习知识路线-史上最全(框架篇)

1.Spring框架深入SpringIOC容器:BeanFactory与ApplicationContextBean生命周期:实例化、属性填充、初始化、销毁依赖注入方式:构造器注入、Setter注...

OpenResty 入门指南:从基础到动态路由实战

一、引言1.1OpenResty简介OpenResty是一款基于Nginx的高性能Web平台,通过集成Lua脚本和丰富的模块,将Nginx从静态反向代理转变为可动态编程的应用平台...

你还在为 Spring Boot3 分布式锁实现发愁?一文教你轻松搞定!

作为互联网大厂后端开发人员,在项目开发过程中,你有没有遇到过这样的问题:多个服务实例同时访问共享资源,导致数据不一致、业务逻辑混乱?没错,这就是分布式环境下常见的并发问题,而分布式锁就是解决这类问题的...

近2万字详解JAVA NIO2文件操作,过瘾

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。从classpath中读取过文件的人,都知道需要写一些读取流的方法,很是繁琐。最近使用IDEA在打出.这个符号的时候,一行代...

学习MVC之租房网站(十二)-缓存和静态页面

在上一篇<学习MVC之租房网站(十一)-定时任务和云存储>学习了Quartz的使用、发邮件,并将通过UEditor上传的图片保存到云存储。在项目的最后,再学习优化网站性能的一些技术:缓存和...

Linux系统下运行c++程序(linux怎么运行c++文件)

引言为什么要在Linux下写程序?需要更多关于Linux下c++开发的资料请后台私信【架构】获取分享资料包括:C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdf...

2022正确的java学习顺序(文末送java福利)

对于刚学习java的人来说,可能最大的问题是不知道学习方向,每天学了什么第二天就忘了,而课堂的讲解也是很片面的。今天我结合我的学习路线为大家讲解下最基础的学习路线,真心希望能帮到迷茫的小伙伴。(有很多...

一个 3 年 Java 程序员 5 家大厂的面试总结(已拿Offer)

前言15年毕业到现在也近三年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在流程中...最终有幸去了网易。但是要...

多商户商城系统开发全流程解析(多商户商城源码免费下载)

在数字化商业浪潮中,多商户商城系统成为众多企业拓展电商业务的关键选择。这类系统允许众多商家在同一平台销售商品,不仅丰富了商品种类,还为消费者带来更多样的购物体验。不过,开发一个多商户商城系统是个复杂的...

取消回复欢迎 发表评论: