栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis Clustor(集群)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis Clustor(集群)

目录

一、Redis 数据分区(虚拟槽分区)

二、集群功能限制

三、搭建集群

1.准备节点

2.节点握手

3.分配槽

4.集群模式

5.搭建集群注意事项

6.节点通信

四、集群伸缩

1.伸缩原理

2.扩容集群

3.收缩集群

五、请求路由

1.请求重定向

2.计算槽

六、故障转移

1.故障发现

2.故障恢复


一、Redis 数据分区(虚拟槽分区)

Redis Clustor 槽范围是0-16383。槽是集群内数据管理和迁移的基本单位,所有的键根据哈希函数映射到0-16383整数槽内,计算公式:slot=CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。

node(节点)→slot(槽)→key→value

二、集群功能限制

1.mset、mget只支持在同一个槽内的key,因为不在一个槽内的key可能存在于不同节点上

2.key的事务操作只能在同一个节点上,不同节点不能使用事务操作

3.不能将一个大的键值对象hash、list等映射到不同节点上

4.单机下的redis支持16个数据库,集群模式下只能使用一个数据库,即db0

5.复制结构只支持一层,从节点只能复制主节点

三、搭建集群

1.准备节点

Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。每个节点需要开启配置 cluster-enabled yes,让Redis运行在集群模式下。建议为集群内所有节点统一目录,一般划分为三个目录:conf、data、log,分别存放配置、数据和日志相关文件。

2.节点握手

节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信,达到感知对方的过程。由客户端发起命令。例:cluster meet 127.0.0.1 6380 客户端让127.0.0.1 所代表的节点6379向6380节点发起握手

  • 节点6379本地创建6380节点信息对象,并发送meet消息
  • 节点6380接受到meet消息后,保存6379节点信息并回复pong消息
  • 之后节点6379和6380彼此定期通过ping/pong消息进行正常的节点通信

我们只需要在集群内任意节点上执行cluster meet 命令加入新节点,握手状态会通过消息在集群内传播,这样其他节点会自动发现新节点并发起握手流程。节点建立握手之后集群还不能正常工作,处于下线状态,数据读写都被禁止

3.分配槽

Redis集群把所有数据映射到16384个槽中,每个key会映射为一个固定的槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过cluster addslots命令为节点分配槽

例:redis-cli   -h  127.0.0.1  -p  6379  cluster  addslots  {0...5461}

槽全部分配给节点后,当前集群状态是OK,集群进入在线状态

4.集群模式

每个负责处理槽的节点为主节点,应该具有从节点,保证当它出现故障时可以自动进行故障转移。从节点负责复制主节点槽信息和相关的数据,使用cluster  replicate  {nodeId} 命令让一个节点成为从节点

5.搭建集群注意事项
  • 加入集群的节点地址必须不包含任何槽和数据,否则会拒绝创建集群
  • 集群需要保证完整性,所有的槽都分配到存活的主节点上

6.节点通信

Redis 集群采用P2P的Gossip协议,原理是节点彼此不断通信交换信息,一段时间之后所有的节点都会知道集群完整的信息,这种方式类似流言传播。通信过程:

  • 集群中的每个节点都会单独开辟一个TCP通道,用于节点之间彼此通信,通信端口号在基础端口上加10000
  • 每个节点在固定周期内通过特定规则选择几个节点发送ping消息
  • 接收到ping消息的节点用pong消息作为响应

Gossip消息:ping消息、pong消息、meet消息、fail消息

  • meet消息:用于通知新节点加入
  • ping消息:用于检测节点是否在线和交换彼此状态信息,ping消息发送封装了自身节点和部分其他节点的状态数据
  • pong消息:当接收到meet消息和ping消息后,作为响应消息回复给发送方确认消息正常通信。pong消息封装了自身状态数据
  • fail消息:当节点判断集群内另一个节点下线时,会向集群内广播一个fail消息,其他节点接收到fail消息之后把对应节点更新为下线状态。
  • 所有的消息都采用相同的消息头,内部包含发送节点关键信息,如节点id、槽映射、节点标识(主从角色、是否下线)等。

通信流程:接收ping/meet消息→解析消息头和消息体→判断是否为新节点→如果是发送meet消息进行节点握手→如果不是更新该节点状态到本地列表→最终都回复pong消息

节点选择流程:节点定时任务→每秒执行10次间隔1秒→选择发送节点(1.每秒随机5次找出最久没有通信节点 2.最后通信时间大于node-timeout/2)→ping消息数据(包含1.自身节点信息 2. 1/10其他节点信息)→发送ping消息

四、集群伸缩

1.伸缩原理

Redis集群提供了灵活的节点扩容和收缩方案,在不影响对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容。其中原理可抽象为槽盒对应数据在不同节点之间灵活移动

2.扩容集群

准备新节点→加入集群→迁移槽和数据

迁移槽和数据:

  • 槽迁移计划:首先需要为新节点制定槽的迁移计划,确定原有节点的哪些槽需要迁移到新节点,迁移计划需要保证每个节点负责相似数量的槽,从而保证各节点的数据均匀
  • 迁移数据:数据迁移过程是逐个槽进行的

3.收缩集群

收缩集群意味着缩减规模,需要从现有集群中安全下线部分节点。

  • 首先需要确定下线节点是否有负责的槽,如果是,需要把槽迁移到其他节点,保证节点下线后整个集群节点映射的完整性
  • 当下线节点不再负责槽或者本身是从节点时,就可以通知集群内其他节点忘记下线节点,当所有节点忘记该节点后就可以正常关闭了

