在MongoDB中对集合进行分片时,为什么我的数据目录如此之大?

时间:2016-07-19 16:29:20

标签: mongodb database-migration sharding

我在MongoDB中使用分片集合并创建了一些脚本来设置副本集,将它们添加到分片,然后将这些分片添加到我的主mongos进程。

我使用非常愚蠢的Python脚本生成数据:

import json

def gen_data(filename):
    with open(filename, 'w') as f:
        for i in range(100000*33):
            d = {"Hello": i, "World" : 99999-i}
            json.dump(d, f)
            f.write("\n")

if __name__ == "__main__":
    gen_data("my_data.json")

我创建了四个分片(a, b, c, d),每个分片有三个repl集(0, 1, 2)。数据目录称为a0, a1, a2, b0, b1, b2, c0, c1, c2, d0, d1, d2

在启用我的集合"hello.world"的分片后,我将块大小设置为100M。我导入数据,索引'_id',然后等待迁移。

在我的平衡器完成运行后,我发现每个碎片中的块数基本相等,但块的数量对于数据没有意义:

databases:
    {  "_id" : "hello",  "primary" : "a",  "partitioned" : true }
        hello.world
            shard key: { "_id" : 1 }
            unique: false
            balancing: true
            chunks:
                a   3
                b   3
                c   3
                d   2
//...

my_data.json是118M,但是当我检查数据目录的大小时,我发现它们中的每个都比原始数据大得多,我感到非常惊讶:

[erip@my_host shard_experiment]$ for s in {a..d}; do for n in {0..2}; do du -sh "$s$n"; done; done;
521M    a0
420M    a1
421M    a2
344M    b0
343M    b1
342M    b2
336M    c0
337M    c1
337M    c2
335M    d0
337M    d1
337M    d2

为什么我的数据目录如此之大?我在设置分片服务器时使用--smallfiles,但是我发现这些小型导入文档的开销很大。

1 个答案:

答案 0 :(得分:1)

请注意,--smallfiles选项仅适用于MMAPv1存储引擎,它不适用于MongoDB 3.2中默认的WiredTiger存储引擎。

MongoDB Journal可能占用了相当大的空间,每个节点可能需要300MB。您可以通过运行以下内容来验证这一点:

find . -name "journal" -exec du -sh {} \;

此外,Replica Set Oplog可能也使用了合理的空间。您可以通过登录其中一个副本集的mongo shell并运行db.printReplicationInfo()来检查正在使用的oplog大小。您可以通过在最初首次启动副本集时设置oplogSize来减少这种情况。

如果你拥有非常少量的数据,那么开销很大,但随着你的数据变得越来越大,这个开销只会很小。

使用启发式算法预先进行块拆分,因此您将看到在块达到最大大小之前发生拆分。