Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/
数据库手册
/ / /

AnalyzeShardKey(数据库命令)

analyzeShardKey

7.0 版本中的新增功能

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

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

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

注意

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

analyzeShardKey 采用以下语法:

db.collection.analyzeShardKey(
<shardKey>,
{
keyCharacteristics: <bool>,
readWriteDistribution: <bool>,
sampleRate: <double>,
sampleSize: <int>
}
)
字段
类型
必要性
说明

shardKey

文档

必需

要分析的分片键。这可以是未分片集合或分片集合的候选分片键,也可以是分片集合的当前分片键。

没有默认值。

keyCharacteristics

布尔

Optional

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

默认值为 true

readWriteDistribution

布尔

Optional

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

默认值为 true

要使用 analyzeShardKey 返回集合的读取和写入分布指标,必须配置查询分析器以对在集合上运行的查询示例。否则,analyzeShardKey 将读取和写入分布指标返回为 0 值。要配置查询分析器,请参阅 configureQueryAnalyzer(数据库命令)。

sampleRate

double

Optional

计算有关分片分片键特征的指标时,集合中要进行示例的文档所占的比例。 如果设立sampleRate ,则无法设立sampleSize

必须大于 0,直至并包括 1

没有默认值。

sampleSize

整型

Optional

计算分片密钥特征相关指标时要采样的文档数量。如果设置 sampleSize,则无法设置 sampleRate

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

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

keyCharacteristic 由有关分片键的关联基数 ( cardinality )、频率(Frequency) 和单调性(monotonicity) 的指标组成。 仅当keyCharacteristics为 true 时才会返回这些指标。

这些指标是在运行analyzeShardKey时根据从集合中采样的文档计算得出的。 计算要求分分片键有一个支持索引。 如果没有支持索引,则不会返回任何指标。

您可以使用 sampleRatesampleSize 字段配置采样。两者都是可选的,但只能指定一个。当 sampleRatesampleSize 均未指定时, MongoDB将使用analyzeShardKeyCharacteristicsDefaultSampleSize 参数的值,该值的默认值为 10 百万。

要根据collection中的所有文档计算指标,请将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 不会阻止对collection的读取或写入。

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

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

下表显示了analyzeShardKeyshardCollection的相同分片键支持的索引:

命令
片键
支持索引

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", ...}

shardCollection

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

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

这允许您分析可能尚无分片所需的支持索引的分片键。

analyzeShardKeyshardCollection都有以下索引要求:

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

为了最大限度地降低性能,请使用secondarysecondaryPreferred读取偏好(read preference)运行analyzeShardKey 。在分片集群(cluster)上,如果未指定, mongos会自动将读取偏好(read preference)设置为secondaryPreferred

  • 您无法在Atlas Flex 集群上运行analyzeShardKey

  • 您无法在独立运行的实例上运行analyzeShardKey

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

  • 您无法针对time-series collection运行analyzeShardKey

  • 您无法对具有Queryable Encryption的collection运行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

整型

collection中的文档数量。

numOrphanDocs

整型

孤立文档的数量。

出于性能原因,不会将孤立文档排除在指标计算之外。 如果numOrphanDocs相对于numDocsTotal较大,则考虑等到孤立文档的数量与集合中的文档总数相比非常小时再运行命令。

avgDocSizeBytes

整型

collection中的文档的平均大小(以字节为单位)。

如果numDocsTotalnumDocsSampled相当,则可以通过将每个mostCommonValuesfrequency乘以avgDocSizeBytes来估计最大数据块的大小。

numDocsSampled

整型

采样文档的数量。

numDistinctValues

整型

不同分片键值的数量。

请选择具有较大numDistinctValues的分片键,因为不同的分片键值的数量是负载均衡器可以创建的最大数据块数。

isUnique

布尔

指示分片键是否唯一。 仅当分片键存在唯一索引时,才会将其设置为true

如果分片键是唯一的,则不同值的数量等于文档的数量。

mostCommonValues

文档数组

最常用分片键值的值和frequency (文档数量)的数组。

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

可以通过设置analyzeShardKeyNumMostCommonValues来配置最常见的分片键值的数量,默认为5 。 为了避免超过响应的 16 MB BSON 大小限制,如果每个值的大小超过 15 MB / analyzeShardKey NumMostCommonValues,则每个值都将设置为“截断”。

mostCommonValues[n].value

文档

分片键。

mostCommonValues[n].frequency

整型

给定分片键的文档数量。

选择一个分片键,其中每个最常用值的频率相对于numDocsSampled较低。

monotonicity. recordIdCorrelationCoefficient

