MongoDB 分片集群写入的记录多于插入的记录

MongoDB sharded cluster writing more records than inserted

我有一个包含大约 4300 万条记录的 spark 数据框,我正在尝试将其写入 Mongo Collection。 当我将其写入 unsharded collection 时,输出记录与我尝试插入的记录相同。但是当我将相同的数据写入分片 collection(散列)时,记录数增加了 3 millinos。

有趣的是,即使在我的 spark 作业完成后,记录的数量仍在波动。 (没有其他连接)

当我对范围分片 collection 执行相同操作时,记录数是一致的。 (编辑:即使使用范围分片集群,它也会在一段时间后开始波动)

谁能帮我理解为什么会这样?而且,我正在对我的 collection 进行分片,因为我每天要写大约 3000 亿条记录,我想提高我的写入吞吐量;所以任何其他建议将不胜感激。

我有 3 个分片,每个分片在 3 个实例上复制

我没有在 spark mongo 连接器中使用任何其他选项,仅使用 ordered=False

编辑: 几个小时后,记录数似乎稳定下来,记录数正确,但如果有人能帮助我理解为什么 mongo 表现出这种行为

,那就太好了

混淆是集合元数据和逻辑文档之间的差异,同时正在进行平衡。

最重要的是,如果您需要准确计数,您应该使用 db.collection.countDocuments()

更深入的解释:

当 MongoDB 对集合进行分片时,它会为每个分片分配一定范围的文档。当您插入文档时,这些范围通常会不均匀地增长,因此平衡器进程会在必要时将范围拆分为更小的范围,以保持它们的数据大小大致相同。

它还会在分片之间移动这些块,以便每个分片具有大致相同数量的块。

将块从一个分片移动到另一个分片的过程涉及复制该范围内的所有文档,验证它们是否已全部写入新分片,然后将它们从旧分片中删除。这意味着被移动的文档将在两个分片上存在一段时间。

当您通过 mongos 提交查询时,分片将执行过滤阶段以排除块中尚未完全移至此分片或完全移出块后未被删除的文档。

要利用此过滤器对文档进行计数,请使用 db.collection.countDocuments()

每个 mongod 维护它拥有的每个集合的元数据,其中包括文档计数。此计数在每次插入时递增,在每次删除时递减。元数据计数无法从未完成的迁移中排除孤立文档。

db.collection.stats() 返回的文档计数基于元数据。这意味着如果平衡器正在迁移任何块,则两个分片都会报告已复制但尚未删除的文档,因此总体计数会更高。