【问题标题】:MongoDB sharded cluster writing more records than insertedMongoDB分片集群写入的记录多于插入的记录
【发布时间】:2022-01-24 15:16:32
【问题描述】:

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

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

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

有人能帮我理解为什么会这样吗?而且,我正在对我的集合进行分片,因为我每天要写大约 3000 亿条记录,我想增加我的写入吞吐量;所以任何其他建议都会非常感激。

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

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

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

【问题讨论】:

  • 看到波动的时候你是怎么数文件的?
  • 使用 db.collection.stats() 和 mongo compass 进行检查

标签: mongodb performance pyspark consistency


【解决方案1】:

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

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

更深层次的解释:

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

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

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

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

要使用此过滤器计算文档,请使用db.collection.countDocuments()

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

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

【讨论】:

  • 感谢@joe 的解释
猜你喜欢
  • 2011-07-05
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多