我在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
,但是我发现这些小型导入文档的开销很大。
答案 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来减少这种情况。
如果你拥有非常少量的数据,那么开销很大,但随着你的数据变得越来越大,这个开销只会很小。
使用启发式算法预先进行块拆分,因此您将看到在块达到最大大小之前发生拆分。