doc: 阅读redis cluster文档
This commit is contained in:
@@ -212,6 +212,10 @@
|
||||
- [CLUSTER NODES](#cluster-nodes)
|
||||
- [Cluster bus](#cluster-bus)
|
||||
- [Cluster topology](#cluster-topology)
|
||||
- [node handshake](#node-handshake)
|
||||
- [Redirection and Resharding](#redirection-and-resharding)
|
||||
- [MOVED Redirection](#moved-redirection)
|
||||
- [Live reconfiguration](#live-reconfiguration)
|
||||
|
||||
|
||||
# redis
|
||||
@@ -3385,4 +3389,72 @@ redis cluster是一个`full mesh`结构,集群中每个node都和其他所有
|
||||
|
||||
redis cluster nodes组成了full mesh,但是node使用了`gossip protocol`和`configuration update mechanism`用于避免`nodes之间的消息交换过于频繁`。故而,消息交换的数量并非指数级增长。
|
||||
|
||||
#### node handshake
|
||||
node会从cluster bus port接收连接,当接收到ping时会返回响应,即使发出ping的node并不可信。除了ping packet之外,如果接收方node认为发送方节点并不是cluster中的一员,那么接收方会丢弃所有发送方除了ping packet之外的packets。
|
||||
|
||||
只有在如下两种场景下,一个node才会将应一个node认作集群的一部分:
|
||||
- 如果一个节点通过`MEET` message来展示其自身(CLUSTER MEET命令)。meet message和`PING` message类似,但是会强制接收方将其作为cluster的一部分来接受。只有当系统管理员通过`CLUSTER MEET ip port`命令来发送请求时,node才向其他nodes发送meet message。
|
||||
- 如果一个已经受信任的节点通过gossip传播了关于`node C`的消息,那么其他节点也会将`node C`注册为集群的一部分。
|
||||
- 例如,`A knows B`,`B knows C`,最终B会向A发送关于C的gossip messages。当该行为发生时,A会将C注册为network的补一份,并且尝试和C建立连接
|
||||
|
||||
上述示例代表,只要将节点加入到`connected graph`,其最终自动会形成一个`fully connected graph`(尚未连接的nodes会两两自动建立连接)。在cluster中,只要管理员强制建立信任关系,节点能够自动发现其他节点。
|
||||
|
||||
### Redirection and Resharding
|
||||
#### MOVED Redirection
|
||||
一个redis client可以向cluster中所有的节点发送请求,包括replica nodes。该node会分析请求,如果请求时可接受的(在query中只有一个key,或多个key被hash到相同的slot中),那么其会分析key由哪个node负责:
|
||||
- 如果node本身负责该slot,那么该请求将会被执行
|
||||
- 否则,node将会向client返回`MOVED error`,示例如下所示:
|
||||
```redis-cli
|
||||
GET x
|
||||
-MOVED 3999 127.0.0.1:6381
|
||||
```
|
||||
|
||||
上述error代表key对应的hash slot(3999)和负责该key实例的`endpoint:port`值。client需要重新向`endpoint:port`发送请求。
|
||||
> 上面示例中,`endpoint`可以是一个ip address,hostname,或可以为空(`-MOVED 3999 :5380)
|
||||
> - 当endpoint为空时,代表server node拥有unknown endpoint,client应该将下一个请求发送给`当前请求的endpoint`,但是使用响应中的port
|
||||
|
||||
在client重新发送请求之前,如果间隔时间较长,此时cluster configuration可能会发生变动,此时再发送请求,如果负责该key的节点发生变化,目前节点仍可能会返回一个MOVED error。
|
||||
|
||||
client不必须,但是应该记住`hash slot 3999被127.0.0.1:6381管理`。之后如果新command对该hash slot发送请求,那么其可以直接针对正确的节点发送请求,避免重定向带来的开销。
|
||||
|
||||
对client而言,另一个可选项是`在接收到MOVED redirection之后,通过CLUSTER SHARDS命令清空整个client-side cluster layout`。通常而言,当遇到重定向时,更可能是多个slots都被reconfigured,此时尽快更新client configuration是更好的策略。
|
||||
|
||||
当集群处于稳定状态下时,最终所有客户端都会获取到`map of hash slots`,确保cluster效率更高,client无需重定向就能查询到正确的nodes。
|
||||
|
||||
#### Live reconfiguration
|
||||
Redis Cluster支持在运行时动态添加、移除nodes的能力。对redis cluster而言,节点的增加和移除被抽象为相同的行为:`moving a hash slot from one node to another`。上述机制也能被用于cluster的rebalance。
|
||||
- 将新节点添加到cluster时,`some set of hash slots from existing nodes`将会被移动到新的节点
|
||||
- 将节点从cluster中被移除时,`hash slots assigned to that node`将会被移动到其他的existing nodes
|
||||
- 在cluster进行rebalance时,`a given set of hash slots`将会在节点之间进行移动
|
||||
|
||||
实现上述内容的核心是`hash slots的移动`。从实际角度来看,hash slots是一系列keys的集合,故而在redis cluster进行resharding时,就是将keys从一个实例移动到另一个实例。`移动hash slot`代表`移动被hash到该slot的keys`。
|
||||
|
||||
`CLUSTER`命令拥有如下`subcommands`来操作redis cluster node中的`slot translation table`:
|
||||
- `CLUSTER ADDSLOTS slot1 [slot2]...[slotN]`
|
||||
- `CLUSTER DELSLOTS slot1 [slot2]...[slotN]`
|
||||
- `CLUSTER ADDSLOTSRANGE start-slot1 end-slot1 [start-slot2 end-slot2]...[start-slotN end-slotN]`
|
||||
- `CLUSTER DELSLOTSRANGE start-slot1 end-slot1 [start-slot2 end-slot2]...[start-slotN end-slotN]`
|
||||
- `CLUSTER SETSLOT slot NODE node`
|
||||
- `CLUSTER SETSLOT slot MIGRATING node`
|
||||
- `CLUSTER SETSLOT slot IMPORTING node`
|
||||
|
||||
在上述命令中,`ADDSLOTS, DELSLOTS, ADDSLOTSRANGE, DELSLOTSRANGE`四个命令用于`assign/remove slots to redis node`。(`Assigning a slot means to tell a given master node that it will be in charge of storing and serving content for the specified hash slot`)
|
||||
|
||||
当hash slots被分配后,其将会通过gossip protocol在cluster的范围内传播该信息。
|
||||
|
||||
`ADDSLOTS/ADDSLOTSRANGE`命令通常在`新集群被从头创建,为每个master节点分配所有16384个hash slots的子集时`被使用。
|
||||
|
||||
`DELSLOTS/DELSLOTSRANGE`则主要在手动修改cluster configuration时被使用,通常其使用场景较少。
|
||||
|
||||
> `ADDSLOTS, DELSLOTS, ADDSLOTSRANGE, DELSLOTSRANGE`命令只修改slot归属,`不负责数据的迁移或删除`。
|
||||
|
||||
`SETSLOT`命令则用作则如下:
|
||||
- `SETSLOT slot Node node`: assign a slot to a specific node ID
|
||||
- `SETSLOT slot MIGRATING/IMPORTING node`:主要用于将hash slot从一个节点迁移到另一个节点
|
||||
- 当使用`MIGRATING`时,仅当key在node中存在时,该node将会接收所有针对该hash slot的查询;否则query将会通过ASK进行重定向
|
||||
- 当使用`IMPORTING`时,仅当request前缀ASKING时,该node会接收所有针对该hash slot的查询;如果client发送请求时并没有指定ASKING,那么将会返回`MOVED error`,将请求重定向到`owner of the hash slot`
|
||||
|
||||
`slot migration`的示例如下,假设存在两个redis master nodes:`A和B`。如果想要将hash slot 8从A移动到B,那么可以发送如下命令:
|
||||
- send B: `CLUSTER SETSLOT 8 IMPORTING A`
|
||||
- send A: `CLUSTER SETSLOT 8 MIGRATING B`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user