7.3 搭建cluster集群
因为cluster的中文翻译是"集群",所以在一些资料里会把此处提到的cluster集群称为Redis集群.从广义上来讲,只要两台服务器之间有关联,它们就可以构成一个集群,所以在前文里把由"一主二从"和"哨兵节点加一主二从"等构成的系统称为"集群".这里为了避免混淆,将提到的集群称为cluster集群
相比于哨兵模式,cluster集群能支持扩容,且无须额外的节点来监控状态,所以使用这种模式集群的系统会用得更多些
7.3.1 哈希槽与cluster集群
在cluster集群中,有16384个哈希槽(hash slot),在设置Redis的键(key)时,会先用CRC16算法对key运算,然后使用16384对这个结果取模,取模的结果是多少,就把这个key放到该结果锁编号的哈希槽中.数学算法如下所示,其中slotIndex表示该key所存放的槽的编号
slotIndex = HASH_SLOT = CRC16(key) mod 16384
Redis Cluster使用16384作为哈希槽的数量,因为它是一个相对小而合理的数值,可以在集群的各个节点之间实现均衡的数据分配,同时保持管理和重新分片的复杂性在可接受的范围内.
选择16384的几个原因如下:
性能和管理的平衡:选择一个太小的哈希槽数可能会导致数据分布不均匀.相反,选择一个太大的哈希槽数会增加管理的复杂性,例如在节点之间迁移哈希槽时.16384提供了一个合适的中间值
分片和迁移:当需要将哈希槽从一个节点迁移到另一个节点时(例如当添加或删除集群节点时),较小的哈希槽数意味着每个槽可能包含更多的键,这会使迁移操作更加耗时.16384个哈希槽提供了更细粒度的数据分片,从而使得单个哈希槽的迁移成为一个相对快速的操作
历史和常规选择:这也可能是基于经验和其他分布式系统的常见实践.例如,一些其他的系统或数据库也可能使用类似的哈希槽或分区数量
二进制因子:16384是2^14.在计算机科学中,使用2的幂是很常见的,因为它们在计算上是高效的
总之,16384是一个经过权衡后的选择,它在分布均匀性、管理的复杂性和操作效率之间达到了一个平衡
比如某cluster集群由三台Redis服务器组成,那么编号从0到5460号哈希槽会被分配到第一台Redis服务器,5461到10922号哈希槽会被分配到第二台服务器,10923到16383号哈希槽会被分配到第三台服务器上,如下图示:

同理,如果某cluster集群是由六台Redis服务器组成的,那么每台服务器上也会被平均分配一定数量的哈希槽.此外,cluster集群里也支持主从复制模式,即分配到一定数量哈希槽的Redis服务器也可以携带一个或多个从节点.下图为包含三主三从的cluster集群的效果:

