重新分片概述
Garnet 集群支持扩缩容操作,以应对需求波动或故障转移。集群操作员可以添加/删除节点并执行在线重新分片,而不会造成任何停机(即客户端在相关数据在节点之间迁移时仍能执行查询)。在底层,重新分片是通过结合使用 CLUSTER SETSLOT 和 MIGRATE 命令实现的。本页概述了这些命令支持的选项和功能,以及如何使用它们在可用主节点之间重新分片槽位的一些示例。有关此处提及的命令的更多详细信息,请查阅集群命令文档。
槽位迁移概述
将槽位从一个(源)主节点迁移到另一个(目标)主节点涉及以下步骤:
- 将目标节点上的槽位状态更改为 IMPORTING 状态。
- 将源节点上的槽位状态更改为 MIGRATING 状态。
- 将实际键从源节点迁移到目标节点。
- 通过更改槽位所有者和状态来通知目标和源节点所有权变更。
集群操作员可以手动执行上述步骤,方法是结合使用 CLUSTER SETSLOT、MIGRATE、CLUSTER COUNTKEYSINSLOT 和 CLUSTER GETKEYSINSLOT 命令,或者利用 MIGRATE 命令的变体自动执行所有步骤。
手动槽位迁移
在两个节点之间迁移槽位的第一步是分别将槽位设置为 IMPORTING 和 MIGRATING。这可以通过以下任一命令实现:
CLUSTER SETSLOT <slot> <IMPORTING node-id | MIGRATING node-id | NODE node-id | STABLE>
CLUSTER SETSLOTRANGE <IMPORTING node-id | MIGRATING node-id | NODE node-id | STABLE> start-slot end-slot [start-slot end-slot ...]
更改槽位状态可防止客户端在迁移完成之前在源节点执行写入操作。这确保了写入安全,但它不会阻止对现有键的读取。源节点会将对不存在键的读取和写入重定向到目标节点。客户端可以在每次写入前使用 ASKING 命令来覆盖写入限制。但是,这应该谨慎使用,因为没有采取任何保护措施来防止在迁移过程中丢失写入。
更改正在迁移的槽位状态后的下一步是查找所有哈希到相应迁移槽位的键,并将它们传输到目标节点。这通过以下命令实现:
CLUSTER COUNTKEYSINSLOT slot
CLUSTER GETKEYSINSLOT slot
migrate <host> <port> [KEY] | [destination-db] [COPY] [REPLACE] [AUTH password] [AUTH2 username password] [KEYS keys]
操作员可以使用上述命令遍历现有键并将它们传输到目标节点。当数据迁移完成时,操作员应该向源节点和目标节点发出 CLUSTER SETSLOT NODE <node-id>
以完成槽位所有权更改。如果迁移失败,集群操作员负责解决任何可能的错误,以使集群处于稳定状态。这可以通过根据需要结合使用以下命令来完成:
CLUSTER SETSLOT STABLE
CLUSTER DELKEYSINSLOT <slot>
CLUSTER DELKEYSINSLOTRANGE start-slot end-slot [start-slot end-slot ...]
.
自动槽位迁移
手动迁移键是一项繁琐且容易出错的操作。集群操作员可以通过利用 migrate 命令的一个变体来克服这个问题,该变体一次迁移整个槽位或槽位范围。
migrate <host> <port> [KEY] | [destination-db] [COPY] [REPLACE] [AUTH password] [AUTH2 username password] [[SLOTS slot] [SLOTSRANGE start-slot end-slot [start-slot end-slot ...]]
migrate 命令的 slots 变体将自动执行上述所有操作。它将生成一个后台进程来执行所有必要的操作。集群操作员可以通过使用以下命令来监控迁移进度:
CLUSTER MTASKS
CLUSTER SLOTSTATE <slot>
迁移槽位示例
本节提供了一个关于如何使用迁移槽位选项一次迁移多个槽位的示例。此示例假设存在一个包含 2 个节点的集群部署,如下所示:
127.0.0.1:7000> cluster nodes
7e59ecfef6cae5e22b47d8f63c789a1e66031a60 192.168.1.26:7000@17000,test-host1 myself,master - 0 0 1 connected 0-8191
4cb7e9cb54684d20f777c2916145acfd6be48efe 192.168.1.26:7001@17001,test-host2 master - 0 0 2 connected 8192-16383
在将数据添加到节点 2 后,我们可以识别哪些槽位包含相应的键。为了此测试用例的目的,我们将仅将相关槽位移动到节点 1。或者,我们可以手动移动整个槽位范围或单个键。
PS C:\Dev> redis-cli -p 7001
127.0.0.1:7001> set x 12
OK
127.0.0.1:7001> set y 22
OK
127.0.0.1:7001> set a 33
OK
127.0.0.1:7001> set d 44
OK
127.0.0.1:7001> get x
"12"
127.0.0.1:7001> get y
"22"
127.0.0.1:7001> get a
"33"
127.0.0.1:7001> get d
"44"
127.0.0.1:7001> cluster nodes
4cb7e9cb54684d20f777c2916145acfd6be48efe 192.168.1.26:7001@17001,test-host2 myself,master - 0 0 2 connected 8192-16383
7e59ecfef6cae5e22b47d8f63c789a1e66031a60 192.168.1.26:7000@17000,test-host1 master - 0 0 1 connected 0-8191
127.0.0.1:7001> cluster keyslot x
(integer) 16287
127.0.0.1:7001> cluster keyslot y
(integer) 12222
127.0.0.1:7001> cluster keyslot a
(integer) 15495
127.0.0.1:7001> cluster keyslot d
(integer) 11298
要移动单个槽位,我们使用 SLOTS 选项,如下所示:
127.0.0.1:7001> migrate 192.168.1.26 7000 "" 0 -1 SLOTS 16287 12222 15495 11298
OK
127.0.0.1:7001> cluster nodes
4cb7e9cb54684d20f777c2916145acfd6be48efe 192.168.1.26:7001@17001,test-host2 myself,master - 0 0 2 connected 8192-11297 11299-12221 12223-15494 15496-16286 16288-16383
7e59ecfef6cae5e22b47d8f63c789a1e66031a60 192.168.1.26:7000@17000,test-host1 master - 0 0 3 connected 0-8191 11298 12222 15495 16287
迁移完成后,我们可以通过在每个节点上调用 cluster nodes
来查看更新的配置。此时,如果向节点 2 发出读取请求,我们将收到重定向到节点 1 的消息。要访问已迁移的键,由于节点 1 是与相应键关联的槽位的所有者,因此我们必须连接到节点 1。
127.0.0.1:7001> get x
(error) MOVED 16287 192.168.1.26:7000
127.0.0.1:7001> get y
(error) MOVED 12222 192.168.1.26:7000
127.0.0.1:7001> get a
(error) MOVED 15495 192.168.1.26:7000
127.0.0.1:7001> get d
(error) MOVED 11298 192.168.1.26:7000
127.0.0.1:7001> exit
PS C:\Dev> redis-cli -p 7000
127.0.0.1:7000> get x
"12"
127.0.0.1:7000> get y
"22"
127.0.0.1:7000> get a
"33"
127.0.0.1:7000> get d
"44"
127.0.0.1:7000> cluster nodes
7e59ecfef6cae5e22b47d8f63c789a1e66031a60 192.168.1.26:7000@17000,test-host1 myself,master - 0 0 3 connected 0-8191 11298 12222 15495 16287
4cb7e9cb54684d20f777c2916145acfd6be48efe 192.168.1.26:7001@17001,test-host2 master - 0 0 2 connected 8192-11297 11299-12221 12223-15494 15496-16286 16288-16383
127.0.0.1:7000>