文档菜单
文档首页
/
MongoDB 手册
/ / /

analyzeShardKey

在本页

  • 定义
  • 兼容性
  • 语法
  • 命令字段
  • 行为
  • 访问控制
  • 输出
  • 示例
  • 了解更多
analyzeShardKey

版本中7.0.

计算用于评估未分片或分片集合的碎片键的指标。指标基于样本查询。您可以使用configureQueryAnalyzer在集合上配置查询采样。

此命令在以下环境中托管的部署中可用

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

注意

此命令支持所有MongoDB Atlas集群。有关所有命令的Atlas支持信息,请参阅不受支持的命令。

analyzeShardKey 具有以下语法

db.adminCommand(
{
analyzeShardKey: <string>,
key: <shardKey>,
keyCharacteristics: <bool>,
readWriteDistribution: <bool>,
sampleRate: <double>,
sampleSize: <int>
}
)
字段
类型
必要性
描述
analyzeShardKey
string
Required

要分析的数据集命名空间。

没有默认值。

key
document
Required

分析的分片键。这可以是一个未分片集合或分片集合的候选分片键,或者分片集合的当前分片键。

没有默认值。

keyCharacteristics
布尔型
可选

是否计算分片键特性的指标。详细信息,请参阅keyCharacteristics。

默认值为 true

readWriteDistribution
布尔型
可选

是否计算读写分布的指标。详细信息,请参阅readWriteDistribution。

默认值为 true

要使用 analyzeShardKey 返回集合的读写分布指标,您必须配置查询分析器以采样在集合上运行的查询。否则,analyzeShardKey 返回的读写分布指标为 0 值。有关配置查询分析器的信息,请参阅configureQueryAnalyzer。

sampleRate
双精度浮点型
可选

在计算分片键特性指标时,从集合中采样的文档比例。如果您设置了 sampleRate,则不能设置 sampleSize

必须大于 0,且不超过 1

没有默认值。

sampleSize
整型
可选

在计算分片键特性指标时,要采样的文档数量。如果您设置了 sampleSize,则不能设置 sampleRate

如果没有指定,并且没有指定 sampleRate,则样本大小默认为 analyzeShardKeyCharacteristicsDefaultSampleSize 设置的样本大小。

analyzeShardKey 根据您在运行方法时指定的 keyCharacteristicreadWriteDistribution 值返回不同的指标。

keyCharacteristic 包含关于分片键的 基数频率单调性 的指标。只有在 keyCharacteristics 为 true 时,这些指标才会返回。

当基于从集合中采样的文档运行 analyzeShardKey 时,会计算这些指标。计算需要分片键有一个 支持索引。如果没有支持索引,则不会返回任何指标。

您可以使用 sampleRatesampleSize 字段配置采样。两者都是可选的,只能指定一个。如果两者都没有指定,则样本大小设置为 10。通过设置 analyzeShardKeyCharacteristicsDefaultSampleSize 来配置此值。

要基于集合中的所有文档计算指标,请将 sampleRate 设置为 1

readWriteDistribution 包含关于查询路由模式和分片键范围 热点 的指标。这些指标基于采样查询。

要配置集合的查询采样,请使用 configureQueryAnalyzer 命令。只有当 readWriteDistributiontrue 时,才会返回读取和写入分布指标。当执行 analyzeShardKey 时,会计算这些指标,并且这些指标使用采样后的读取和写入查询。如果没有采样查询,则不会返回读取和写入分布指标。

  • 如果没有采样读取查询,命令将返回 writeDistribution,但省略 readDistribution

  • 如果没有采样写入查询,命令将返回 readDistribution,但省略 writeDistribution

要使用 analyzeShardKey 返回集合的读写分布指标,您必须配置查询分析器以采样在集合上运行的查询。否则,analyzeShardKey 返回的读写分布指标为 0 值。有关配置查询分析器的信息,请参阅configureQueryAnalyzer。

