doc: 阅读redis cluster的slot migration文档

This commit is contained in:
asahi
2025-09-29 15:33:43 +08:00
parent e47dc4711e
commit f159c6cc0e

View File

@@ -216,6 +216,11 @@
- [Redirection and Resharding](#redirection-and-resharding) - [Redirection and Resharding](#redirection-and-resharding)
- [MOVED Redirection](#moved-redirection) - [MOVED Redirection](#moved-redirection)
- [Live reconfiguration](#live-reconfiguration) - [Live reconfiguration](#live-reconfiguration)
- [ADDSLOTS/DELSLOTS](#addslotsdelslots)
- [MIGRATING/IMPORTING](#migratingimporting)
- [MIGRATE](#migrate)
- [`CLUSTER GETKEYSINSLOT`](#cluster-getkeysinslot)
- [MIGRATE](#migrate-1)
# redis # redis
@@ -3422,6 +3427,7 @@ client不必须但是应该记住`hash slot 3999被127.0.0.1:6381管理`。
当集群处于稳定状态下时,最终所有客户端都会获取到`map of hash slots`确保cluster效率更高client无需重定向就能查询到正确的nodes。 当集群处于稳定状态下时,最终所有客户端都会获取到`map of hash slots`确保cluster效率更高client无需重定向就能查询到正确的nodes。
#### Live reconfiguration #### Live reconfiguration
##### ADDSLOTS/DELSLOTS
Redis Cluster支持在运行时动态添加、移除nodes的能力。对redis cluster而言节点的增加和移除被抽象为相同的行为`moving a hash slot from one node to another`。上述机制也能被用于cluster的rebalance。 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时`some set of hash slots from existing nodes`将会被移动到新的节点
- 将节点从cluster中被移除时`hash slots assigned to that node`将会被移动到其他的existing nodes - 将节点从cluster中被移除时`hash slots assigned to that node`将会被移动到其他的existing nodes
@@ -3448,13 +3454,54 @@ Redis Cluster支持在运行时动态添加、移除nodes的能力。对redis cl
> `ADDSLOTS, DELSLOTS, ADDSLOTSRANGE, DELSLOTSRANGE`命令只修改slot归属`不负责数据的迁移或删除`。 > `ADDSLOTS, DELSLOTS, ADDSLOTSRANGE, DELSLOTSRANGE`命令只修改slot归属`不负责数据的迁移或删除`。
`SETSLOT`命令则用作则如下:
- `SETSLOT slot Node node`: assign a slot to a specific node ID - `SETSLOT slot Node node`: assign a slot to a specific node ID
##### MIGRATING/IMPORTING
除了通过ADDSLOTS/DELSLOTS改变slots的归属外slot还可以被设置为两个特殊的状态`MIGRATING`, `IMPORTING`。上述这两个特殊状态用于`migrate a hash slot from one node to another`由于ADDSLOTS/DELSLOTS只负责修改slot归属并不负责数据迁移故而在数据迁移时需要通过`MIGRATING/IMPORTING`来支持)
`SETSLOT`命令则用作则如下:
- `SETSLOT slot MIGRATING/IMPORTING node`:主要用于将hash slot从一个节点迁移到另一个节点 - `SETSLOT slot MIGRATING/IMPORTING node`:主要用于将hash slot从一个节点迁移到另一个节点
-使用`MIGRATING`时,仅当key在node中存在时该node将会接收所有针对该hash slot的查询否则query将会通过ASK进行重定向 -slot被标记为`MIGRATING`时,代表node为迁移的`源节点`。当该节点接收到关于该hash slot的请求时
- 当使用`IMPORTING`仅当request前缀ASKING时该node会接收所有针对该hash slot的查询如果client发送请求时并没有指定ASKING那么将会返回`MOVED error`,将请求重定向到`owner of the hash slot` - 如果请求中的key存在则服务该请求
- 如果请求中的key不存在则可能已经迁移到目标节点中此时会使用`ASK`重定向,将请求转发到迁移的`目标节点`
- 当slot被设置为`IMPORTING`代表node为迁移的`目标节点`。该节点只在`request is preceded by an ASKING command`时,才会服务该请求
- 如果client在发送针对slot的请求前没有先发送`ASKING`命令,那么当前请求将会通过`MOVED` redirection error被转发给`source node`(此时,数据迁移尚未完成,迁移的源节点仍然被视为`owner of the slot`
按照上述描述slot迁移的示例如下所示
- 假设拥有两个master nodes分别为`A, B`,如果希望将`slot 8`从node A移动到`node B`,那么发送的命令如下所示:
- 向node B发送`CLUSTER SETSLOT 8 IMPORTING A`
- 该命令将node B标记为了目标节点并指定源节点为A
- 向node A发送`CLUSTER SETSLOT 8 MIGRATING B`
- 该命令将目标A标记为了源节点并指明了目标节点B
此时节点A作为slot迁移的源节点在迁移过程中仍然被cluster看作是`owner of hash slot`。故而,当其他节点接收到关于`迁移中slot`的请求时仍然将其重定向到node A此时A对于请求的处理如下
- 如果请求的key仍在node A中存在那么node A处理该请求
- 如果请求的key不再node A中那么其会通过`ASK`将请求重定向到B此时客户端首先向node B发送`ASKING`,然后再重新发送请求
> 在节点迁移过程中不仅允许对key执行读操作也允许对其执行写操作。例如若key之前在集群中不存在并且被hash到`slot 8`,此时`slot 8`正在迁移。故而client针对key的创建操作会先被`MOVED error`重定向到源节点`node A``node A`中并没有该key故而会被`ASK`重定向到目标节点`node B`。此时,`node B`会处理client的key创建请求。
>
> `故而在slot迁移的过程中针对slot中key的创建统一在目标节点处写入创建操作并不由源节点处理。`
##### MIGRATE
可以通过在`redis-cli`中执行如下命令来将slot中的keys来进行迁移
###### `CLUSTER GETKEYSINSLOT`
```redis-cli
CLUSTER GETKEYSINSLOT slot count
```
该命令将会返回指定hash slot中`count`数量的keys。对于返回的keys可以通过`MIGRATE`命令来进行迁移从A到B的迁移是原子的来源和目标instance都会会locked
###### MIGRATE
```redis-cli
MIGRATE target_host target_port "" target_database id timeout KEYS key1 key2 ...
```
上述命令将会连接到目标节点,发送`serialized version of the key`,并且一旦接收到`OK` code之后源节点中key将会被删除。
> 故而在任何时刻对于外部client而言key要么存在于A中要么存在于B中。
在redis cluster中无需将database指定为`0`之外的值,此处支持`database`选项主要是为了redis cluster外的其他场景。`MIGRATE`命令经过优化,即使在移动`long lists`之类的复杂key也能保持较快的速度。
当迁移过程结束之后,`SETSLOT <slot> NODE <node-id>`命令将会被发送给涉及迁移的两个节点从而将slots重新设置回其正常状态之前状态为MIGRATING/IMPORTING。通常情况下该命令也会被发送给其他所有节点从而避免`new configuration`在集群间的传播耗费太长时间。
`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`