如何获取MongoDB每个块的数据大小
最近发现MongoDB分片集群的流量不太均衡,研究之后发现根本原因在于数据分布不均衡。虽然数据分布均衡不等于流量均衡,但还是应该尽量使得数据分布在不同shard之间基本均衡。三个shard的数据分布大概这样:
Shard | Data Size |
---|---|
mongo-0 | 10.55 GB |
mongo-1 | 25.76 GB |
mongo-2 | 10.04 GB |
mongo-1
这个分片的数据大小显著高于其他分片,而三个分片的chunk数目是基本一致的,所以需要分析不同分片上的chunk大小分布。
坏消息是并没有直接获取每个chunk数据大小的API。虽然chunk的基本信息存储在config.chunks
表中,但这个表并没有data size
类似的字段。假设有一个cxx
collection,使用Uuid
作为片键,查看config.chunks
表,它的某一个chunk的信息长这样:
{
"_id": {
"$oid": "603348a8b74404eea898cc25"
},
"lastmod": {
"$timestamp": {
"t": 0,
"i": 773
}
},
"lastmodEpoch": {
"$oid": "5ff83e4ba85a6bd465831542"
},
"ns": "cxx",
"min": {
"Uuid": "044B96CA34334FBE860D47BD63339B8E"
},
"max": {
"Uuid": "0494E87F8ED34B0E9ECF6BE5363BBD3C"
},
"shard": "mongo-2",
"history": [{
"validAfter": {
"$timestamp": {
"t": 6261,
"i": 1632930119
}
},
"shard": "mongo-2"
}
]
}
好消息是这个信息包括了一个chunk中所含数据的min/max
key。因此,我们可以通过 dataSize
API
来间接获取chunk数据大小:
{
dataSize: <string>,
keyPattern: <document>,
min: <document>,
max: <document>,
estimate: <boolean>
}
原理也很简单,就是使用dataSize
API计算在此chunk中的所有文档的大小总和。就上面的chunk的例子,可以在mongo
shell中使用如下命令获取它的实际大小(注意指定命令执行的最大超时时间maxTimeMS
):
db.runCommand({ dataSize: "cxx", keyPattern: { "Uuid": 1 }, min: { "Uuid": "044B96CA34334FBE860D47BD63339B8E" }, max: { "Uuid": "0494E87F8ED34B0E9ECF6BE5363BBD3C" }, maxTimeMS:1000 })
为了分析某个collection的所有chunk的数据大小分布,可以通过遍历config.chunks
表中的所有chunk并逐个获取它的数据大小来完成。最终的脚本如下(按需修改ns
和Uuid
等字段):
var ns = "";
db.getSiblingDB("config").chunks.find({ns : ns}).forEach(function(chunk) {
chunkSize = db.runCommand({ dataSize: ns, keyPattern: { "Uuid": 1 }, min: { "Uuid": chunk.min.Uuid }, max: { "Uuid": chunk.max.Uuid }, maxTimeMS:1000 })
print(chunk.shard + " " + chunk.min.Uuid + ": " + tojson(chunkSize.size/1024/1024) + "MB")
})
示例输出如下:
mongo-0 00020DFCE1B64BE28098133E09F0DFF9: 27.868586540222168MB
mongo-0 020FC0A3F7DC456D8CA48787A22BFEF5: 0.03055095672607422MB
mongo-1 02109DCC630C4EB68D890BB1C664C732: 2.049802780151367MB
mongo-1 02394113C1FF4C33BB067299D00F2A57: 0.17893218994140625MB
mongo-0 023CB90536CB4D9A83E88BC362CDA80A: 5.774362564086914MB
mongo-0 02AD2533642349398B6B7518914C87E7: 8.088775634765625MB
mongo-1 03463C80D8844550A3F1F259345807DA: 3.041494369506836MB
mongo-0 037F4D692AE34A3FB7F4B5A3205121C2: 1.5527820587158203MB
mongo-1 039C5810056F4205B1FC476A67F003BF: 6.535520553588867MB
mongo-2 04197554460047ADBD5B62B35F4956B6: 2.715306282043457MB
...