keyCharacteristics
readWriteDistribution
返回的结果
true
false
false
true
analyzeShardKey 返回 readWriteDistribution 指标,并省略 keyCharacteristics 指标。
true
true
  • analyzeShardKey 返回 readWriteDistribution 指标和 keyCharacteristics 指标。

  • 如果分片键没有支持索引,analyzeShardKey 将返回 readWriteDistribution 指标,并省略 keyCharacteristics 指标。

analyzeShardKey 不会阻塞对集合的读取或写入。

关于读取和写入分布的指标质量取决于查询采样发生时工作负载的代表性。对于某些应用程序,返回代表性指标可能需要将查询采样保持开启几天。

analyzeShardKey所需的支持索引与shardCollection命令所需的支持索引不同。

此表显示了analyzeShardKey和shardCollection对同一分片键的支持索引。

命令
分片键
支持索引

analyzeShardKey

{ a.x: 1, b: "hashed" }
  • { a.x: 1, b: 1, ... }

  • { a.x: "hashed", b: 1, ... }

  • { a.x: 1, b: "hashed", ... }

  • { a.x: "hashed", b: "hashed", ...}

分片集合
{ a.x: 1, b: "hashed" }
{ a.x: 1, b: "hashed", ... }

这允许您分析一个可能尚未有分片所需支持索引的分片键。

analyzeShardKey和shardCollection都具有以下索引要求

要创建支持索引,请使用db.collection.createIndex()方法。

为了最小化性能,使用analyzeShardKeysecondarysecondaryPreferred读取偏好。在分片集群中,如果没有指定,mongos会自动将读取偏好设置为secondaryPreferred

  • 您不能在Atlas 共享集群无服务器实例上运行analyzeShardKey

  • 您不能在独立部署上运行analyzeShardKey

  • 您不能直接针对--shardsvr副本集运行analyzeShardKey。在分片集群上运行时,analyzeShardKey必须针对mongos运行。

  • 您不能针对时间序列集合运行analyzeShardKey

  • 您不能针对具有可查询加密的集合运行analyzeShardKey

analyzeShardKey 需要以下角色之一

analyzeShardKey 返回有关 keyCharacteristicsreadWriteDistribution 的信息。

  • keyCharacteristics 提供有关分片键的基数、频率和单调性的度量。

  • readWriteDistribution 提供有关查询路由模式和分片键范围的繁忙程度的度量。

这是当 keyCharacteristics 设置为 true 时返回的 keyCharacteristics 文档的结构。

{
keyCharacteristics: {
numDocsTotal: <integer>,
numOrphanDocs: <integer>,
avgDocSizeBytes: <integer>,
numDocsSampled: <integer>,
isUnique: <bool>,
numDistinctValues: <integer>,
mostCommonValues: [
{ value: <shardkeyValue>, frequency: <integer> },
...
],
monotonicity: {
recordIdCorrelationCoefficient: <double>,
type: "monotonic"|"not monotonic"|"unknown",
}
}
}
字段
类型
描述
用法
numDocsTotal
整型
集合中的文档数量。
numOrphanDocs
整型
孤儿文档的数量。
出于性能原因,孤儿文档不会被排除在指标计算之外。如果 numOrphanDocs 相对于 numDocsTotal 较大,考虑等到孤儿文档的数量与集合中总文档数相比非常小之后再运行命令。
avgDocSizeBytes
整型
集合中文档的平均大小,单位为字节。
如果 numDocsTotalnumDocsSampled 相当,可以通过将每个 mostCommonValuesfrequency(文档数)乘以 avgDocSizeBytes 来估算最大块的大小。
numDocsSampled
整型
样本文档的数量。
numDistinctValues
整型
唯一分片键值的数量。
由于唯一分片键值的数量是均衡器可以创建的最大块数,因此选择具有大 numDistinctValues 的分片键。
isUnique
布尔型
表示分片键是否唯一。如果分片键有唯一索引,则仅设置为 true
如果分片键是唯一的,则唯一值的数量等于文档的数量。
mostCommonValues
文档数组
一个包含最常见分片键值及其 frequency(文档数)的数组。

分片键值的频率是该值包含的块中的最小文档数。如果频率较高,则块可能会成为存储、读取和写入的瓶颈。选择一个频率相对于 numDocsSampled 较低的分片键。

