Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

sh.updateZoneKeyRange()

在此页面上

  • 定义
  • 兼容性
  • 行为
  • 示例
sh.updateZoneKeyRange(namespace, minimum, maximum, zone)

将范围分分片键与区域关联。

您可以在未分片的集合或不存在的集合上运行updateZoneKeyRange数据库命令及其助手 sh.updateZoneKeyRange()sh.addTagRange()

重要

mongosh 方法

本页面提供 mongosh 方法的相关信息。这不是数据库命令或特定语言驱动程序(例如 Node.js)的相关文档。

有关数据库命令,请参阅 updateZoneKeyRange 命令。

如需了解 MongoDB API 驱动程序,请参阅特定语言的 MongoDB 驱动程序文档。

sh.updateZoneKeyRange() 采用以下参数:

Parameter
类型
说明
namespace
字符串

分片集合的命名空间zone关联。

必须对集合进行分片才能使操作成功。

minimum
文档

片键值范围的下限(含)。

<fieldname> : <value>的形式指定分片键的每个字段。 该值必须与分片键具有相同的 BSON 类型。

要使用哈希分片,字段值的类型必须为NumberLong

maximum
文档

片键值范围的独占上限。

<fieldname> : <value>的形式指定分片键的每个字段。 该值必须与分片键具有相同的 BSON 类型。

要使用哈希分片,字段值的类型必须为NumberLong

zone
字符串
与以minimummaximum为界的分片键值范围关联的区域名称。

仅在连接到 实例时发出sh.updateZoneKeyRange() mongos

此方法可用于以下环境中托管的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

重要

无服务器实例不支持此命令。 有关更多信息,请参阅不支持的命令。

您创建的分片键值范围的下边界和上边界不能与分片集合的现有范围重叠。 例如,给定110的现有范围,您无法创建520的新范围,因为新范围将与现有范围重叠。

一个区域可以有多个与之关联的数据范围,但一个范围最多只能与一个区域关联。

有关分片集群中区域的更多信息,请参阅区域手册页面。

如果您考虑对空集合或不存在的集合执行 区域分片 ,请在对集合分片 之前sh.updateZoneKeyRange() 使用 创建区域和区域范围( 自 起4.0.2 )。从版本4开始。 0 。 3 、 在空集合或不存在的集合上创建区域和区域范围允许 MongoDB 在对集合进行分片时优化初始数据段创建和分配过程。 与在分片后创建区域相比,这种优化的流程支持更快地设置分区分片,并且负载均衡器开销更少。 负载均衡器在优化初始数据段创建和分配后执行所有数据段管理。

有关为初始数据段分布定义区域和区域范围的示例,请参阅为空集合或非现有集合预定义区域和区域范围。

MongoDB 支持对复合哈希索引上的集合进行分片。 在复合哈希分片键上对空集合或不存在的集合进行分片时,MongoDB 可以执行优化的初始数据段创建和分配。

如果哈希字段是分片键的前缀(即分片键中的第一个字段),则必须满足以下所有条件,MongoDB 才能执行初始数据段创建和分发:

如果哈希字段不是分片分片键的前缀(即分片分片键具有一个或多个非哈希前导字段),则必须满足以下所有条件, MongoDB才能执行初始数据块创建和分配:

  • 该集合为不同前缀字段值的每个组合(即 哈希字段之前的所有字段)。

  • 对于每个区域范围的下限,请为哈希字段和所有后续字段指定MinKey

  • 对于每个区域范围,至少有一个上限前缀字段必须与其对应的下限前缀字段不同。

  • sh.shardCollection()指定presplitHashedZones: true选项。

有关在复合哈希分片键上为初始数据段分布定义区域和区域范围的更完整示例,请参阅为空或不存在的集合预定义区域和区域范围。

提示

另请参阅:

将范围与区域关联后,负载均衡器必须首先运行,以便将范围被区域覆盖的任何数据段迁移到该区域内的分片。 在均衡完成之前,考虑到为分片集群配置的区域,某些数据段可能驻留在错误的分片上。 有关更多信息,请参阅负载均衡器

有关迁移如何在分片集群中工作的更多信息,请参阅分片集群负载均衡器手册页面。

区域范围始终包括下边界,但不包括上边界。

删除集合将删除其关联的区域/标记范围。

在早期版本中,MongoDB 不会删除已删除集合的标签关联,如果您稍后创建同名的新集合,则旧标签关联将应用于新集合。

对于使用身份验证运行的分片集群,您必须通过以下任一项身份验证:

  • 其权限包括对config数据库中的各种集合执行指定操作的用户:

    • find config.shards集合上的

    • findupdate集合上的config.tags 和 ;

    或者,

  • 权限包括对enableSharding 集群 资源的 的用户。

