我有一些分片集合。在 MongoDB 2.4.11 中,它们的大小在 50-90MiB 之间。根据文档,默认 block 大小为 64MB。
当我使用下面的命令检查 block 分布时,
db.getCollection(collName).getShardDistribution()
表明
一些大小低于 64MB 的集合已被分成几个 block 。
data : 58.13MiB docs : 148540 chunks : 2
estimated data per chunk : 29.06MiB
estimated docs per chunk : 74270
一些大小为 x 的集合,其中 64MB < x < 128 MB 有超过 2 个 block 。
data : 98.24MiB docs : 277520 chunks : 4
estimated data per chunk : 24.56MiB
estimated docs per chunk : 69380
这种行为是预期的吗?这是怎么发生的?
最佳答案
64MB 的值(可配置)是最大 block 大小而不是目标 block 大小。根据经验,通常 block 的创建大小会略低于该大小的一半,但有许多因素,这基本上是正常的,无需担心。
再多解释一下, block 通常会在达到最大大小之前很久就被分割。有两种机制会导致 split ,一种仅适用于集合的初始分片,另一种将一直运行(只要有写入发生且未禁用)。
这两种机制实际上使用相同的命令来确定一个 block 是否应该被分割,内部命令splitVector() .当 splitVector
被调用时,它检查指定的范围(在本例中是整个集合)并返回一个或多个分割点(如果有的话)(一个空数组意味着 block 的大小正确并且不需要拆分)。
随后的 block 拆分由 mongos
完成。您用来写入集合的任何 mongos
都会跟踪写入给定 block 的数据量,并且会定期检查(根据写入 block 的数量)是否存在任何有效拆分点,再次利用 splitVector
来做到这一点。如果找到有效的 split 点,它将在下一次获得所需锁时尝试 split 。
您可能想知道它是如何选择分割点的 - 这有点复杂,它可以基于数据大小或文档数量,当然还有您将最大块大小设置为多少。检查特定数据集的最佳方法是进行一些测试。例如,这里有两个集合,foo.data
和 bar.data
。我创建了仅包含 50MiB 数据的 bar.data
和包含 200MiB 数据的 foo.data
- 它们都具有相同大小的文档。 bar.data
集合没有拆分,所以 splitVector 很高兴这个 block 保持原样,而 foo.data
集合被拆分成 9 个大小相似的初始 block 您所看到的 (~24MiB):
{ "_id" : "bar", "partitioned" : true, "primary" : "shard0000" }
bar.data
shard key: { "_id" : 1 }
chunks:
shard0000 1
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 0)
{ "_id" : "foo", "partitioned" : true, "primary" : "shard0000" }
foo.data
shard key: { "_id" : 1 }
chunks:
shard0000 9
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : ObjectId("0a831759adacefd1231e6939") } on : shard0000 Timestamp(1, 0)
{ "_id" : ObjectId("0a831759adacefd1231e6939") } -->> { "_id" : ObjectId("150f322badacefd1233c920a") } on : shard0000 Timestamp(1, 1)
{ "_id" : ObjectId("150f322badacefd1233c920a") } -->> { "_id" : ObjectId("1f9bfd35adacefd1235b2786") } on : shard0000 Timestamp(1, 2)
{ "_id" : ObjectId("1f9bfd35adacefd1235b2786") } -->> { "_id" : ObjectId("2a213937adacefd1237829cb") } on : shard0000 Timestamp(1, 3)
{ "_id" : ObjectId("2a213937adacefd1237829cb") } -->> { "_id" : ObjectId("34b25e1cadacefd12396d4b1") } on : shard0000 Timestamp(1, 4)
{ "_id" : ObjectId("34b25e1cadacefd12396d4b1") } -->> { "_id" : ObjectId("3f3643feadacefd123b4a8f2") } on : shard0000 Timestamp(1, 5)
{ "_id" : ObjectId("3f3643feadacefd123b4a8f2") } -->> { "_id" : ObjectId("49c8edafadacefd123d33325") } on : shard0000 Timestamp(1, 6)
{ "_id" : ObjectId("49c8edafadacefd123d33325") } -->> { "_id" : ObjectId("5458e4ddadacefd123f14eb5") } on : shard0000 Timestamp(1, 7)
{ "_id" : ObjectId("5458e4ddadacefd123f14eb5") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 8)
关于mongodb - MongoDB 中的默认 block 大小和拆分行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25863108/