我有一个集合,其中分片键是UUID(十六进制字符串)。这个集合非常庞大:812百万个文档,2个分片上大约9600个块。由于某种原因,我最初存储的文件,而不是UUID在分片键字段中有整数。后来我完全删除了它们,现在我的所有文档都被UUID分片。但我现在面临着大块分发的问题。虽然我有整数而不是UUID的文档,但是balancer为这些文档创建了大约2700个块,并将所有文档留在一个碎片上。当我删除所有这些文件时,没有删除块,它们保持为空,它们将始终为空,因为我现在只使用UUID。由于平衡器根据每个分片的块数而不是文档数或大小来分配块,我的一个分片占用的磁盘空间比另一个多3倍:
--- Sharding Status ---
db.click chunks:
set1 4863
set2 4784 // 2717 of them are empty
set1> db.click.count()
191488373
set2> db.click.count()
621237120
这里令人遗憾的是mongodb没有提供手动删除或合并块的命令。 我的主要问题是,任何这方面的工作都可以摆脱空洞:
停止平衡器。连接到每个配置服务器,从config.chunks
范围的空块中删除,并将minKey
切片修复为在第一个非空块的开头结束。启动平衡器。
看似有风险,但据我所知,config.chunks
是唯一存储块信息的地方。
停止平衡器。启动一个新的mongod实例并将其作为第3个分片连接。手动将所有空块移动到这个新碎片,然后永久关闭它。启动平衡器。 不确定,但只要我不再在分片键中使用整数值,所有查询都应运行正常。
答案 0 :(得分:0)
有些人可能会读到这一点,并认为空的空间占据了空间。事实并非如此 - 块本身不占用空间 - 它们是分片键的逻辑范围。
但是,跨分片的块平衡是基于块的数量,而不是每个块的大小。
您可能希望将语音添加到此票证中:https://jira.mongodb.org/browse/SERVER-2487
答案 1 :(得分:0)
由于mongodb平衡器仅在分片之间平衡块数,因此在集合中包含太多空块会导致碎片由块数平衡,但严重不平衡每个碎片的数据大小(例如,如db.myCollection.getShardDistribution所示) ())。
您需要识别空块,并将它们合并到具有数据的块中。这将消除空块。现在所有这些都记录在Mongodb文档中(至少3.2及以上,甚至可能在此之前)。