AnalyzeShardKey
定义
analyzeShardKey
7.0 版本中的新增功能。
计算用于评估未分片或分分片的集合的分片分片键的指标。 指标基于采样的查询。 您可以使用
configureQueryAnalyzer
在集合上配置查询采样。
兼容性
此命令可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
analyzeShardKey
采用以下语法:
db.adminCommand( { analyzeShardKey: <string>, key: <shardKey>, keyCharacteristics: <bool>, readWriteDistribution: <bool>, sampleRate: <double>, sampleSize: <int> } )
命令字段
字段 | 类型 | 必要性 | 说明 |
---|---|---|---|
analyzeShardKey | 字符串 | 必需 | 要分析的collection的命名空间。 没有默认值。 |
key | 文档 | 必需 | 要分析的分片键。这可以是未分片集合或分片集合的候选分片键,也可以是分片集合的当前分片键。 没有默认值。 |
keyCharacteristics | 布尔 | Optional | 是否计算有关分片键特征的指标。 有关详细信息,请参阅keyCharacteristics。 默认值为 |
readWriteDistribution | 布尔 | Optional | 是否计算读写分布的指标。 有关详细信息,请参阅readWriteDistribution。 默认值为 要使用 |
sampleRate | double | Optional | 计算有关分片分片键特征的指标时,集合中要进行示例的文档所占的比例。 如果设立 必须大于 没有默认值。 |
sampleSize | 整型 | Optional | 计算分片密钥特征相关指标时要采样的文档数量。如果设置 如果未指定,且未指定 |
行为
analyzeShardKey
根据您在运行该方法时指定的keyCharacteristic
和readWriteDistribution
值,返回不同的指标。
关于分片键特征的指标
keyCharacteristic
由有关分片键的关联基数 ( cardinality )、频率(Frequency) 和单调性(monotonicity) 的指标组成。 仅当keyCharacteristics
为 true 时才会返回这些指标。
这些指标是在运行analyzeShardKey
时根据从集合中采样的文档计算得出的。 计算要求分分片键有一个支持索引。 如果没有支持索引,则不会返回任何指标。
您可以使用sampleRate
和sampleSize
字段配置采样。 两者都是可选的,只能指定一个。 如果两者均未指定,则将样本大小设置为10
。 通过设置analyzeShardKeyCharacteristicsDefaultSampleSize
来配置此值。
要根据collection中的所有文档计算指标,请将sampleRate
设置为1
。
有关读取和写入分布的指标
readWriteDistribution
包含有关查询路由模式和分片键范围热度的指标。 这些指标基于采样的查询。
要为集合配置查询采样,请使用configureQueryAnalyzer
命令。 仅当readWriteDistribution
为true
时才会返回读取和写入分布指标。 这些指标是在运行analyzeShardKey
时计算的,并且这些指标使用采样的读取和写入查询。 如果没有采样查询,则不会返回读取和写入分布指标。
如果没有采样的读取查询,该命令将返回
writeDistribution
但忽略readDistribution
。如果没有采样的写入查询,该命令将返回
readDistribution
但忽略writeDistribution
。
要使用analyzeShardKey
返回集合的读取和写入分布指标,必须配置查询分析器以对在集合上运行的查询进行示例。 否则, analyzeShardKey
将读取和写入分布指标返回为0
值。 要配置查询分析器,请参阅configureQueryAnalyzer。
keyCharacteristics 值 | readWriteDistribution 值 | 返回的结果 |
---|---|---|
true | false |
|
false | true | analyzeShardKey 返回readWriteDistribution 指标并省略keyCharacteristics 指标。 |
true | true |
|
非阻塞行为
analyzeShardKey
不会阻止对collection的读取或写入。
查询采样
有关读取和写入分布的指标质量取决于进行查询采样时工作负载的代表性。对于某些应用程序,返回代表性指标可能需要将查询采样保持打开状态几天。
支持索引
analyzeShardKey
所需的支持索引与shardCollection
命令所需的支持索引不同。
下表显示了analyzeShardKey
和shardCollection
的相同分片键支持的索引:
命令 | 片键 | 支持索引 |
---|---|---|
| { a.x: 1, b: "hashed" } |
|
shardCollection | { a.x: 1, b: "hashed" } | { a.x: 1, b: "hashed", ... } |
这允许您分析可能尚无分片所需的支持索引的分片键。
analyzeShardKey
和shardCollection
都有以下索引要求:
要创建支持索引,请使用db.collection.createIndex()
方法。
读取偏好
为了最大限度地降低性能,请使用secondary
或secondaryPreferred
读取偏好(read preference)运行analyzeShardKey
。在分片集群(cluster)上,如果未指定, mongos
会自动将读取偏好(read preference)设置为secondaryPreferred
。
限制
您无法在独立运行的实例上运行
analyzeShardKey
。您无法直接针对
--shardsvr
副本集运行analyzeShardKey
。 在分片集群上运行时,analyzeShardKey
必须针对mongos
运行。您无法针对time-series collection运行
analyzeShardKey
。您无法对具有Queryable Encryption的collection运行
analyzeShardKey
。
访问控制
analyzeShardKey
需要以下角色之一:
enableSharding
针对正在分析的collection的权限操作。clusterManager
针对集群的角色。
输出
analyzeShardKey
返回有关keyCharacteristics和readWriteDistribution的信息。
keyCharacteristics
提供有关分片键的关联基数、频率和单调性的指标。readWriteDistribution
提供有关查询路由模式和分片键范围热度的指标。
keyCharacteristics
这是当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中的文档的平均大小(以字节为单位)。 | 如果 numDocsTotal 与numDocsSampled 相当,则可以通过将每个mostCommonValues 的frequency 乘以avgDocSizeBytes 来估计最大数据块的大小。 |
numDocsSampled | 整型 | 采样文档的数量。 | |
numDistinctValues | 整型 | 不同分片键值的数量。 | 请选择具有较大 numDistinctValues 的分片键,因为不同的分片键值的数量是负载均衡器可以创建的最大数据块数。 |
isUnique | 布尔 | 指示分片键是否唯一。 仅当分片键存在唯一索引时,才会将其设置为 true 。 | 如果分片键是唯一的,则不同值的数量等于文档的数量。 |
mostCommonValues | 文档数组 | 最常用分片键值的值和 frequency (文档数量)的数组。 | 分片键值的频率是指数据块中包含该值的最小文档数。如果频率较大,则该数据块可能会成为存储、读取和写入的瓶颈。选择一个分片键,其中每个最常用值的频率相对于 可以通过设置 |
mostCommonValues[n].value | 文档 | 分片键。 | |
mostCommonValues[n].frequency | 整型 | 给定分片键的文档数量。 | 选择一个分片键,其中每个最常用值的频率相对于 numDocsSampled 较低。 |
monotonicity.
recordIdCorrelationCoefficient | double | 仅在单调性已知时设置。 | 当以下任一条件为 true 时,此项设置为
如果collection已Go数据块迁移,则单调性检查可能会返回不正确的结果。数据块迁移会从发送分片中删除文档,然后将其重新插入接收分片中。不保证来自客户端的插入顺序会得到保留。 您可以使用analyzeShardKeyMonotonicity CorrelationCoffiencyThreshold 配置相关系数的阈值。 |
monotoncity.type | 字符串 | 可以是以下之一:
| 避免使用类型为 如果按单调递增或递减的分片键对collection进行分片,则文档将插入到拥有 |
readWriteDistribution
这是当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。
readDistribution 字段
字段 | 类型 | 说明 | 使用 |
---|---|---|---|
sampleSize.total | 整型 | 已采样读取查询的总数。 | |
sampleSize.find | 整型 | 已采样的 find 查询总数。 | |
sampleSize.aggregate | 整型 | 已采样的 aggregate 查询总数。 | |
sampleSize.count | 整型 | 已采样的 count 查询总数。 | |
sampleSize.distinct | 整型 | 已采样的 distinct 查询总数。 | |
percentageOfSingleShardReads | double | 无论数据如何分布,针对单个分片的读取百分比。 | |
percentageOfMultiShardReads | double | 针对多个分片的读取百分比。 | 如果数据的分布使得读取的目标值属于单个分片,则此类别包括可能仅针对单个分片的读取。 如果查询对大量数据进行操作,则针对多个分片而不是一个分片可能会由于并行查询执行而减少延迟。 |
percentageOfScatterGatherReads | double | 分散-聚集读取的百分比,无论数据如何分布。 | 避免使用该指标具有较高值的分片键。 虽然分散-聚集查询对没有目标数据的分片影响很小,但它们仍然会对性能产生一些影响。 在具有大量分片的集群上,分散-聚集查询的性能明显低于针对单个分片的查询。 |
numReadsByRange | 整数数组 | 数字数组,表示从 MinKey 到MaxKey 排序的每个范围成为目标的次数。 | 避免使用 选择 可以使用 |
writeDistribution 字段
字段 | 类型 | 说明 | 使用 |
---|---|---|---|
sampleSize.total | 整型 | 已采样写入查询的总数。 | |
sampleSize.update | 整型 | 已采样的 update 查询总数。 | |
sampleSize.delete | 整型 | 已采样的 delete 查询总数。 | |
sampleSize.findAndModify | 整型 | 已采样的 findAndModify 查询总数。 | |
percentageOfSingleShardWrites | double | 无论数据如何分布,针对单个分片的写入百分比。 | |
percentageOfMultiShardWrites | double | 针对多个分片的写入百分比。 | 如果数据的分布使得写入的目标值属于单个分片,则此类别包括可能仅针对单个分片的写入。 |
percentageOfScatterGatherWrites | double | 无论数据如何分布,分散-聚集写入的百分比。 | 避免使用该指标具有较高值的分片键,因为针对单个分片的写入通常性能更高。 |
numWritesByRange | 整数数组 | 数字数组,表示从 MinKey 到MaxKey 排序的每个范围成为目标的次数。 | 避免使用 选择 可以使用 |
percentageOfShardKeyUpdates | double | 更新文档分片分片键值的写入查询的百分比。 | 避免使用 目前仅支持以可重试写入或事务形式进行更新,并且批处理大小限制为 |
percentageOfSingleWritesWithoutShardKey | double | 为 multi=false 且无法定位到单个分片的写入查询的百分比。 | 避免使用该指标具有较高值的分片键。 执行此类写入的成本很高,因为可能涉及运行内部事务。 |
percentageOfMultiWritesWithoutShardKey | double | 为 multi=true 且无法定位到单个分片的写入查询的百分比。 | 避免使用该指标具有较高值的分片键。 |
示例
考虑一个社交媒体应用的简化版本。 我们尝试分片的集合是post
集合。
post
collection中的文档具有以下模式:
{ 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()
方法创建索引。
{ lastName: 1 } keyCharacteristics
此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" }, } }
{ userId: 1 } keyCharacteristics
此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" }, } }
{ userId: 1 } readWriteDistribution
此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 } }