MongoDB:一个集合中的亿万文档

51

我需要将66亿个二元组加载到集合中,但是我找不到最佳的方法。

将这么多文档加载到单个主键索引上会花费很长时间,但据我所知,Mongo没有支持分区的等效功能?

分片会有帮助吗?我应该尝试将数据集分成许多集合并将该逻辑构建到我的应用程序中吗?


4
请看我的回答是否有帮助:https://dev59.com/e-o6XIcBkEYKwwoYSClJ#6786925 - DhruvPathak
2个回答

67

很难说什么是最佳的批量插入方式 - 这在一定程度上取决于您要插入的对象的大小和其他不可测量因素。您可以尝试一些范围并查看哪种方法能够提供最佳性能。作为替代方案,有些人喜欢使用mongoimport,它非常快速,但您导入的数据需要是json或csv格式的。如果数据以BSON格式存在,则可以使用mongodrestore。

Mongo可以轻松处理数十亿个文档,并且可以在一个集合中拥有数十亿个文档,但请记住最大文档大小为16mb。许多人在MongoDB中拥有数十亿个文档,并且关于此进行了大量讨论,可以在MongoDB Google用户组中找到相关内容。如果您改变主意想使用多个集合,这里有一篇关于使用大量集合的文档可以阅读。您拥有的集合越多,索引也就越多,这可能不是您想要的。

这是Craigslist的演示,介绍了如何向MongoDB中插入数十亿个文档以及该人的博客文章

看起来分片对您来说可能是一个好的解决方案,但通常分片用于跨多个服务器进行扩展,并且许多人这样做是因为他们想要扩展写入操作或无法将工作集(数据和索引)保存在RAM中。从单个服务器开始,然后随着数据增长或需要额外的冗余和弹性而转移到分片或副本集是完全合理的。

然而,还有其他用户使用多个mongods来绕过单个mongod的锁定限制,以便处理大量写操作。这很明显,但仍值得一提,因为一个多mongod设置比单个服务器更复杂。如果您的IO或CPU没有达到最大值,在此情况下,您的工作集小于RAM,数据很容易保持平衡(相当随机分布),您应该能看到改进结果(将分片放在单个服务器上)。需要注意的是,存在内存和IO争用的潜力。随着2.2版本并发性数据库锁定的改进,我认为将很少理由进行这样的部署。

您需要正确计划分片移动,即仔细考虑选择分片密钥。如果您采用这种方式,最好预先分裂并关闭均衡器。移动数据以保持平衡将是适得其反的,这意味着您需要事先决定如何分割数据。此外,有时设计文档时重要的是考虑某些字段是否有用于分片或作为主键。

以下是一些有用的链接 -

  • 分片最佳实践演示

  • 1
    如果你正在迭代处理大量数据,就像你所建议的那样,在任何数据库中都会变得很慢,包括其他大型数据库解决方案。 - Chris Houghton
    不,@ChrisHoughton,即使在超过65亿条记录的情况下,使用mysql innodb引擎进行插入/选择操作速度也会显著提高,当然需要使用复合索引和分区。但是,当我尝试在mongodb上处理10亿条记录时,特别是在使用聚合函数时,效果非常糟糕。 - Arthur Kushman

    8
    你可以绝对地在MongoDB中分片数据(这将在分片键上分区到N个服务器上)。事实上,这是它的核心优势之一。你不需要在应用程序中这样做。
    对于大多数用例,我强烈建议对66亿个文档进行分片。根据我的经验,MongoDB在许多中等规模的服务器上表现更好,而不是一个大型服务器。

    1
    这仅适用于单个服务器。即使创建4个分片,每个分片仍将保存数十亿条记录... - Elliot Chance
    至少在6个月前我使用高容量MongoDB时,锁定非常不理想。即使你的分片在同一物理服务器上,运行多个MongoDB实例可能会获得更好的性能(但我认为这种配置并没有得到官方支持)。请对你的用例进行基准测试。 - Eric J.
    3
    同样,如果你没有足够的RAM来保持工作集(经常访问的文档)在内存中,Mongo性能会急剧下降(相对而言)。要注意这一点。 - Eric J.
    2
    @EricJ. 这不是索引需要适合内存的情况吗? - D-Klotz
    @D-Klotz:实际上两者都是。至少在我当时使用MongoDB的时候是这样。与SQL Server相比,内存中的索引通常是最关键的方面。 - Eric J.

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接