mongodb - MongoDB 中的默认 block 大小和拆分行为

标签 mongodb sharding

我有一些分片集合。在 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.databar.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/

相关文章:

linux - mongodb 无法从 mongo.conf 开始

node.js - 使用空数组添加新用户记录时为 "E11000 duplicate key error collection"

templates - Logstash模板不适合增加分片数量

sharding - 如何在 ArangoDB 中设置集群和分片?

SolrCloud:是否可以在搜索结果中获取文档的分片 ID

sql - MongoDB : few questions

node.js - MongoDB 使用聚合根据条件从嵌套数组中删除对象

arrays - 如果找不到值,则使用 Mongoose 将对象添加到数组,否则更新字段

database-design - 数据库分片、非规范化和同步

Mongodb 分片平衡不正常,报很多 moveChunk 错误