【问题标题】:Optimizing MongoDB for reads [closed]优化 MongoDB 以进行读取 [关闭]
【发布时间】:2013-11-22 15:30:23
【问题描述】:

我使用 MongoDB 作为只读文档源,用于计算统计信息。每个文档都没有子文档,但数据库大约有大约 900k 文档,并且每天会增加大约 1k 文档,在数据库空闲时添加。

所以,我想了解以下几点:

  1. 我了解到,当整个集合存储在 RAM 中时,MongoDB 工作得最好。假设我的数据库约为 400MB,并且我们的服务器可以轻松地将整个内容塞入 RAM,有没有办法告诉 MongoDB 将我的整个集合预加载到 RAM 中?

  2. 我还了解到,在某些情况下,创建副本集将有助于提高数据库的读取性能。我的情况是其中一种有用的情况吗?

  3. 我正在线程化我的统计计算,但请注意,当我线程化它们而不是同步运行它们时,在执行这些计算时完成对 mongoDB 运行的查询所需的时间增加了三倍。当我同时对同一个集合发出请求时,我可以做些什么来提高数据库的性能?

【问题讨论】:

  • 当您有多个问题时,请为每个问题打开一个新问题。如果有人可以回答三个问题之一,但不是全部,他们就不会写答案,因为它会因为不完整而被否决。
  • MongoDB 文档可以帮助您:docs.mongodb.org/master/administration/optimization

标签: multithreading mongodb mongoid


【解决方案1】:

不,当集合在 RAM 中时,MongoDB 不能最好地工作。我不知道是谁告诉你的,但这是对 MongoDB 工作原理的常见误解。

当 MongoDB 不仅可以将您的工作集放入 RAM (What does it mean to fit "working set" into RAM for MongoDB?) 中,而且还能以极快的速度将其加载到 RAM 中时,它的效果最好。有助于提高工作集中分页速度的一件事是文档的大小。

这是 MongoDB 限制为 16MB 的原因之一,已经发现,更大的大小开始对性能产生严重的不利影响。基本上,您花费了太多时间从磁盘加载数据,这是在 SQL 技术中通过逻辑拆分表来进行非规范化的原因之一;让它们更快地加载。

这意味着您可能必须同时优化值的大小和字段名称的大小,以匹配读取的性能需求。当然,您还必须匹配硬件。

副本集实际上并非旨在帮助提高读取性能,它们旨在通过自动故障转移为您的数据提供高可用性。您阅读的主题建议从辅助服务器获取陈旧的读数。正如最近已经证明的那样(edit:因为provided 是一个强词并且这是基于场景的,我会说“找到”),实际上可能不如使用PrimaryPreferred 读取首选项的性能。

至于提高性能,我们需要您提供有关页面错误、IO 瓶颈以及一般 mongostat 和顶部的统计信息。

【讨论】:

  • 如果整个集合都在 RAM 中,比不完全在 RAM 中要好。我觉得你说的不是真的。当然,如果磁盘 IO 很慢,那么这可能会严重损害整体性能。但是,如果可以在用户访问数据库之前加载整个集合......那么,这不是理想的吗?还有许多其他因素可能会导致查询变慢,当然也可能会产生重大影响(例如缺少索引)。
  • @WiredPrairie 操作系统很少将整个集合长时间保存在内存中,即使它很小,mongod 当然也不会将它固定到内存中,因此它实际上不会表现得更好。
  • 如果经常使用它会被保存在内存中,尤其是在没有内存压力的情况下。
  • (我赞成你的答案,因为我认为它比接受的答案更好...... :))。
  • “正如最近证明的那样,这实际上可能会降低性能” [需要引用]
【解决方案2】:

关于第1点:

您可以使用touch command 来说服数据库将集合加载到内存中。但请记住,这不是永久性的。当您不尽快访问缓存的文档时,它们将被取消缓存以支持更频繁使用的文档。

关于第2点和第3点:

副本集是提高并行读取操作性能的好方法。副本集的每个服务器都镜像整个数据,并且可以自行响应任何查询,而无需联系其他服务器。这意味着当您将副本集中的服务器数量增加一倍时,同时查询的性能也会增加一倍。

请记住,您在连接上设置的read preferences 可能会阻止它使用多个服务器。

或者,您可以构建一个分片集群,但这在技术上比副本集复杂得多,并且当您的查询与集合的分片键不匹配或当您以使请求在分片之间不均匀分布的方式选择您的分片键。

【讨论】:

  • 谢谢,这是一个让我开始的好地方!
  • 你是什么意思“没办法做到这一点” - 有触摸命令:docs.mongodb.org/manual/reference/command/touch
  • 副本集用于 HA 和故障转移。它们不是一种扩展读取的方法。
  • @AsyaKamsky 谢谢,我不知道触摸。答案已编辑。
  • @AsyaKamsky 提高可靠性只是使用副本集的原因之一。您可以使用副本集通过拥有多个辅助节点并在它们之间分配读取来扩展读取。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2023-02-09
  • 1970-01-01
  • 2019-11-23
  • 2021-12-04
  • 1970-01-01
  • 2018-06-27
相关资源
最近更新 更多