可以通过设置 analyzeShardKeyNumMostCommonValues(默认为 5)来配置最常见分片键值的数量。为了避免超过 16MB BSON 大小限制,如果其大小超过 15MB / analyzeShardKey NumMostCommonValues.

mostCommonValues[n].value
document
分片键。
mostCommonValues[n].frequency
整型
给定分片键的文档数。
选择一个频率相对于 numDocsSampled 较低的分片键。
monotonicity. recordIdCorrelationCoefficient
双精度浮点型
仅在知道单调性时设置。

当以下情况之一为真时,设置为 "unknown"

  • 分片键没有每个 shardCollection 定义的辅助索引。

  • 集合是 集群化的。

  • 分片键是一个散列复合分片键,其中散列字段不是第一个字段。

如果集合已通过块迁移,则单调性检查可能返回不正确的结果。块迁移会从捐赠分片删除文档并将它们重新插入到接收器分片。无法保证客户端的插入顺序得到保留。

您可以使用 analyzeShardKeyMonotonicity CorrelationCoefficientThreshold. 配置相关系数的阈值。

monotoncity.type
string

可以是以下之一

"单调递增""非单调递增""未知"

除非你不需要经常插入新文档,否则请避免使用类型为"单调递增"的分片键。

如果一个集合是根据单调递增或递减的分片键进行分片的,则新文档将被插入到拥有MaxKeyMinKey分片的分片上。这个分片可能会成为插入的瓶颈,而且数据很可能大部分时间都不平衡,因为均衡器需要与进入的插入操作竞争。

readWriteDistribution设置为true时,返回的文档结构如下

{
readDistribution: {
sampleSize: {
total: <integer>,
find: <integer>,
aggregate: <integer>,
count: <integer>,
distinct: <integer>
},
percentageOfSingleShardReads: <double>,
percentageOfMultiShardReads: <double>,
percentageOfScatterGatherReads: <double>,
numReadsByRange: [
<integer>,
...
]
},
writeDistribution: {
sampleSize: {
total: <integer>,
update: <integer>,
delete: <integer>,
findAndModify: <integer>
},
percentageOfSingleShardWrites: <double>,
percentageOfMultiShardWrites: <double>,
percentageOfScatterGatherWrites: <double>,
numWritesByRange: [
<integer>,
...
],
percentageOfShardKeyUpdates: <double>,
percentageOfSingleWritesWithoutShardKey: <double>,
percentageOfMultiWritesWithoutShardKey: <double>
}
}

要使用 analyzeShardKey 返回集合的读写分布指标,您必须配置查询分析器以采样在集合上运行的查询。否则,analyzeShardKey 返回的读写分布指标为 0 值。有关配置查询分析器的信息,请参阅configureQueryAnalyzer。

字段
类型
描述
用法
sampleSize.total
整型
样本读查询的总数。
sampleSize.find
整型
样本find查询的总数。
sampleSize.aggregate
整型
样本aggregate查询的总数。
sampleSize.count
整型
样本count查询的总数。
sampleSize.distinct
整型
样本distinct查询的总数。
percentageOfSingleShardReads
双精度浮点型
指向单个分片的读操作的比例,无论数据如何分布。
percentageOfMultiShardReads
双精度浮点型
指向多个分片的读操作的比例。

这一类别包括可能只针对单个分片的读操作,如果数据分布使得读操作的目标值落在单个分片下。

如果查询操作大量数据,那么与只针对一个分片相比,可能由于并行查询执行而降低延迟。

scatterGather读取百分比
双精度浮点型
表示scatter-gather读取的百分比,无论数据如何分布。

避免使用高值的分片键。虽然scatter-gather查询对没有目标数据分片的影响很小,但它们仍然会有一些性能影响。

在具有大量分片的集群上,scatter-gather查询的性能明显低于针对单个分片进行的查询。

按范围读取的数量
整数数组
表示从MinKeyMaxKey的每个范围被目标查询次数的数字数组。

避免使用numReadsByRange分布非常偏斜的分片键,因为这表明可能存在一个或多个读取的热分片。

