Redis Cluster是Redis的分布式解决方案。就是按照hash分区规则将Redis数据映射到多个Redis节点。数据分区是分布式存储的核心 。
一、hash分区规则
a)节点取余分区
b)一致性hash分区
c)虚拟槽分区,Redis的slot范围是0-16383,slot是集群内数据管理和迁移的基本单位。
二、Redis的Slot
slot=CRC16(key) & 16383,通过slot解耦数据和节点之间的关系。
三、限制
a)mset、mget等批量操作仅支持具有相同slot值的key。
b)仅支持多key在同一节点上的事务操作,当多个key分布在不同节点上时无法使用事务。
c)不能将大的键值对象如hash、list映射到不同的节点。
d)不支持多数据库空间。
四、Redis集群启动流程
集群配置文件:node-{port}.conf,Redis自动维护集群配置文件,不需要手动维护。
命令:查看集群节点状态 -> cluster nodes,
查看集群状态 -> cluster info
五、节点握手
节点握手就是运行在集群模式下的节点通过gossip协议彼此通信,感知对方的过程。握手后,集群处于下线状态,所有读写都被禁止,只有16384个slot全部分配给节点后,集群才可以正式对外服务。
命令:握手 -> cluster meet {ip} {port},异步。
六、分配槽
redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0...5461}
redis-cli -h 127.0.0.1 -p 6380 cluster addslots {5462...10922}
redis-cli -h 127.0.0.1 -p 6381 cluster addslots {10923...16383}
七、Redis Cluster的节点角色
主节点:首次启动的节点和被分配槽的节点,从节点:负责复制主节点槽信息和相关的数据。
命令:-> cluster replicate {nodeId},命令必须在对应的从节点上执行,nodeId是需要复制的主节点的节点ID
八、官方Redis集群搭建工具redis-trib.rb
redis-trib.rb是ruby实现的redis集群管理工具。
1、ruby环境准备
2、节点准备
3、创建集群:redis-trib.rb create --replicas 1 127.0.0.1:6481 127.0.0.1:6482 127.0.0.1:6483 127.0.0.1:6484 127.0.0.1:6485 127.0.0.1:6486
注意:给 redis-trib.rb的节点地址必须不能包括任何槽/数据的节点。
4、集群完整性检查:redis-trib.rb check 127.0.0.1:6379
九、节点通信
1、Gossip协议,信息交换,包括:消息头、消息体
- ping消息:用于检测节点是否在线和交换彼此状态信息,每秒。
- pong消息:响应
- meet消息:
- fail消息等:当节点判定集群内另一个节点下线时,会向集群内广播一个fail消息。
2、节点选择
3、通过cluster_node_timeout参数,可以影响集群信息交换的频率,从而影响故障转移、槽信息更新、新节点发现的速度。
ping消息的数量=1+10*num(node.pong_received>cluster_node_timeout/2)
4、集群伸缩:就是槽和数据在节点之间的移动
1)集群扩容:
- 准备新节点:redis-server conf/redis-6385.conf ...
- 加入集群:cluster meet 127.0.0.1 6385 或 redis-trib.rb add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> 。
- 迁移槽和数据:redis-trib.rb reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipleline <arg> 。
- redis-trib.rb rebalance host:port检查节点之间槽的均衡性。
- 添加从节点:cluster replicate {masterNodeId}。
2)集群收缩
- 下线迁移槽:redis-trib.rb reshard 127.0.0.1:6381
- 忘记节点:redis-trib.rb del-node {host:port} {downNodeId} 或 cluster forget {downNodeId}
- 先下线从节点,再下线主节点
5、请求路由
1)请求重定向
查看键所在的slot命令:cluster keyslot test:2
hash_tag:键内部使用大括号包含的内容叫hash_tag,它提供了不同的键可以具备相同slot的功能。例如:mget user:{10086}:friends user:{10086}:videos。
2)Smart客户端
Smart客户端通过在内部维护slot->node的映射关系,本地就可实现键到节点的查找,MOVED重定向负责协助Smart客户端更新slot->node映射。