为什么在 MongoDB 中对集合进行分片时我的数据目录如此之大?
Why are my data directories so large when sharding a collection in MongoDB?
我正在尝试对 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
.
启用我的集合分片后,我将块大小设置为 100M,"hello.world"
。我导入数据,在 '_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
,但我发现导入如此小的文档的开销很大。
请注意,--smallfiles
选项仅适用于 MMAPv1 存储引擎,不适用于 MongoDB 3.2 中默认的 WiredTiger 存储引擎。
MongoDB Journal 很可能使用了相当数量的 space,每个节点大概 300MB。您可以通过 运行 验证这一点,例如:
find . -name "journal" -exec du -sh {} \;
此外,Replica Set Oplog 可能也使用了合理数量的 space。您可以通过登录副本集之一的 mongo shell 和 运行 db.printReplicationInfo()
来检查正在使用的 oplog 大小。您可以通过在首次启动副本集时设置 oplogSize 来减少这种情况。
像您这样拥有非常少量的数据,开销很大,但是随着您的数据变得越来越大,这种开销将只是很小的一部分。
块拆分是使用启发式算法预先完成的,因此您会看到拆分发生在块达到最大大小之前。
我正在尝试对 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
.
启用我的集合分片后,我将块大小设置为 100M,"hello.world"
。我导入数据,在 '_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
,但我发现导入如此小的文档的开销很大。
请注意,--smallfiles
选项仅适用于 MMAPv1 存储引擎,不适用于 MongoDB 3.2 中默认的 WiredTiger 存储引擎。
MongoDB Journal 很可能使用了相当数量的 space,每个节点大概 300MB。您可以通过 运行 验证这一点,例如:
find . -name "journal" -exec du -sh {} \;
此外,Replica Set Oplog 可能也使用了合理数量的 space。您可以通过登录副本集之一的 mongo shell 和 运行 db.printReplicationInfo()
来检查正在使用的 oplog 大小。您可以通过在首次启动副本集时设置 oplogSize 来减少这种情况。
像您这样拥有非常少量的数据,开销很大,但是随着您的数据变得越来越大,这种开销将只是很小的一部分。
块拆分是使用启发式算法预先完成的,因此您会看到拆分发生在块达到最大大小之前。