选择一个分片键,其中numReadsByRange的总和与sampleSize.total相似。

可以使用analyzeShardKeyNumRanges参数配置范围的数量,默认值为100。值为100是因为目标是找到一个可以扩展到100个分片的分片键。

字段
类型
描述
用法
sampleSize.total
整型
样本写入查询总数。
sampleSize.update
整型
样本update查询总数。
sampleSize.delete
整型
样本delete查询总数。
sampleSize.findAndModify
整型
样本findAndModify查询总数。
单分片写入百分比
双精度浮点型
无论数据如何分布,表示针对单个分片进行写入的百分比。
多分片写入百分比
双精度浮点型
表示针对多个分片进行写入的百分比。
该类别包括可能只针对单个分片进行写入的写入,如果数据分布使得写入的目标值落在单个分片内。
scatterGather写入百分比
双精度浮点型
表示scatter-gather写入的百分比,无论数据如何分布。
避免使用此指标具有高值的分片键,因为通常针对单个分片进行写入的性能更高。
按范围写入的数量
整数数组
表示从MinKeyMaxKey的每个范围被目标查询次数的数字数组。

避免使用numWritesByRange分布非常偏斜的分片键,因为这表明可能存在一个或多个写入的热分片。

选择一个分片键,其中numWritesByRange的总和与sampleSize.total相似。

可以使用analyzeShardKeyNumRanges参数配置范围的数量,默认值为100。值为100是因为目标是找到一个可以扩展到100个分片的分片键。

shardKey更新百分比
双精度浮点型
表示更新文档分片键值的写入查询的百分比。

避免使用具有高 percentageOfShardKeyUpdates 的分片键。对文档分片键值的更新可能会导致文档移动到不同的分片,这需要在查询目标分片上执行内部事务。有关更改文档分片键值的详细信息,请参阅更改分片键。

目前仅支持作为可重试写操作或事务中的更新,且具有 1 的批量大小限制。

percentageOfSingleWritesWithoutShardKey
双精度浮点型
写查询中未指定分片键且无法针对单个分片的目标的查询的百分比。

避免此指标具有高值的分片键。

执行此类写操作成本较高,因为它们可能涉及运行内部事务。

percentageOfMultiWritesWithoutShardKey
双精度浮点型
写查询中指定了 multi=true 且无法针对单个分片的目标的查询的百分比。
避免此指标具有高值的分片键。

考虑一个简化版的社会媒体应用。我们试图分片的集合是 post 集合。

post 集合中的文档具有以下架构

{
userId: <uuid>,
firstName: <string>,
lastName: <string>,
body: <string>, // the field that can be modified.
date: <date>, // the field that can be modified.
}
  • 该应用有 1500 名用户。

  • 有 30 个姓氏和 45 个名字,有些比其他名字更常见。

  • 有三个名人用户。

  • 每个用户恰好关注五个其他用户,并且有很大概率至少关注一个名人用户。

  • 每个用户每天随机时间发布大约两篇帖子。他们会在帖子发布后立即编辑一次。

  • 每个用户每六个小时登录一次,阅读自己的个人资料以及过去24小时内关注的用户发布的帖子。他们也会随机回复过去三小时内的一篇帖子。

  • 对于每个用户,应用程序在午夜时分删除超过三天前的帖子。