7.3.2 初步搭建cluster集群
a. 编写配置文件
step1. 编写redisClusterMaster1的配置文件
step2. 编写redisClusterMaster2的配置文件
step3. 编写redisClusterMaster3的配置文件
step4. 编写clusterSlave1的配置文件
注:此处并没有在配置文件中配置主从关系,后续步骤中会设置主从关系
step5. 编写clusterSlave2的配置文件
step6. 编写clusterSlave3的配置文件
可以看到,和搭建主从模式的集群一样,也是要求集群中所有节点的用户名和密码一致
b. 启动节点
step1. 启动clusterMaster1节点
step2. 启动clusterMaster2节点
step3. 启动clusterMaster3节点
step4. 启动clusterSlave1节点
step5. 启动clusterSlave2节点
step6. 启动clusterSlave3节点
c. 查看配置文件
step1. 查看nodes-6379.conf
其中:
myself,master:表示该节点属于master节点,且只连接到myself自身,没有同其他Redis节点关联step2. 查看nodes-6380.conf
step3. 查看nodes-6381.conf
step4. 查看nodes-26379.conf
step5. 查看nodes-26380.conf
step6. 查看nodes-26381.conf
可以看到,此时各个节点都没有互相关联
d. 关联各个节点
CLUSTER MEET命令用于向Redis Cluster节点引入新的节点.这是集群扩展或修改时的基本操作.以下是命令的功能和使用场景的详细描述:
功能
当你执行CLUSTER MEET命令时,你实际上是在告诉一个现有的Redis Cluster节点去与另一个Redis节点(可能是新的节点)进行通信并建立连接
具体来说,执行此命令后:
指定的现有节点(通常称为目标节点)将尝试与新节点建立连接
一旦连接建立,两个节点将交换集群配置信息,并开始周期性地彼此同步
新节点将被引入到集群网络中,但此时它可能还没有承担任何哈希槽的责任.为了使其成为集群的功能性部分,您可能需要进一步分配哈希槽或从其他节点迁移哈希槽
使用场景
扩展集群:当你想要向现有的Redis Cluster添加更多节点以增加容量或提供更高的可用性时,您会使用此命令
集群维护:如果某个节点出现故障并且需要被替换,或者您只是想要重新配置集群的节点布局,你也可能会使用此命令
初次设置集群:在初次创建Redis Cluster时,您需要使用
meet命令将所有节点连接在一起
其中:
existing-node-ip:现有节点的IPexisting-node-port:现有节点的端口new-node-ip:要引入的新节点的IPnew-node-port:要引入的新节点的端口
查看集群情况:
cluster_known_nodes:当前cluster集群中有6个节点cluster_state:目前集群处于fail状态,因为还没有给集群中的节点分配哈希槽
e. 分配哈希槽
为3个主节点分配哈希槽,其命令语法如下:
CLUSTER ADDSLOTS:是Redis Cluster的一个命令,用于将一个或多个哈希槽分配给当前节点.这是构建Redis Cluster时的一个重要步骤,因为它决定了哪些键被存储在哪个节点
该命令的基本语法如下:
其中:
slot:是一个介于0到16383之间的数字,代表一个哈希槽
需要注意的是,一旦一个哈希槽被分配给一个节点,它不能被重新分配给另一个节点,除非你首先使用CLUSTER DELSLOTS命令从原始节点中删除它
redis-cli -h -p -a ":"
此处逐个添加slot不太现实,所以采用shell中的范围表示法来添加:
node-ip:要分配哈希槽的Redis Cluster节点的IP 地址node-port:要分配哈希槽的Redis Cluster节点的端口<slot1> [slot2] ... [slotN]:要分配给该节点的哈希槽的编号
例如:想要为IP为192.168.1.10、端口为7000的节点分配哈希槽1到5000,可以按如下写法:
step1. 分配哈希槽给3个主节点
step2. 查看当前集群情况
可以看到,此时集群状态为正常,且已经有16384个哈希槽被分配到了该集群中.
f. 设置从节点
step1. 查看节点ID
CLUSTER REPLICATE nodeID:设置当前节点为指定节点的从节点
命令CLUSTER NODES可用于查看节点ID
其中第1列即为节点ID
即:
clusterMaster1的节点ID为:c182e10b7f26e1289f6aa4fd41ac707ec3319508
clusterMaster2的节点ID为:dda36b27b4e0ed367b3267a565ed327fcda1f0e8
clusterMaster2的节点ID为:11e718918a9c689ed80bca73e3c24d9f2bb34102
step2. 设置clusterSlave1节点为clusterMaster1的从节点
step3. 设置clusterSlave2节点为clusterMaster2的从节点
step4. 设置clusterSlave3节点为clusterMaster3的从节点
step5. 在任一节点上查看集群节点情况
可以看到,目前是3主3从的状态了
7.3.3 在cluster集群中读写数据
在任一从节点上执行写入操作,触发写入错误:
可以看到,其实并不是写入操作失败了,报错信息表明写入的键被移动到了127.0.0.1:6380的低5798个哈希槽中.在操作中,用户希望是透明地进行数据的读写操作,而不希望看到此类的读写错误
为了达到这个效果,需要在redis-cli命令后加入-c参数,以实现互联的效果:
注意:在redis cluster的集群下,必须在连接时使用--user和--pass指定用户名密码,才能在执行命令时不报错.当然,集群中各节点的用户名密码应相同.否则报错如下:
读取:
7.3.4 模拟扩容和数据迁移动作
扩容1主1从:
step1. 编写clusterMasterNew.conf文件
step2. 启动clusterMasterNew节点
step3. 编写clusterSlaveNew.conf文件
step4. 启动clusterSlaveNew节点
step5. 将clusterMasterNew节点和clusterSlaveNew节点加入集群
step6. 在clusterSlaveNew节点设置其对应的主节点
查看节点ID:
可以看到,b65229a1d68aabf96ad488fe4115814167afbeec为clusterMasterNew的节点ID
设置主从:
查看设置结果:
step7. 重新分片
其中:
127.0.0.1:6379:指定执行重新分配哈希槽命令的redis服务器--cluster-from:指定要迁出哈希槽的节点ID,多个节点ID由,分割--cluster-to:指定要迁入的节点ID--cluster-slots:指定要迁移的哈希槽数量.此处的数量是指总数,而非是每个节点上的哈希槽数量
执行结果:
确认迁移后:
step8. 查看集群情况
cluster_size:4:表示集群大小.由于当前该cluster集群包含了4个主节点和4个从节点,而哈希槽是分散在了4个主节点上,所以集群大小为4
查看节点情况:
7.3.5 cluster集群的常用配置参数
cluster-enabled:表示Redis节点是否支持cluster集群.取值是yes表示支持集群;取值是no表示以普通Redis服务器节点的方式启动cluster-config-file:指定cluster集群配置文件的名称.该配置文件不是由使用者创建或更改的,而是在Redis服务器第一次以cluster节点身份启动时自动生 成的.在该文件中保存了cluster集群里本节点和其他节点的信息和关联方式cluster-require-full-coverage:表示当cluster集群中有节点失效时,该集群是否继续对外提供写服务.出于1容错性考虑,建议该参数值设置为no.若设置为yes,则集群中有节点失效时,该集群只能提供读服务cluster-node-timeout:用于设置cluster集群中节点的最长不可用时间(单位:毫秒).如果主节点的不可用时间超过该参数指定的值,那么会向对应的从节点进行故障转移动作cluster-migration-barrier:用于设置主节点的最小从节点数量.假设该值设置为1,当某主节点的从节点个数小于1时,就会从其他从节点个数大于1的主节点那边调剂一个从节点过来.这样做的目的是避免出现不包含从节点的主节点,因为一旦出现这种情况,当主节点失效后,就无法再用从节点进行故障恢复的动作.也就是说,合理地设置该参数能提升cluster集群系统的可靠性
Last updated