Redis Cluster
Redis Cluster
Redis Cluster
- redis提供了3中分布式方案
- 主从模式、哨兵模式、集群模式
- 主从和哨兵模式只是解决单点故障问题, 提高读并发性能
- 集群模式则可以做到扩展redis的内存
- 多组主从节点构成一个集群
集群节点初始化
- 每个集群节点通过配置项开启集群功能
- 启动redis-server, 进入clusterInit()
- 此时节点生成了, 但是集群间是没有通信的
- 每个开启集群的节点都有关于集群的信息(clusterState) (刚开始是默认值)
- redis集群是去中心化的, 每个节点都存一份clusterState
配置文件
1
2
3
cluster-enabled yes # 打开集群模式
cluster-config-file nodes-6379.conf # 设定节点配置文件名
cluster-node-timeout 15000 # 设定节点失联时间, 超过该时间(毫秒), 集群自动进行主从切换
clusterState
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct clusterNode {
char name[REDIS_CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */
int flags; /* REDIS_NODE_... */
unsigned char slots[REDIS_CLUSTER_SLOTS/8]; /* slots handled by this node */
int numslots; /* Number of slots handled by this node */
int numslaves; /* Number of slave nodes, if this is a master */
struct clusterNode **slaves; /* pointers to slave nodes */
struct clusterNode *slaveof; /* pointer to the master node */
} clusterNode;
typedef struct clusterState {
clusterNode *myself; /* This node */
dict *nodes; /* Hash table of name -> clusterNode structures */
zskiplist *slots_to_keys;
} clusterState;
集群建立连接
redis-cli --cluster create --cluster-replicas {x} addr1 addr2 ...--cluster-replicas用于指定有多少个备份节点(就是从节点, 用于故障切换)- 例如有addr1-addr4, 然后指定x=1(一个master有一个从节点)
- addr1, addr2就会被设置成master
- addr3, addr4分别是其从节点
- 建立连接的过程就是每个节点将clusterState完善的过程
- 除了nodes外, 主要要对master节点进行slot的分配
集群slot & 读写数据
- slot的范围是[0 - 16*1024-1]
- crc16(key) belongs [0 - 16*1024-1]
- slot被划分给master节点
- key会通过crc16(hash算法)计算应该落在哪个slot中
- 每个节点通过一个bitmap来记录自己拥有哪些slot
- bitmap就是unsigned char, 因为char是1字节, 因此分配REDIS_CLUSTER_SLOTS/8的空间
- unsigned char slots[REDIS_CLUSTER_SLOTS/8]
- 当写入数据时, 除了正常写数据, 还需要维护一个跳表
- zskiplist *slots_to_keys
- 这个跳表中score是hashslot(类似于slot的index), redisObject是key
- zslInsert(server.cluster->slots_to_keys,hashslot,key)
- 这个跳表可以用于快速判断自己拥有的slot中, 哪些有数据
- zslFirstInRange(server.cluster->slots_to_keys, &range)
集群新增/移除节点 & slot迁移
- 当集群新加入一个节点时, 这个新节点是不拥有slot的(此时这个新节点不能进行读写)
- 此时需要从其他节点中迁移slot (reshard)
redis-cli --cluster reshard addr1
- 删除节点同样需要reshard slot
- 这里的删除不是发生故障, 而是将节点从集群中除去
集群的故障转移
- 集群通过内部机制实现故障转移, 与哨兵机制不同
- redis集群是去中心化的
- 各master之间互相发送Ping/Pong信息
- 当某个节点发现另一个节点故障(此时为主观故障)
- 然后它向剩余节点发送FAIL消息, 要求剩下的节点进行投票
- 当超过半数节点认为节点主观故障, 则标记为客观故障
- 出现客观故障节点后, 进行故障转移
- 从它的从节点中选一个成为master
This post is licensed under CC BY 4.0 by the author.