MongoDB最佳实践

fmms 12年前

  英文原文:MongoDB Best Practices

  将 MongoDB 加入到我们的服务支持列表中,是整个团队年初工作计划中的首要任务。但我们感觉如果先添加一项对 NoSQL 存储的支持,而不是先升级已支持的关系型数据库,可能对用户不太好,毕竟目前的用户都使用关系型数据库。

  所以我们决定将引入 MongoDB 这项工作放到升级 MySQL 和 PostgreSQL 之后来做。到目前为止,MySQL 5.5 的 Beta 版已在进行中,而 PostgreSQL 的9.1 Beta 版也将进入流程,因此我们打算在 2012 年第一季度中应用这两个版本。

  由于我们对 MongoDB 的关注,我们选择性地为几名使用 MongoDB 的用户提供了技术支持。在这个过程中,我们了解到了很多可能出现问题的地方。所以想借此文与大家分享 Engine Yard 眼中的 MongoDB 最佳实践。

  如果你的 MongoDB 是定制化安装的,我们强烈建议你将自己的设置与本文讲到的内容进行对比,并进行必要的设置修改。

  通常意义上的 NoSQL 最佳实践

  已有很多文章对 NoSQL 选型方面进行过讨论。在选择一个数据库产品时,通常可能需要考虑以下因素:读写吞吐量、持久化、一致性以及延迟等。在 Nathan Hurst 的文章《Visual Guide to NoSQL Systems》中对这些方面都做了详尽的介绍。

  数据库的选择是个大问题,本文不打算就这方面深入介绍,但希望读者能够自己去了解这方面的知识。一旦开发者了解得足够多,最后的结论永远都只有一个:没有任何一个数据库能够满足所有的应用场景。本文内容是基于选择 MongoDB 作为数据库存储上来说的。Engine Yard 在这方面提出了如下四点建议。

  全面测试。测试一定要使用切合实际场景的数据,并且需要尽量模拟业务场景的数据操作情况。否则,开发者会发现在上线后的实际场景下,可能导致一些性能瓶颈甚至发现整体架构上的设计缺陷。因此,尽可能使用实际场景的操作使用来进行测试,然后收集足够的测试数据。

  千万别以为在关系型数据库上的使用方法可以被直接移植。MongoDB 并不支持一些关系型数据库的功能,所以开发者最好先搞清楚 MongoDB 支持哪些功能。为了获得更好的性能,开发者最好多看 10gen 官方建议的文档设计和操作方法。另外,在使用 MongoDB 前,建议开发者做好对整个架构进行重构以适用新的存储模型的准备。为了更好地理解数据迁移的代价,建议阅读《The cost ofMigration》一文。

  明确数据需要的一致性和可靠性。对 MongoDB 来说,可靠性不再过度地依赖将数据写入到磁盘的操作,更多的是通过将数据同步到其他节点的方式解决可靠性问题。绝不建议开发者在真实环境中使用没有备份的节点单独工作。这一点很重要,所以建议开发者了解其中的原因。

  明确你对 EBS 的期望。如果你是 Engine Yard 云平台的用户(AWS EC2),那么应该知道,EBS 的性能不太稳定。所以在测试时,你最好收集足够多的 EBS 设备吞吐数据以做考量。Engine Yard 本身并没有对用户在 EBS 性能上做限制。

  MongoDB 最佳实践

  以下是我们将 MongoDB 引入到服务支持列表过程中所遵循的原则。

  总是使用 Replica Sets。Replica Sets 通过自动 failover 机制提供 MongoDB 的高可用性。在应用中,如 primary 机器出现故障,那么某一台 secondary 机器就会通过选举成为新的 primary,整个集群仍然能够提供正常服务。我们的服务不会支持无同步机制的 MongoDB 布置方案。如果在开发者自己的环境中同步机制的代价过高,我们建议其使用一些云存储服务。Engine Yard 目前已经与 MongoHQ 和 MongoLab 都建立了合作关系。开发者可以在合作者页面找到更多这方面的信息。

  保持版本更新。保持版本更新很重要,10gen 在每个版本中都会修复一些问题,使 MongoDB 的运行更出色。比如在2.0.x 版本中,MongoDB 的存储性能和并发性能就有极大提高,同时还包括索引优化、Bug 修复以及 compaction 命令等一系列改进,以便开发者更方便地扩展其集群。如果你还在使用1.6.3版本,那就快升级吧。

  不要在 32 位系统上使用 MongoDB。在 32 位机器上,MongoDB 只能存储约2.5GB 的数据。因为 MongoDB 在内部实现上是通过内存映射的方式来提高性能的,所以在 32 位机器上其内存地址本身就限制了数据容量。在 Engine Yard 云服务中使用 MongoDB,请使用 Large instance 来部署 MongoDB。在实际产品中,我们也只支持 64 位的 MongoDB。

  默认开启 journaling 日志。MongoDB 支持在写操作前记录 journaling 日志来提高节点的可用性。强烈建议在部署时开启 journaling 日志。注意数据文件的存放位置。在使用时,请确认你的数据文件处于一个持久化存储中(比如/data/mongodb 目录)。也可以使用非持久化的设备进行数据文件存储,不过你最好小心再小心,因为这可能会对你的集群架构造成影响。推荐使用 EBS 进行 MongoDB 的数据文件存储。热数据最好能放在内存中。能够保持热数据(以及索引数据)一直放在内存中,这一点非常重要,它将对整个集群的性能造成影响。如果通过监控发现 page fault 的数量增加,那么很可能就是热数据量超出了可用内存大小。当热数据量超出了可用内存量时,通常有两种解决方法:增加内存和数据分片。建议先增加内存,再考虑通过数据分片的方式解决。

  压力过大升级配置。如果机器负载达到 65%,那么应该考虑升级机器配置。在日常使用中,最好保持负载低于 65%。同时这也对数据恢复和纵向扩展有影响。当需要升级配置时,AWS 建议按下面的顺序来做:Large、Extra Large、High Memory 4XL。而在更高配置的机器上,网络延迟也会更小。

  分片需谨慎。分片策略会受数据访问特点的影响,所以在进行数据分片前,最好先理清楚数据的访问特点,并想明白是否确实需要分片。分片字段对性能的影响非常大,所以选择一个好的分片字段是非常重要的。Config 节点对整个集群的健康运行是至关重要的,所以一旦你选择使用分片机制,就一定要保证有 3 个 Config 节点。永远不要删除 Config 节点的数据,要确保频繁地对这些数据进行日常备份。如果可能,通过域名来指定节点的地址,比如在/etc/hosts 文件中指定相应的本地域名,这能让你在集群配置上更灵活。Config 节点的压力很小,但还需运行在 64 位机器上。千万不要把 3 个 Config 节点都放在同一台机器上!

  另外,如果你要部署一个分片集群,那么可以向 Engine Yard 专家服务预约咨询服务。

  使用 Mongo MMS 图形化监控服务。如果你还没有完善的 MongoDB 监控,可以尝试 Mongo MMS。Mongo MMS 是 10gen 官方发布的一个监控服务,可以将集群的各项健康指标以图形化的方式汇总展示。