clusterAdminclusterManager内置角色具有发出sh.updateZoneKeyRange()的适当权限。 有关更多信息,请参阅基于角色的访问控制的文档页面。

给定分片键为{ a : 1 }的分片集合exampledb.collection ,以下操作在alpha区域上创建一个下限为1且上限为10的范围:

sh.updateZoneKeyRange(
"exampledb.collection",
{ a : 1 },
{ a : 10 },
"alpha"
)

以下操作通过将null传递给zone字段来删除之前创建的范围。

sh.updateZoneKeyRange(
"exampledb.collection",
{ a : 1 },
{ a : 10 },
null
)

minmax必须与目标范围的边界完全匹配。 以下操作尝试删除之前创建的范围,但将{ a : 0 }指定为min边界:

sh.updateZoneKeyRange(
"exampledb.collection",
{ a : 0 },
{ a : 10 },
null
)

虽然{ a : 0 }{ a : 10 }的范围包含现有范围,但它不是精确匹配,因此updateZoneKeyRange不会删除任何内容。

给定分片键为{ a : 1, b : 1 }的分片集合exampledb.collection ,以下操作创建一个覆盖{ a: 1, b : 1 }下限和{ a : 10, b : 10}上限的范围,并将其与alpha区域关联:

sh.updateZoneKeyRange(
"exampledb.collection",
{ a : 1, b : 1 },
{ a : 10, b : 10 },
"alpha"
)

如果在空集合或不存在的集合上创建区域和区域范围,则在对集合进行分片时,MongoDB 可能会优化初始数据段创建和分配过程。 与在分片后创建区域相比,这种优化的流程支持更快地设置分区分片,并且负载均衡器开销更少。 负载均衡器在优化初始数据段创建和分配后执行所有数据段管理。 有关更多信息,请参阅使用复合哈希分片键进行初始数据段分发

以下部分包含三种不同分片键类型的示例。

请考虑以下示例,这些示例探索了三种不同分片键类型的预定义区域或区域范围:

注意

此示例仅适用于没有哈希字段的单字段或复合分片键。

例如, { "zip" : 1 }{ "zip" : 1, "account" : 1}

1

使用sh.addShardToZone()创建区域:

sh.addShardToZone("shardA", "DC1")
sh.addShardToZone("shardB", "DC2")
2

使用sh.updateZoneKeyRange()exampledb数据库中的空contacts集合创建范围:

sh.updateZoneKeyRange(
"exampledb.contacts",
{ zip: 10001 },
{ zip: 10090 },
"DC1"
);
sh.updateZoneKeyRange(
"exampledb.contacts",
{ zip: 90001 },
{ zip: 96054 },
"DC2"
);
3

注意

如果该集合不存在,则分片操作会创建该集合。

如果集合为空且不存在支持分片键的索引,则分片操作会创建索引。

使用sh.shardCollection()对集合contacts进行分片:

sh.shardCollection("exampledb.contacts", { zip: 1 } );
4

要查看创建的数据段和分布,请运行sh.status()操作:

sh.status()

该方法返回:

--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5b80c06d35a961fd0ae1986d")
}
shards:
{ "_id" : "shardA", "host" : "shardA/mongodb0.example.net:27018,mongodb1.example.net:27018,mongodb2.example.net:27018", "state" : 1, "tags" : [ "DC1" ] }
{ "_id" : "shardB", "host" : "shardB/mongodb3.example.net:27018,mongodb4.example.net:27018,mongodb5.example.net:27018", "state" : 1, "tags" : [ "DC2" ] }
active mongoses:
"4.2.0" : 2
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "config", "primary" : "config" }
{ "_id" : "exampledb", "primary" : "shardA", "version" : { "uuid" : UUID("6c351bcf-acd2-4fd9-82d8-9f6bd7321558"), "lastMod" : 1 } }
exampledb.contacts
shard key: { "zip" : 1 }
unique: false
balancing: true
chunks:
shardA 3
shardB 2
{ "zip" : { "$minKey" : 1 } } -->> { "zip" : 10001 } on : shardA Timestamp(1, 0)
{ "zip" : 10001 } -->> { "zip" : 10090 } on : shardA Timestamp(1, 1)
{ "zip" : 10090 } -->> { "zip" : 90001 } on : shardB Timestamp(1, 2)
{ "zip" : 90001 } -->> { "zip" : 96054 } on : shardB Timestamp(1, 3)
{ "zip" : 96054 } -->> { "zip" : { "$maxKey" : 1 } } on : shardA Timestamp(1, 4)
tag: DC1 { "zip" : 10001 } -->> { "zip" : 10090 }
tag: DC2 { "zip" : 90001 } -->> { "zip" : 96054 }