此工作负载具有以下查询模式

  • find 命令,带有过滤器 { userId: , firstName: , lastName: }

  • find 命令,带有过滤器 { $or: [{ userId: , firstName: , lastName:, date: { $gte: }, ] }

  • findAndModify 命令,带有过滤器 { userId: , firstName: , lastName: , date: } 以更新正文和日期字段。

  • update 命令,带有 multi: false 和过滤器 { userId: , firstName: , lastName: , date: { $gte: , $lt: } } 以更新正文和日期字段。

  • delete 命令,带有 multi: true 和过滤器 { userId: , firstName: , lastName: , date: { $lt: } }

以下是从七天的工负载中收集的示例候选分片键的 analyzeShardKey 返回的指标。

注意

在运行 analyzeShardKey 命令之前,请先阅读本页前面的 支持索引 部分。如果您需要为正在分析的分片键使用支持索引,请使用 db.collection.createIndex() 方法来创建索引。

analyzeShardKey 命令提供了对 social.post 集合中 { lastName: 1 } 分片键的指标

db.adminCommand(
{
analyzeShardKey: "social.post",
key: { lastName: 1 },
keyCharacteristics: true,
readWriteDistribution: false
}
)

此命令的输出类似于以下内容

{
"keyCharacteristics": {
"numDocsTotal" : 9039,
"avgDocSizeBytes" : 153,
"numDocsSampled" : 9039,
"isUnique" : false,
"numDistinctValues" : 30,
"mostCommonValues" : [
{
"value" : {
"lastName" : "Smith"
},
"frequency" : 1013
},
{
"value" : {
"lastName" : "Johnson"
},
"frequency" : 984
},
{
"value" : {
"lastName" : "Jones"
},
"frequency" : 962
},
{
"value" : {
"lastName" : "Brown"
},
"frequency" : 925
},
{
"value" : {
"lastName" : "Davies"
},
"frequency" : 852
}
],
"monotonicity" : {
"recordIdCorrelationCoefficient" : 0.0771959161,
"type" : "not monotonic"
},
}
}

analyzeShardKey 命令提供了对 social.post 集合中 { userId: 1 } 分片键的指标

db.adminCommand(
{
analyzeShardKey: "social.post",
key: { userId: 1 },
keyCharacteristics: true,
readWriteDistribution: false
}
)

此命令的输出类似于以下内容

{
"keyCharacteristics": {
"numDocsTotal" : 9039,
"avgDocSizeBytes" : 162,
"numDocsSampled" : 9039,
"isUnique" : false,
"numDistinctValues" : 1495,
"mostCommonValues" : [
{
"value" : {
"userId" : UUID("aadc3943-9402-4072-aae6-ad551359c596")
},
"frequency" : 15
},
{
"value" : {
"userId" : UUID("681abd2b-7a27-490c-b712-e544346f8d07")
},
"frequency" : 14
},
{
"value" : {
"userId" : UUID("714cb722-aa27-420a-8d63-0d5db962390d")
},
"frequency" : 14
},
{
"value" : {
"userId" : UUID("019a4118-b0d3-41d5-9c0a-764338b7e9d1")
},
"frequency" : 14
},
{
"value" : {
"userId" : UUID("b9c9fbea-3c12-41aa-bc69-eb316047a790")
},
"frequency" : 14
}
],
"monotonicity" : {
"recordIdCorrelationCoefficient" : -0.0032039729,
"type" : "not monotonic"
},
}
}

analyzeShardKey 命令提供了对 social.post 集合中 { userId: 1 } 分片键的指标

db.adminCommand(
{
analyzeShardKey: "social.post",
key: { userId: 1 },
keyCharacteristics: false,
readWriteDistribution: true
}
)

此命令的输出类似于以下内容

{
"readDistribution" : {
"sampleSize" : {
"total" : 61363,
"find" : 61363,
"aggregate" : 0,
"count" : 0,
"distinct" : 0
},
"percentageOfSingleShardReads" : 50.0008148233,
"percentageOfMultiShardReads" : 49.9991851768,
"percentageOfScatterGatherReads" : 0,
"numReadsByRange" : [
688,
775,
737,
776,
652,
671,
1332,
1407,
535,
428,
985,
573,
1496,
...
],
},
"writeDistribution" : {
"sampleSize" : {
"total" : 49638,
"update" : 30680,
"delete" : 7500,
"findAndModify" : 11458
},
"percentageOfSingleShardWrites" : 100,
"percentageOfMultiShardWrites" : 0,
"percentageOfScatterGatherWrites" : 0,
"numWritesByRange" : [
389,
601,
430,
454,
462,
421,
668,
833,
493,
300,
683,
460,
...
],
"percentageOfShardKeyUpdates" : 0,
"percentageOfSingleWritesWithoutShardKey" : 0,
"percentageOfMultiWritesWithoutShardKey" : 0
}
}

返回

addShardToZone