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
字符串与以minimum
和maximum
为界的分片键值范围关联的区域名称。仅在连接到 实例时发出
sh.updateZoneKeyRange()
mongos
。
兼容性
此方法可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
重要
无服务器实例不支持此命令。 有关更多信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
行为
您创建的分片键值范围的下边界和上边界不能与分片集合的现有范围重叠。 例如,给定1
到10
的现有范围,您无法创建5
到20
的新范围,因为新范围将与现有范围重叠。
一个区域可以有多个与之关联的数据范围,但一个范围最多只能与一个区域关联。
有关分片集群中区域的更多信息,请参阅区域手册页面。
空集合或不存在集合的初始数据段分布
如果您考虑对空集合或不存在的集合执行 区域分片 ,请在对集合分片 之前sh.updateZoneKeyRange()
使用 创建区域和区域范围( 自 起4.0.2 )。从版本4开始。 0 。 3 、 在空集合或不存在的集合上创建区域和区域范围允许 MongoDB 在对集合进行分片时优化初始数据段创建和分配过程。 与在分片后创建区域相比,这种优化的流程支持更快地设置分区分片,并且负载均衡器开销更少。 负载均衡器在优化初始数据段创建和分配后执行所有数据段管理。
有关为初始数据段分布定义区域和区域范围的示例,请参阅为空集合或非现有集合预定义区域和区域范围。
使用复合哈希分片键进行初始数据段分配
MongoDB 支持对复合哈希索引上的集合进行分片。 在复合哈希分片键上对空集合或不存在的集合进行分片时,MongoDB 可以执行优化的初始数据段创建和分配。
如果哈希字段是分片键的前缀(即分片键中的第一个字段),则必须满足以下所有条件,MongoDB 才能执行初始数据段创建和分发:
该集合具有单个区域范围,所有下限字段为
MinKey
,所有上限字段为MaxKey
。
如果哈希字段不是分片分片键的前缀(即分片分片键具有一个或多个非哈希前导字段),则必须满足以下所有条件, MongoDB才能执行初始数据块创建和分配:
该集合为不同前缀字段值的每个组合(即 哈希字段之前的所有字段)。
对于每个区域范围的下限,请为哈希字段和所有后续字段指定
MinKey
。对于每个区域范围,至少有一个上限前缀字段必须与其对应的下限前缀字段不同。
有关在复合哈希分片键上为初始数据段分布定义区域和区域范围的更完整示例,请参阅为空或不存在的集合预定义区域和区域范围。
平衡器
将范围与区域关联后,负载均衡器必须首先运行,以便将范围被区域覆盖的任何数据段迁移到该区域内的分片。 在均衡完成之前,考虑到为分片集群配置的区域,某些数据段可能驻留在错误的分片上。 有关更多信息,请参阅负载均衡器。
有关迁移如何在分片集群中工作的更多信息,请参阅分片集群负载均衡器手册页面。
边界
区域范围始终包括下边界,但不包括上边界。
删除的集合
删除集合将删除其关联的区域/标记范围。
在早期版本中,MongoDB 不会删除已删除集合的标签关联,如果您稍后创建同名的新集合,则旧标签关联将应用于新集合。
安全性
对于使用身份验证运行的分片集群,您必须通过以下任一项身份验证:
其权限包括对
config
数据库中的各种集合执行指定操作的用户:或者,
权限包括对
enableSharding
集群 资源的 的用户。
clusterAdmin
或clusterManager
内置角色具有发出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 )
min
和max
必须与目标范围的边界完全匹配。 以下操作尝试删除之前创建的范围,但将{ 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}
创建区域
使用sh.addShardToZone()
创建区域:
sh.addShardToZone("shardA", "DC1") sh.addShardToZone("shardB", "DC2")
创建区域范围
使用sh.updateZoneKeyRange()
为exampledb
数据库中的空contacts
集合创建范围:
sh.updateZoneKeyRange( "exampledb.contacts", { zip: 10001 }, { zip: 10090 }, "DC1" ); sh.updateZoneKeyRange( "exampledb.contacts", { zip: 90001 }, { zip: 96054 }, "DC2" );
将集合分片
注意
如果该集合不存在,则分片操作会创建该集合。
如果集合为空且不存在支持分片键的索引,则分片操作会创建索引。
使用sh.shardCollection()
对集合contacts
进行分片:
sh.shardCollection("exampledb.contacts", { zip: 1 } );
查看创建的数据段和分布
要查看创建的数据段和分布,请运行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}
,其中哈希字段是分片键前缀。
创建区域
计划的分片键是{ "_id" : "hashed", "facility" : 1 }
。 由于哈希字段是前缀(即分片键中的第一个字段),因此使用 创建 单个 sh.addShardToZone()
区域:
sh.addShardToZone("shardA", "FacilityAlpha") sh.addShardToZone("shardB", "FacilityAlpha")
创建区域范围
具有哈希前缀的复合哈希分片键上的初始数据段分布需要单个区域范围,其中所有下限字段为MinKey
,所有上限字段为MaxKey
。
使用sh.updateZoneKeyRange()
创建单个范围:
sh.updateZoneKeyRange( "examples.metrics", { "_id" : MinKey, "facility" : MinKey }, { "_id" : MaxKey, "facility" : MaxKey }, "FacilityAlpha" );
将集合分片
注意
如果该集合不存在,则分片操作会创建该集合。
如果集合为空且不存在支持分片键的索引,则分片操作会创建索引。
使用带有sh.shardCollection()
presplitHashedZones: true 的 对集合进行分片并执行初始数据段创建和分发:
sh.shardCollection( "examples.metrics", { "_id" : "hashed", "facility" : 1 }, false, { presplitHashedZones: true } )
查看创建的数据段和分布
要查看创建的数据段和分布,请运行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个数据段。 两个数据段分别对应绝对下限和上限。 在 和 上创建了一个与 相对应的区域。shardA
shardB
FacilityAlpha
使用哈希字段将区域细分为2数据段。
具有非前缀哈希字段的复合哈希分片键
注意
此示例仅适用于复合哈希分片键,其中哈希字段不是分片键的前缀(即,分片键中的第一个字段未进行哈希处理)。
例如, { "facility" : 1, "_id" : "hashed" }
MongoDB 支持对复合哈希索引上的集合进行分片。 在复合哈希分片键上进行分片时,仅当定义的区域范围满足其他要求时,MongoDB 才能对空或不存在的集合执行优化的初始数据段创建和分布。
考虑一个空集合examples.metrics
,它将存储两个制造工厂之一的分析数据。 计划的分片键为{ "facility" : 1, "_id" : "hashed" }
,其中哈希字段不是分片键前缀。
facility
字段存储设施的名称:"FacilityAlpha"
或"FacilityBaker"
。 该集合需要facility
上的区域范围,以帮助将每个设施的数据隔离到特定分片。_id
字段弥补了facility
字段关联基数较低的问题。 哈希弥补了_id
字段的单调递增性质。
创建区域
使用sh.addShardToZone()
命令创建区域。
sh.addShardToZone("shardA", "FacilityAlpha") sh.addShardToZone("shardB", "FacilityBaker")
创建区域范围
计划的分片键是{"facility" : 1, "_id" : "hashed"}
。 facility
字段有两个可能的值: FacilityAlpha
和FacilityBaker
。
如果哈希字段不是前缀,则复合哈希分片键上的初始数据段分布需要为不同前缀字段值的每个组合(即 哈希字段之前的所有字段)。 由于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
不存在其他不同值的假设。 由于该集合仅包含facility
为FacilityAlpha
或FacilityBaker
的文档,因此此范围仅涵盖具有不同分片键前缀值"facility" : "FacilityBaker"
以及所有可能的_id
值的文档。
将集合分片
注意
如果该集合不存在,则分片操作会创建该集合。
如果集合为空且不存在支持分片键的索引,则分片操作会创建索引。
使用带有sh.shardCollection()
presplitHashedZones: true 的 对集合进行分片并执行初始数据段创建和分发:
sh.shardCollection( "examples.metrics", { "facility" : 1, "_id" : "hashed"}, false, { presplitHashedZones: true } )
查看创建的数据段和分布
要查看创建的数据段和分布,请运行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
上,分别对应于FacilityAlpha
和FacilityBaker
。 使用哈希字段,每个区域被进一步细分为2数据段。