五、请求路由

1.请求重定向

在集群模式下,Redis接收任何键相关的命令时首先计算键对应的槽,在根据槽找出对应的节点,如果节点是自身,则处理命令;否则回复MOVED重定向错误,通知客户端请求正确的节点,这个过程称为MOVED重定向。

重定向信息包含了键所对应的槽以及负责该槽的节点地址,根据这些信息客户端可以向正确的节点发送请求

2.计算槽

Redis首先需要计算键所对应的槽,根据键的有效部分使用CRC16函数计算出散列值,再取对16383的余数,使每个键都可以映射到0-16383槽范围内。其中如果键内容包含{和}大括号字符,则计算槽的有效部分是括号内的内容;否则采用键的全内容计算槽

其中键内部使用大括号包含的内容又叫做hash_tag,它提供不同的键可以具备相同slot功能

例如:在集群模式下使用mget等命令优化批量调用时,键列表必须具有相同的slot,否则会报错。这时可以利用hash_tag让不同的键具有相同的slot达到优化的目的

mget  user : {10086} : friends  user : {10086} : videos

六、故障转移

1.故障发现

Redis集群内节点通过ping/pong消息实现节点通信,消息可以传播节点槽信息、主从状态、节点故障等。因此故障发现也是通过消息传播机制实现的,主要环节:主观下线(pfail)和客观下线(fail)

  • 主观下线:指某个节点认为另一个节点不可用,即下线状态,这个状态不是最终的故障判定,只能代表一个节点的意见,可能存在误判的情况
  • 客观下线:指标记一个节点真正的下线,集群内多个节点都认为该节点不可用,从而达成共识的结果。如果是持有槽的主节点故障,需要为该节点进行故障转移

主观下线流程:

  1. 节点a发送ping消息给节点b,如果通信正常将收到pong消息,节点a更新最近一次与节点b的通信时间
  2. 如果节点a与节点b通信出现问题则断开连接,下次会进行重连。如果一直通信失败,则节点a与节点b最后通信时间将无法更新
  3. 节点a内的定时任务检测到与节点b最后通信时间超过 cluster-node-timeout 时,更新本地对节点b的状态为主观下线

客观下线流程:

  1. 当某个节点判断另一个节点为主观下线后,相应的节点状态会跟随消息在集群内传播
  2. 当消息体内含有其他节点的pfail状态会判断发送节点的状态,如果发送节点是主节点则对报告的pfail状态处理,如果是从节点则忽略
  3. 找到pfail对应的节点结构,更新clusterNode内部下线报告链接
  4. 根据更新后的下线报告链表尝试进行客观下线:
  • 集群中的节点每次收到其他节点的pfail状态,都会尝试触发客观下线
  • 统计有效的下线报告数量,如果小于集群内持有槽的主节点总数的一半则退出
  • 当下线报告大于槽主节点数量的一半时,标记对应的故障节点为客观下线状态
  • 向集群广播一条fail消息,通知所有的节点将故障节点标记为客观下线,fail消息的消息体只包含故障节点的ID

2.故障恢复

如果持有槽的主节点故障下线后,它的所有从节点承担故障恢复的义务,当从节点通过内部定时任务发现自身复制的主节点进入客观下线时,将会触发故障恢复流程

  1. 资格检查:每个从节点都要检查最后与主节点断线时间,如果断线时间超过cluster-node-time*cluster-slave-validity-factor(从节点的有效因子,默认10),则当前从节点不具备故障转移资格
  2. 准备选举时间:当从节点符合故障转移资格后,更新触发故障选举时间,只有到达该时间后才能执行后续流程。每个从节点使用不同的延迟选举时间来支持优先级。复制偏移量越大说明从节点延迟越低,触发故障选举越早,那么它具有更高的优先级来替换故障主节点。
  3. 发起选举:                                                                                                                                                                                                                                                                                更新配置纪元:配置纪元是一个只增不减的整数,每个主节点自身维护一个配置纪元标示当前主节点的版本,所有主节点的配置纪元都不相等,从节点会复制主节点的配置纪元。整个集群又维护一个全局的配置纪元,用于记录集群内所有主节点配置纪元的最大版本。配置纪元会随着ping/pong消息在集群内传播,当发送方与接收方都是主节点且配置纪元相等时代表出现了冲突,nodeId更大的一方会递增全局配置纪元并赋值给当前节点来区分冲突。从节点每次发起投票时都会自增集群的全局配置纪元,并单独保存在clusterState.failover_auth_epoch变量中用于标识本次从节点发起选举的版本                                                                                                                                                                         广播选举消息:在集群内广播选举消息,并记录已发送过消息的状态,保证该节点在一个配置纪元内只发起一次选举
  4. 选举投票:只有持有槽的主节点才会处理故障选举消息,因为每个持有槽的主节点在每个配置纪元内只有一张选票,当接到第一个请求投票的从节点消息时回复FAILOVER_AUTH_ACK消息作为投票,之后相同配置纪元内其他从节点的选举消息将忽略。当从节点收集到N/2+1个持有槽的主节点投票时,从节点可以执行替换主节点操作。
  5. 替换主节点:
  • 当前从节点取消复制变为主节点
  • 执行clusterDelSlot操作撤销故障主节点负责的槽,并执行clusterAddSlot把这些槽委派给自己
  • 向集群广播自己的pong消息,通知集群内所有的节点当前从节点变为主节点并接管了故障主节点的槽信息

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/987904.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号