【问题标题】:Fastest way to delete 100M+ documents by ID按 ID 删除 100M+ 文档的最快方法
【发布时间】:2019-01-04 23:22:23
【问题描述】:

我目前面临从数据库中从 100k 文档到 100M 文档的多个集合中删除 100M+ 文档的问题,总共约 300M 文档。此外,每个文档在其他集合中都有引用,这些引用必须被取消。我有一个要删除的所有文档的集合 + ID 列表,目标是尽快删除它们,以便对用户的影响最小。

我目前的方法是通过{ _id: { $in: [] } } 发送要删除的 5k 组,同时以相同的分组方式将更新发送到引用这些文档的所有集合。结果证明这很慢,所以我正在寻找替代方案。

我刚刚阅读了有关批量写入 API 的信息,我想知道这是否是一个更好的解决方案。如果是这样,我很好奇使用它的最有效方法是什么。我是否应该像现在一样继续分组,但在一个批量请求中一次发送多个组?我应该停止在查询中进行分组,而是使用批量请求作为我的组和 5k 个单独的删除/更新命令吗?

【问题讨论】:

  • @user2864740 不确定您的意思?出于速度和成本原因,我们正在归档旧数据以回收数据库中的空间。
  • 啊,我以为你只是在扔掉它:>

标签: mongodb


【解决方案1】:

因为我们无法承受用户停机时间,而且解决方案要每天运行(尽管规模要小得多,因为我们正在赶上第一次运行),所以我无法使用 Salvador Dali 的解决方案。我最终将要删除的记录分组为 1k 组,并为每条记录发送一个包含一个 delete() 操作的 BulkWrite 命令。同时,我发送了 n 个 BulkWrite 命令来取消对每个记录的引用,其中 n 是引用记录的集合的数量,并且每个 BulkWrite 请求具有 1k 个单独的 update() 操作,类似于 delete()。这执行得相当快,所以我没有尝试通过调整 BulkWrite 命令中的操作数来进一步优化。

【讨论】:

    【解决方案2】:

    根据您的要求(您有 3 亿份文档,您需要删除其中的 1/3),我会调查执行以下操作:

    创建新集合,然后用满足您要求的元素填充它。然后,删除以前的集合并重命名您的临时集合。

    多一点解释。您有一个包含 N 个文档的集合 A。您需要根据 ID 删除 N/3 个文档。为您的 ID 创建一个哈希表以进行删除。然后迭代集合,对于 ID 不在散列中的每个元素,将其保存在新的临时集合中。您可以通过将它们保存在 bulk insert 来改进它。

    为什么我认为它会更快:当您使用索引时,每次搜索都需要 O(log(n)) 时间,因此您可能会花费 O(n * log(k))。在我的情况下,在哈希映射中搜索是 O(1),因此我希望 O(n)

    【讨论】:

    • 感谢您的想法!这需要在迭代时暂停对集合的所有写入,对吧?不幸的是,这对我们来说是最坏的情况
    • @bloudermilk 您可以执行以下操作:遍历当前时间戳以下的所有项目,然后使用您为其余文档显示的方法。假设您在这段时间内不会有很多新文件(与您的 3 亿相比),它应该可以正常工作
    猜你喜欢
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 2022-06-30
    • 2012-01-07
    相关资源
    最近更新 更多