bigywater.tech
MongoDB · 77

zone sharding

怎么让某个区域的数据落在指定的分片上?zone sharding 怎么配、balancer 怎么执行、改 zone 会怎样?这篇给 3 个分片打 EU / US 标签,按 region 前缀的分片键验证数据的迁移。

8,000
eu 区域迁到 EU 分片 sh0 的文档数
19 个
配置 zone 后 chunk 数:边界上被切开
15 秒
改 zone 后 US 区域 8,000 个文档搬到新分片 sh2 所用的时间

配置

实测 · 本机执行输出
  分片的 zone: [('sh0', ['EU']), ('sh1', ['US']), ('sh2', None)]
  zone 的键范围(config.tags): [('EU', {'region': 'eu', 'uid': MinKey()}, {'region': 'eu', 'uid': MaxKey()}), ('US', {'region': 'us', 'uid': MinKey()}, {'region': 'us', 'uid': MaxKey()})]

addShardToZone 给分片打标签,updateZoneKeyRange 把分片键范围绑定到 zone。分片键必须以区域字段为前缀。

迁移

实测 · 本机执行输出
  各分片上各区域的文档数 (分片, 区域): {('sh1', 'eu'): 8000, ('sh1', 'us'): 8000, ('sh1', 'apac'): 8000}

balancer 按 zone 把数据迁到对应分片:eu 迁到 EU 分片 sh0,us 留在 US 分片 sh1。

chunk 边界

实测 · 本机执行输出
  balancer 开了 150 秒后各分片上各区域的文档数(含尚未清理的孤儿): {('sh0', 'eu'): 8000, ('sh1', 'eu'): 8000, ('sh1', 'us'): 8000, ('sh1', 'apac'): 8000, ('sh2', 'apac'): 6951}
  各分片拥有的文档数(不含孤儿): {'sh1': 9049, 'sh2': 6951, 'sh0': 8000}

chunk 在 zone 范围的端点被切开,每个 chunk 要么完全属于某个 zone,要么在空隙里。

改 zone

实测 · 本机执行输出
  共 19 个 chunk;各分片 chunk 数 {'sh0': 8, 'sh1': 4, 'sh2': 7}
  跨 region 边界的 chunk(它们的 min/max 的 region 不同): ['sh2  [MinKey()/MinKey(), apac/119390085)', 'sh1  [apac/868601189, eu/MinKey())', 'sh1  [eu/MaxKey(), us/MinKey())', 'sh1  [us/MaxKey(), MaxKey()/MaxKey())']

把 US 范围从 sh1 改到 sh2 后,balancer 自动把 8,000 个文档搬过去,应用不用改。

无 zone 的数据

实测 · 本机执行输出
  改 zone 后 15 秒:各分片拥有的文档数 {'sh2': 14951, 'sh0': 8000, 'sh1': 1049};sh2 上 us 区域的文档 8000

不属于任何 zone 范围的数据(apac)按普通方式平衡。

孤儿

实测 · 本机执行输出
  apac 的 8,000 个文档在各分片上(直连计数,含孤儿): {'sh0': 0, 'sh1': 8000, 'sh2': 6951};各分片拥有的文档数总计 {'sh0': 8000, 'sh1': 1049, 'sh2': 14951}

直连分片看到的文档数包含迁走后尚未清理的孤儿文档。

分步演示

zone sharding
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / MongoDB 9.0.2(Homebrew 的 mongod、mongos)/ mongosh 2.12.0 / pymongo 4.18.3;每个实验在临时目录里起全新的 mongod(独立 dbpath,端口 9900 以上,只监听 127.0.0.1,WiredTiger 缓存 0.25 GB),需要副本集或分片集群时在本机起多个进程;命令输出来自真实的 mongosh,批量写入、计时与多线程用 pymongo;计时用 time.perf_counter,数字每次运行会有小幅抖动,ObjectId、时间戳等每次运行都不同。3 个分片(各为单节点副本集),chunk 1 MB;zone 的 EU / US 只是标签,本机并没有地域延迟
    • 没有验证:zone 范围与 chunk 迁移限速;没有 zone 的分片能否接收有 zone 的数据(这里 apac 分到 sh2 和留在 sh1,是否因为 sh1 是无 zone 约束尚未细究);zone 与 hashed 分片键(需要 presplitHashedZones);读偏好与 zone 的联动(就近读);删除 zone 范围后数据是否回迁
    京ICP备2026067502号-1京公网安备11010502063487号