对于该集合,分片操作跨 shardA 和 shardB 创建了5数据段(两个数据段对应于区域范围,另外三个数据段覆盖所有其他值)。

注意

此示例仅适用于复合哈希分片键,其中哈希字段是分片键的前缀(即,分片键中的第一个字段已进行哈希处理)。

例如, { "_id" : "hashed", "facility" : 1 }

MongoDB 支持对复合哈希索引上的集合进行分片。 在复合哈希分片键上进行分片时,仅当定义的区域范围满足其他要求时,MongoDB 才能对空或不存在的集合执行优化的初始数据段创建和分布。

考虑一个空集合examples.metrics ,它将存储两个制造工厂之一的分析数据。 计划的分片键是{ "_id" : "hashed", "facility" : 1} ,其中哈希字段是分片键前缀

1

计划的分片键是{ "_id" : "hashed", "facility" : 1 } 。 由于哈希字段是前缀(即分片键中的第一个字段),因此使用 创建 单个 sh.addShardToZone()区域:

sh.addShardToZone("shardA", "FacilityAlpha")
sh.addShardToZone("shardB", "FacilityAlpha")
2

具有哈希前缀的复合哈希分片键上的初始数据段分布需要单个区域范围,其中所有下限字段为MinKey ,所有上限字段为MaxKey

使用sh.updateZoneKeyRange()创建单个范围:

sh.updateZoneKeyRange(
"examples.metrics",
{ "_id" : MinKey, "facility" : MinKey },
{ "_id" : MaxKey, "facility" : MaxKey },
"FacilityAlpha"
);
3

注意

如果该集合不存在,则分片操作会创建该集合。

如果集合为空且不存在支持分片键的索引,则分片操作会创建索引。

使用带有sh.shardCollection() presplitHashedZones: true 的 对集合进行分片并执行初始数据段创建和分发:

sh.shardCollection(
"examples.metrics",
{ "_id" : "hashed", "facility" : 1 },
false,
{ presplitHashedZones: true }
)
4

要查看创建的数据段和分布,请运行sh.status()操作:

sh.status()

输出类似于以下内容(为便于阅读,省略了内容):

--- Sharding Status ---
databases:
{ "_id" : "config", "primary" : "config" }
{ "_id" : "examples", "primary" : "shardA", "version" : { "uuid" : UUID("245f8abf-a363-48b0-8208-2a5b577bbb4e"), "lastMod" : 1 } }
examples.metrics
shard key: { "_id" : "hashed", "facility" : 1 }
unique: false
balancing: true
chunks:
shardA 2
shardB 2
{ "_id" : { "$minKey" : 1 }, "facility" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-4611686018427387902"), "facility" : { "$minKey" : 1 } } on : shardA Timestamp(1, 0)
{ "_id" : NumberLong("-4611686018427387902"), "facility" : { "$minKey" : 1 } } -->> { "_id" : NumberLong(0), "facility" : { "$minKey" : 1 } } on : shardA Timestamp(1, 1)
{ "_id" : NumberLong(0), "facility" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("4611686018427387902"), "facility" : { "$minKey" : 1 } } on : shardB Timestamp(1, 2)
{ "_id" : NumberLong("4611686018427387902"), "facility" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 }, "facility" : { "$maxKey" : 1 } } on : shardB Timestamp(1, 3)
tag: FacilityAlpha { "_id" : { "$minKey" : 1 }, "facility" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 }, "facility" : { "$maxKey" : 1 } }

分片操作总共生成了4个数据段。 两个数据段分别对应绝对下限和上限。 在 和 上创建了一个与 相对应的区域。shardAshardBFacilityAlpha使用哈希字段将区域细分为2数据段。

注意

此示例仅适用于复合哈希分片键,其中哈希字段不是分片键的前缀(即,分片键中的第一个字段未进行哈希处理)。

例如, { "facility" : 1, "_id" : "hashed" }

MongoDB 支持对复合哈希索引上的集合进行分片。 在复合哈希分片键上进行分片时,仅当定义的区域范围满足其他要求时,MongoDB 才能对空或不存在的集合执行优化的初始数据段创建和分布。

考虑一个空集合examples.metrics ,它将存储两个制造工厂之一的分析数据。 计划的分片键为{ "facility" : 1, "_id" : "hashed" } ,其中哈希字段不是分片键前缀。

  • facility字段存储设施的名称: "FacilityAlpha""FacilityBaker" 。 该集合需要facility上的区域范围,以帮助将每个设施的数据隔离到特定分片。

  • _id字段弥补了facility字段关联基数较低的问题。 哈希弥补了_id字段的单调递增性质。

1

使用sh.addShardToZone()命令创建区域。

sh.addShardToZone("shardA", "FacilityAlpha")
sh.addShardToZone("shardB", "FacilityBaker")
2