double

仅在单调性已知时设置。

当以下任一条件为 true 时,此项设置为"unknown"

  • 分片键没有符合shardCollection定义的支持索引。

  • collection是集群化的。

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

如果collection已Go数据块迁移,则单调性检查可能会返回不正确的结果。数据块迁移会从发送分片中删除文档,然后将其重新插入接收分片中。不保证来自客户端的插入顺序会得到保留。

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

monotoncity.type

字符串

可以是以下之一:

"monotonic", "not monotonic" , "unknown"

避免使用类型为"monotonic"的分片键,除非您不希望经常插入新文档。

如果按单调递增或递减的分片键对collection进行分片,则文档将插入到拥有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

double

无论数据如何分布,针对单个分片的读取百分比。

percentageOfMultiShardReads

double

针对多个分片的读取百分比。

如果数据的分布使得读取的目标值属于单个分片,则此类别包括可能仅针对单个分片的读取。

如果查询对大量数据进行操作,则针对多个分片而不是一个分片可能会由于并行查询执行而减少延迟。

percentageOfScatterGatherReads

double

分散-聚集读取的百分比,无论数据如何分布。

避免使用该指标具有较高值的分片键。 虽然分散-聚集查询对没有目标数据的分片影响很小,但它们仍然会对性能产生一些影响。

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

numReadsByRange

整数数组

数字数组,表示从MinKeyMaxKey排序的每个范围成为目标的次数。

避免使用numReadsByRange分布严重偏斜的分片键,因为这意味着可能有一个或多个热分片可供读取。

选择numReadsByRange之和类似于sampleSize.total的分片键。

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

字段
类型
说明
使用

sampleSize.total

整型

已采样写入查询的总数。

sampleSize.update

整型

已采样的update查询总数。

sampleSize.delete

整型

已采样的delete查询总数。

sampleSize.findAndModify

整型

已采样的findAndModify查询总数。

percentageOfSingleShardWrites

double

无论数据如何分布,针对单个分片的写入百分比。

percentageOfMultiShardWrites

double

针对多个分片的写入百分比。

如果数据的分布使得写入的目标值属于单个分片,则此类别包括可能仅针对单个分片的写入。

percentageOfScatterGatherWrites

double

无论数据如何分布,分散-聚集写入的百分比。

避免使用该指标具有较高值的分片键,因为针对单个分片的写入通常性能更高。

numWritesByRange

整数数组

数字数组,表示从MinKeyMaxKey排序的每个范围成为目标的次数。

避免使用numWritesByRange分布严重偏斜的分片键,因为这意味着可能有一个或多个热分片可供写入。

选择numWritesByRange之和类似于sampleSize.total的分片键。

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

percentageOfShardKeyUpdates

double

更新文档分片分片键值的写入查询的百分比。

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

目前仅支持以可重试写入或事务形式进行更新,并且批处理大小限制为1

percentageOfSingleWritesWithoutShardKey

double

multi=false且无法定位到单个分片的写入查询的百分比。

避免使用该指标具有较高值的分片键。

执行此类写入的成本很高,因为可能涉及运行内部事务。

percentageOfMultiWritesWithoutShardKey

double

multi=true且无法定位到单个分片的写入查询的百分比。

避免使用该指标具有较高值的分片键。

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

postcollection中的文档具有以下模式:

{
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 个名字,其中一些更常见。

  • 其中有 3 名名人用户。

  • 每个用户恰好关注了另外五个用户,并且很有可能关注至少一个名人用户。

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

  • 每个用户每六个小时登录一次,以阅读自己的个人资料以及过去 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 命令为某些候选分片键返回的示例指标,以及从 7 天的工作负载中收集的采样查询。

注意

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

此示例使用 analyzeShardKey 命令提供 social.post集合上 { _id: 1 }分片键的指标。

以下代码区块使用db.collection.configureQueryAnalyzer() 打开查询采样:

use social
db.post.configureQueryAnalyzer(
{
mode: "full",
samplesPerSecond: 5
}
)

db.collection.configureQueryAnalyzer() 收集查询样本后,以下代码区块使用 analyzeShardKey 命令对 10,000 文档示例并计算结果:

use social
db.post.analyzeShardKey(
{ _id: 1 },
{
keyCharacteristics: true,
readWriteDistribution: false,
sampleSize: 10000
}
)

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

use social
db.post.analyzeShardKey(
{ 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 }分片键的指标:

use social
db.post.analyzeShardKey(
{ 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 }分片键的指标:

use social
db.post.analyzeShardKey(
{ 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

在此页面上