分片键必须以country为前缀,如{country:1}或{country:1,userid:1};区域范围须基于分片键前缀定义、左闭右开且不重叠;shardcollection前须完成区域创建、范围设定及分片绑定;查询必须包含country条件才能精准路由。

分片键必须包含地域字段且为前缀
直接用 country 字段做单字段分片键最稳妥,比如 { country: 1 };若业务还需按用户细分,必须把地域字段放在复合键最左,例如 { country: 1, userid: 1 }。MongoDB 要求区域范围只能基于分片键的前缀定义,userid 单独加在前面或中间都会导致 sh.addShardToZone 失败。
常见错误是先建了 { userid: 1, country: 1 },再想按国家划区域——此时 country 不是前缀,所有 sh.updateZoneKeyRange 操作都会报错 keyPattern must be prefix of shard key。
区域范围必须左闭右开,且不能重叠
定义英国数据只落在欧洲分片时,命令得写成:
sh.updateZoneKeyRange("chat.messages", { country: "UK" }, { country: "UL" }, "eu-zone")
注意第二参数是下界(含),第三参数是上界(不含)。“UL” 是 “UK” 的字典后继,不是随便写的字符串。用 "UK" 到 "UK" 会覆盖空集;用 "UK" 到 "US" 会意外包含 “UM”“UN” 等非法国家码。
- ISO 3166-1 Alpha-2 码是固定两位,可用
String.fromCharCode(code.charCodeAt(1) + 1)算上界,比如"UK"→"UL" - 多个区域范围之间绝对不能交叉,否则 balance 过程会拒绝迁移,日志里出现
conflicting zone ranges - 范围必须覆盖全部可能值,漏掉
"DE"就意味着德国数据会被随机打散到所有分片
分片与区域绑定要在分片集合前完成
对空集合 messages 执行 sh.shardCollection 之前,必须先做完三件事:创建区域、设定范围、把分片加入区域。否则初始 chunk 分配不走区域逻辑,后续再补也无效——已生成的 chunk 不会自动挪动。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
典型顺序:
sh.addShardToZone("shard-eu", "eu-zone")
sh.addShardToZone("shard-us", "us-zone")
sh.updateZoneKeyRange("chat.messages", { country: "UK" }, { country: "UL" }, "eu-zone")
sh.updateZoneKeyRange("chat.messages", { country: "US" }, { country: "UT" }, "us-zone")
sh.shardCollection("chat.messages", { country: 1, userid: 1 })
如果先运行 shardCollection 再补区域,就得手动 moveChunk 或等 balancer 慢慢调整,期间读写可能跨地域路由,延迟不可控。
mongos 路由行为依赖查询是否命中分片键
查某国用户消息时,必须带 country 条件,例如 db.messages.find({ country: "DE", userid: 123 }),mongos 才能精准路由到德国对应分片。如果只查 { userid: 123 },mongos 只能广播到所有分片,哪怕数据物理上只存欧洲机房。
容易被忽略的是聚合管道:$lookup 关联其他集合时,若被关联集合没按同样地域分片,跨机房 JOIN 会放大延迟;$match 阶段没放 country,整个 pipeline 就失去地域亲和性。










