为什么我的数据目录在MongoDB中分割集合时这么大?

问题描述:

我正在玩MongoDB中的一个集合,并创建了一些脚本来设置副本集,将它们添加到碎片,然后将这些碎片添加到我的主mongos进程。为什么我的数据目录在MongoDB中分割集合时这么大?

我生成的数据与一个非常愚蠢的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),每个碎片3件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,但是当我检查我的数据目录的大小,我很惊讶地发现,他们每个人比原始数据要大得多:

[[email protected]_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,但是我发现这些小的导入文档的开销很大。

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

MongoDB的Journal很可能使用了大量的空间,大概300MB的每个节点。您可以通过运行这样验证这一点:

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

此外,Replica Set Oplog大概也利用空间的合理费用。您可以通过登录到您的副本集之一的mongo shell并运行db.printReplicationInfo()来检查正在使用的oplog大小。当您首次启动副本集时,您可以通过设置oplogSize来减少此问题。

有了,你有一个非常小的数据量,开销很大,但随着数据的增长要大得多这种开销将只有少量。

组块分割完成先发制人使用启发式算法,所以你会看到发生拆分大块达到最大尺寸了。