计划的分片键是{"facility" : 1, "_id" : "hashed"}facility字段有两个可能的值: FacilityAlphaFacilityBaker

如果哈希字段不是前缀,则复合哈希分片键上的初始数据段分布需要为不同前缀字段值的每个组合(即 哈希字段之前的所有字段)。 由于facility有两个不同的前缀值,因此该集合需要两个涵盖这些值的区域范围。

  • 下限范围为所有非前缀字段指定MinKey

  • 上限范围至少有一个与其下限对应项不同的前缀字段。

使用sh.updateZoneKeyRange()"facility": "FacilityAlpha"创建范围:

sh.updateZoneKeyRange(
"examples.metrics",
{ "facility": "FacilityAlpha", "_id" : MinKey },
{ "facility": "FacilityBaker", "_id" : MinKey },
"FacilityAlpha"
);
  • 由于区域范围上限包括在内,因此此范围仅涵盖具有不同分片键前缀值"facilty" : "FacilityAlpha"和所有可能的_id值的文档。

使用sh.updateZoneKeyRange()"facility": "FacilityBaker"创建范围:

sh.updateZoneKeyRange(
"examples.metrics",
{ "facility": "FacilityBaker", "_id" : MinKey },
{ "facility": MaxKey, "_id" : MinKey },
"FacilityBaker"
);
  • 虽然该范围的上限在技术上可以捕获facility的其他值,但初始数据段分布逻辑依赖于facility不存在其他不同值的假设。 由于该集合仅包含facilityFacilityAlphaFacilityBaker的文档,因此此范围仅涵盖具有不同分片键前缀值"facility" : "FacilityBaker"以及所有可能的_id值的文档。

3

注意

如果该集合不存在,则分片操作会创建该集合。

如果集合为空且不存在支持分片键的索引,则分片操作会创建索引。

使用带有sh.shardCollection() presplitHashedZones: true 的 对集合进行分片并执行初始数据段创建和分发:

sh.shardCollection(
"examples.metrics",
{ "facility" : 1, "_id" : "hashed"},
false,
{ presplitHashedZones: true }
)
4

要查看创建的数据段和分布,请运行sh.status()操作:

sh.status()

输出类似于以下内容(为便于阅读,省略了内容):

--- Sharding Status ---
databases:
{ "_id" : "config", "primary" : "config" }
{ "_id" : "examples", "primary" : "shardA", "version" : { "uuid" : UUID("6c351bcf-acd2-4fd9-82d8-9f6bd7321558"), "lastMod" : 1 } }
examples.metrics
shard key: { "facility" : 1, "_id" : "hashed" }
unique: false
balancing: true
chunks:
shardA 3
shardB 3
{ "facility" : { "$minKey" : 1 }, "_id" : { "$minKey" : 1 } } -->> { "facility" : "FacilityAlpha", "_id" : { "$minKey" : 1 } } on : shard1 Timestamp(1, 0)
{ "facility" : "FacilityAlpha", "_id" : { "$minKey" : 1 } } -->> { "facility" : "FacilityAlpha", "_id" : NumberLong(0) } on : shard1 Timestamp(1, 1)
{ "facility" : "FacilityAlpha", "_id" : NumberLong(0) } -->> { "facility" : "FacilityBaker", "_id" : { "$minKey" : 1 } } on : shard1 Timestamp(1, 2)
{ "facility" : "FacilityBaker", "_id" : { "$minKey" : 1 } } -->> { "facility" : "FacilityBaker", "_id" : NumberLong(0) } on : shard2 Timestamp(1, 3)
{ "facility" : "FacilityBaker", "_id" : NumberLong(0) } -->> { "facility" : { "$maxKey" : 1 }, "_id" : { "$minKey" : 1 } } on : shard2 Timestamp(1, 4)
{ "facility" : { "$maxKey" : 1 }, "_id" : { "$minKey" : 1 } } -->> { "facility" : { "$maxKey" : 1 }, "_id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 5)
tag: FacilityAlpha { "facility" : "FacilityAlpha", "_id" : { "$minKey" : 1 } } -->> { "facility" : "FacilityBaker", "_id" : { "$minKey" : 1 } }
tag: FacilityBaker { "facility" : "FacilityBaker", "_id" : { "$minKey" : 1 } } -->> { "facility" : { "$maxKey" : 1 }, "_id" : { "$minKey" : 1 } }

分片操作总共生成了6个数据段。 两个数据段分别对应绝对下限和上限。 已创建两个区域,一位于shardA上,一位于shardB上,分别对应于FacilityAlphaFacilityBaker 。 使用哈希字段,每个区域被进一步细分为2数据段。

后退

sh.unshardCollection