redis cluster

redis集群有2种方案,官方redis cluster和代理的codis,本文只对redis cluster进行介绍。
两种集群模式的区别,可以参考:https://www.cnblogs.com/yinyunmoyi/p/11525680.html

1 分区

虚拟槽分区:
Redis Cluser采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整 数槽内,计算公式:slot=CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。
在这里插入图片描述

集群限制:

1)不支持多数据库空间,单机的16个数据库,只能使用第一个数据库db0
2)复制结构只支持一层,从节点直接复制主节点,不支持嵌套树状复制结构

2 搭建集群

2.1 准备节点
至少6个节点才可以组成高可用的集群;
每个节点开启cluster-enabled yes (开启集群模式);

集群配置文件:
每个节点的配置文件格式 nodes-{port}.conf
作用:集群内节点信息发生变化,如:添加节点、节点下线、故障转移等,会自动保存集群状态到配置文件中。
在这里插入图片描述

集群的启动过程:
在这里插入图片描述

2.2 节点握手
背景:启动完单个节点,每个节点只能识别自己节点信息,不能识别其他节点的存在,需要通过节点握手来批次建立联系。

节点握手流程:
在这里插入图片描述

只需要在任意一个节点,执行meet命令分别于其他节点进行握手,就能把所有节点建立联系,命令如下:

127.0.0.1:6379>cluster meet 127.0.0.1 6380
127.0.0.1:6379>cluster meet 127.0.0.1 6381
127.0.0.1:6379>cluster meet 127.0.0.1 6382
127.0.0.1:6379>cluster meet 127.0.0.1 6383
127.0.0.1:6379>cluster meet 127.0.0.1 6384

通过cluster nodes可以查看到到集群中所有节点:
在这里插入图片描述

节点握手后集群还不能正常工作,处于下线状态,所有数据读写都被禁止,通过cluseter info获取集群当前状态:
在这里插入图片描述
其中,cluster_slots_assigned为当前节点分配槽数量,为0表示还未分配节点,所以不可用。只有当13684个槽都分配了节点后,集群才进入在线状态。

2.3 分配槽
使用命令cluster addslots为节点分配槽,命令如下:
在这里插入图片描述

只为6379 6380 6381三个节点分配了槽,其他节点没有分配,把剩下的3个节点设置为从节点(可以故障转移),分别连接对应的主节点,
使用命令cluster replicate {master nodeid}, 之后就形成了集群结构:

在这里插入图片描述

2.4 可以使用redis-trib.rb快速搭建集群
过程略

3 节点通信

通过发送gossip消息进行节点之间的通信, P2P模式点对点通信,去中心化。

3.1 通信流程
节点通信过程:
1)每个节点都会单独开辟一个TCP通道,用于节点之间通信,通信端口号在基础端口上加10000
2)每个节点在固定周期内通过特定规则选择几个节点发送ping消息
3)接收到ping消息的节点用pong消息作为相应

不同节点之间批次不断通信交换信息,一段时间后所有节点之间就都知道集群完整的信息。

在这里插入图片描述

3.2 gossip消息
节点之间是通过gossip消息来互相交互的
gossip消息分类:ping消息、pong消息、meet消息、fail消息,如下
在这里插入图片描述

meet消息:握手,用于通知新节点加入
ping消息:每个节点每秒向多个其他节点发送ping消息,用于检测节点是否在线和交换彼此状态信息
pong消息:接收到meet ping消息后,作为响应消息回复给发送方确认消息正常通信
fail消息:当节点判定另一个节点下线,会想集群中其他节点广播fail消息进行通知

消息解析过程:
在这里插入图片描述

3.3 节点选择

在这里插入图片描述

4 集群伸缩

4.1 伸缩原理
原有的所有节点都需要把一部分槽和数据迁移到新加入的节点
在这里插入图片描述

4.2 扩容集群
步骤如下:
1)准备新节点
2)加入集群
3)为新节点分配槽和数据

槽和数据迁移流程如下:
在这里插入图片描述

4.3 收缩集群
节点下线安全流程:
在这里插入图片描述

5 请求路由

客户端对redis集群通信,为了追求性能最大化,并没有采用代理的方式而是客户端直连节点的方式。

5.1 请求重定向
redis接收任何键的命令时,首先计算出来key对应的槽,在找到对应的节点;
如果节点是自身,则直接处理key命令,否则回复moved重定向错误,通知客户端请求正确的节点。
在这里插入图片描述

重定向信息包含了key所对应的槽和槽的节点地址,根据这些信息客户端就可以向正确的节点发起请求了。
在这里插入图片描述
使用redis-cli 命令,加入-c参数支持自动重定向,不需要客户端在手动发起重定向命令了;

5.2 smart客户端
1 smart原理
smart客户端通过内部维护的slot -> node的映射关系,本地就可以实现键到节点的查找,从而保证IO效率最大化,moved重定向只是协助smart客户端更新本地的slot -> node映射。
在这里插入图片描述

smart客户端执行命令的流程:
1)初始化时把所有slot -> node映射关系缓存到本地客户端;
2)发送命令如果连接错误,会重新选择一个活动节点获取最新的slot ->node映射关系,刷新本地缓存,重新对新的目标节点发起请求;
3)当发送命令失败次数超过5次,会抛出异常

2 smart客户端-JedisCluster
a 初始化方法:
在这里插入图片描述

·SetjedisClusterNode:所有Redis Cluster节点信息(也可
以是一部分,因为客户端可以通过cluster slots自动发现)。
·int connectionTimeout:连接超时。
·int soTimeout:读写超时。
·int maxAttempts:重试次数。
GenericObjectPoolConfig poolConfig:连接池参数,JedisCluster会为
Redis Cluster的每个节点创建连接池,

b 批量操作的方法
批量操作的数据可能分布在不同节点,会造成mset 、mget命令无法实现,解决方式如下:
先获取所有的节点,进行遍历;
每个节点中筛选出来满足条件的key,执行mget或者pipeline操作

5.3 ask重定向
场景:当slot数据在迁移的过程,如果smart客户端根据本地缓存的slot -> node,从源节点未查询到数据,则有可能已经迁移到目标节点了,需要ask重定向到目标节点请求数据。
在这里插入图片描述

ask和moved的重定向的区别:

ask重定向说明集群正在slot数据迁移,客户端无法知道什么时候能迁移完成,因此只能是临时性的重定向,客户端不会更新slots缓存。
moved重定向说明键对应的槽已经明确了新的节点,需要更新slots缓存;

6 故障转移

6.1 故障发现
每个节点都会保存其他节点的信息,每个节点都会定期发送ping消息来检查其他节点是否下线。

下线的方式有2种:
主观下线: 单个节点发送ping认为某个节点下线,则视为主观下线,单个节点可能不准确(网络不稳定原因)
客观下线:半数以上持有槽的主节点都认为某个节点已下线,则视为客观下线,更准确。

注意点:
1 参与故障判断的节点为什么是持有槽的主节点?
集群模式下只有持有槽的主节点才负责读写请求和集群槽的维护,从节点只进行主节点数据和状态信息的复制(备份),不负责读写请求。
2 为什么是半数以上持有槽主节点?
避免网络分区导致集群分割

6.2 故障恢复
如果下线节点吃持有槽的主节点,则需要从他的从节点中选举一个替换他。故障转移流程如下:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值