doc: 阅读redis cluster文档

This commit is contained in:
asahi
2025-09-29 13:50:13 +08:00
parent 97c4a830a9
commit e47dc4711e

View File

@@ -212,6 +212,10 @@
- [CLUSTER NODES](#cluster-nodes) - [CLUSTER NODES](#cluster-nodes)
- [Cluster bus](#cluster-bus) - [Cluster bus](#cluster-bus)
- [Cluster topology](#cluster-topology) - [Cluster topology](#cluster-topology)
- [node handshake](#node-handshake)
- [Redirection and Resharding](#redirection-and-resharding)
- [MOVED Redirection](#moved-redirection)
- [Live reconfiguration](#live-reconfiguration)
# redis # redis
@@ -3385,4 +3389,72 @@ redis cluster是一个`full mesh`结构集群中每个node都和其他所有
redis cluster nodes组成了full mesh但是node使用了`gossip protocol`和`configuration update mechanism`用于避免`nodes之间的消息交换过于频繁`。故而,消息交换的数量并非指数级增长。 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 slot3999和负责该key实例的`endpoint:port`值。client需要重新向`endpoint:port`发送请求。
> 上面示例中,`endpoint`可以是一个ip addresshostname或可以为空`-MOVED 3999 :5380
> - 当endpoint为空时代表server node拥有unknown endpointclient应该将下一个请求发送给`当前请求的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`