集群模式是为了解决Redis的容量瓶颈,让Redis能够横向扩展
Redis分片集群
分片目标:提高性能,负载均衡,提升上限;
https://pdai.tech/md/db/nosql-redis/db-redis-x-cluster.html
- 横向扩展可达1000节点;
- 无代理模式,使用Gossip协议(p2p)去中心化;gossip协议
集群启动过程
1、启动节点
节点启动,会根据配置文件的:
cluster-enabled
来决定是否启动集群模式;
几乎启动方式都跟普通启动一样,只不过会新增2个结构:
- clusterState:集群状态信息;
- clusterNode:保存集群中所有节点的信息;(包括自己)
- 包括:IP、端口、节点名、槽信息等;
2、节点握手
master之间,通过cluster meet命令在Cluster Bus总线上完成节点握手;
3、槽指派
Redis集群通过分片方式,保存数据;
槽:16384个(是一个bit数组),共16384/8 = 2048字节 = 2KB;
- 当前节点所使用的槽的范围,其值置为1;
当所有槽全部指派给所有集群完毕,整个集群才能上线;
集群下的查询操作(非SmartClient)
1、客户端向节点发送键命令;(get/set) 2、节点根据key值计算槽
接受命令的服务器,会计算出key所在的槽;
def slot_number(key): return CRC16(key) & 16384
3、判断槽是否在当前节点:(查看槽数组的值是否为1)
- 在当前节点,直接进行键命令操作;
- 不在当前节点,查询出槽在哪个节点,向客户端返回MOVED重定向,引导正确的节点;
- 如果slot不存在,可能正在迁移;则返回ASK重定向,引导客户端到正在迁移的目标服务器;
4、客户端重新发送键命令到正确的节点;
SmartClient
1、客户端会向集群中的一个可用节点,发送命令,获取槽和节点的映射关系 2、在本地维护映射关系,在执行命令时,本地计算所属节点;节省了一次网络开销; 3、当映射关系变动时,客户端执行命令会出错,再次同步刷新映射关系;
集群下的事务操作
集群无法执行跨节点的事务,同一事务涉及的key,必须存储在同一个节点上;
要做到这一点,Redis提供了
hash tags
,提供给开发者通过命名key的方式,在分片时,将相关的key分到同一个节点;
hash tags
:当一个key中包含:{bussiness-1}.order
和 {bussiness-1}.payment
时,相同的tag会分到同一个节点;
集群扩缩容
1、启动新的Redis节点; 2、向集群中添加主节点 add-node命令将新Redis节点加入集群;
./redis-cli --cluster --add-node [新增节点] [集群节点]
添加slave节点,并指派主节点:
# --cluster-master-id [主节点id], [从节点ip], [主节点ip] ./src/redis-cli --cluster add-node --cluster-slave --cluster-master-id db10a9d5c1662d9e3ce 127.0.0.1:7008 127.0.0.1:7007
3、给新节点分配hash槽,根据命令提示,指定分配的槽点数量;
./redis-cli --cluster reshard [新增节点]
4、缩容类似;