【问题标题】:How to choose from MMAPV1, WiredTiger or In-Memory StorageEngine for MongoDB?MongoDB 的 MMAPV1、WiredTiger 或 In-Memory StorageEngine 如何选择?
【发布时间】:2016-10-25 09:43:11
【问题描述】:

在 MongoDb Documentation 3.2 中,我看到它们支持 3 个存储引擎, MMAPV1、WiredTiger、In-Memory,选哪一个很纠结。

我从描述中感觉到WiredTigerMMAPV1 更好,但在其他消息来源中,他们说 MMAPV1 更适合大量读取......而 WiredTiger 更适合大量写入......

在选择其中一个时是否有一些限制? 有人可以建议一些最佳做法,例如

当我有这种类型的应用程序时,通常最好这个,否则选择其他...

【问题讨论】:

    标签: mongodb storage-engines


    【解决方案1】:

    这是来自个人经验,但是请查看此博客条目,它很好地解释了不同类型的引擎: Mongo Blog v3

    比较 MongoDB WiredTiger 和 MMAPv1 存储引擎。更高的性能和效率在 7 倍和 10 倍的写入性能之间 MongoDB 3.0 提供更精细的文档级并发控制,为大多数写入密集型应用程序提供 7 倍到 10 倍的吞吐量,同时保持可预测的低延迟。

    对我来说选择非常简单,我需要文档级别的锁,这使得 WiredTiger 成为理想的选择,我们没有企业版的 mongo,因此内存引擎不可用。 MMAPv1 Btree 是将内存映射到硬盘的非常基本的技术,效率不高。

    MMAP 存储引擎使用称为“记录分配”的过程来获取磁盘空间用于文档存储。所有记录都连续位于磁盘上,当一个文档变得比分配的记录大时,它必须分配一条新记录。新分配需要移动文档并更新引用该文档的所有索引,这比就地更新花费更多时间并导致存储碎片。此外,由于记录空间的过度分配和缺乏对压缩的支持,当前迭代中的 MMAPv1 通常会导致文件系统的空间利用率很高。 如前所述,存储引擎的锁定方案是影响整体数据库性能的最重要因素之一。 MMAPv1 具有集合级锁定——这意味着一次只有一个插入、更新或删除操作可以使用一个集合。这种类型的锁定方案在并发工作负载中创建了一个非常常见的场景,其中更新/删除/插入操作总是在等待它们前面的操作完成。此外,这些操作的流入速度通常比存储引擎以串行方式完成的速度更快。把它放在上下文中,想象一个周日下午只有一个结账线开放的巨型超市:顾客很多,但吞吐量很低!

    每个人都有不同的要求,但在大多数情况下,WiredTiger 将是理想的选择,因为它在文档级别而不是集合级别上进行原子操作具有很大优势,您根本无法超越。

    更多的读取而不是很多的写入

    如果阅读是您主要关心的问题,这里是解决这个问题的一种方法。

    您可以通过以下方式调整 Mongo Driver Read Preference Modes

    1. 设置副本集,例如 1 个主节点和 3 个辅助节点。
    2. 将写关注设置为majority 这将使 写得慢一点(权衡)。
    3. 将读取偏好设置为次要。

    当您有大量读取时,此设置将执行得非常好,但作为权衡写入会更慢。但是读取数据的吞吐量会很大。

    如果您有其他问题,请将它们添加为评论,我希望这会有所帮助,我将尝试在此答案中解决。

    您还可以查看MMAPv1 vs WiredTiger 评论并注意他是如何从 MMAPv1 更改为 WiredTiger 的。卖方正在记录您无法超越的性能。

    对于新项目,我现在使用 WiredTiger。由于从压缩存储迁移到未压缩的 WiredTiger 存储相当容易,因此我倾向于从压缩开始以提高 CPU 利用率(“物有所值”)。如果压缩对性能或 UX 有明显影响,我会迁移到未压缩的 WiredTiger。

    MongoDB 数据库分析器

    确定数据库需求的最佳方法是设置测试集群并使用MongoDB profiler 在其上运行应用程序 与大多数数据库分析器一样,MongoDB 分析器可以配置为仅写入有关花费超过给定阈值的查询的配置文件信息。因此,一旦您知道慢查询,您就可以确定它是读取与写入还是 cpu 与 ram 并从那里开始。

    【讨论】:

    • 总之,Wired Tiger 几乎总是比 MMAPV1 好?
    • @AlexandruOlaru 我们运行多个 mongoDB 集群,WiredTiger 比 MMAPv1 更适合引擎,所以我的回答是肯定的,几乎总是
    • 没有@AlexandruOlaru 你可以访问这个blog.clevertap.com/…
    • @therealprashant 查看帖子答案更新。我认为“Wired Tiger 几乎总是比 MMAPV1 更好”是真的。
    【解决方案2】:

    您应该使用由内存和 WiredTiger 存储引擎组成的副本集。并且您应该以这样一种方式对您的 MongoDB 进行分片,即最常访问的数据应该由内存中的存储引擎访问,而其余的则使用 WiredTiger 存储引擎。

    在 2014 年收购 WiredTiger 之后,MongoDB 引入了这个存储引擎作为他们的default storage engine from version 3.2。此后,他们自己开始鼓励用户使用 WiredTiger,因为它比 MMAPV1 具有以下优势:

    • WiredTiger 使用文档级并发,而 MMAPV1 使用集合级锁定。这意味着多个用户可以使用 WiredTiger 同时写入一个集合,但不能使用 MMAPV1。
    • 由于 WiredTiger 管理自己的内存,它可以使用压缩,而 MMPAV1 没有任何此类功能。
    • WiredTiger 不允许任何就地更新。因此,它最终会回收不再使用的空间。

    到目前为止,我发现 MMPAV1 相对于 WiredTiger 的唯一优势是:

    • WiredTiger 在 Solaris 平台上不可用,而 MMPAV1 可用。
    • 即使在更新只有一个元素的大文档时,WiredTiger 也会重新编写整个文档,使其变慢。

    因此,您在选择存储引擎时始终可以忽略 MMPAV1。现在让我们来谈谈内存存储引擎。从 MongoDB Enterprise 版本 3.2.6 开始,in-memory storage engine 是 64 位版本中通用可用性 (GA) 的一部分。

    与存储引擎相比,它具有以下优点:

    • 与 WiredTiger 类似,内存存储引擎也允许文档级并发。
    • 内存存储引擎比其他引擎快得多。

      通过避免磁盘 I/O,内存存储引擎允许更可预测的数据库操作延迟。

    但是这个存储引擎也有不少缺点:

    • 内存存储引擎在进程关闭后不会持久化数据。

    • 如果您的数据集太大,那么内存引擎不是一个好的选择。

      内存存储引擎要求其所有数据(如果 mongod 是副本集的一部分,则包括 oplog 等)适合指定的 --inMemorySizeGB 命令行选项或 storage.inMemory.engineConfig.inMemorySizeGB 设置。

    查看 MongoDB 手册,例如 Deployment Architectures 使用内存存储引擎。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多