下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

MongoDB的最佳实践?

作者:课课家教育     来源: http://www.kokojia.com点击数:857发布时间: 2017-08-06 10:00:19

标签: 数据库MongoDB数据库基础

  MongoDB还存在许多需要改善的地方,比如全局写锁(现在仅仅是一个数据库级的写锁)。本文主要关注如何扩展以应对大数据,这里的大数据体积为100GB。

  当你着眼于底层存储的实现时,它将更有意义。基本上,MongoDB由一堆BSON文档mmap(内存映射)链表组成,它们使用了简单的B-tree索引,以及作为存储耐久性机制的基本日志。最终由OS写入磁盘,并在页面中读取由操作系统加载到内存中的数据结果。

并在页面中读取由操作系统加载到内存中的数据结果

  最初被称为杀手级优势的速度方面,其实只是使用了页面缓存的效果。很快你就会意识到“这仅仅是mmap”,所有BS架构相关优化也只是让你的工作集更加适合RAM,如果在分片上进行删除、增加记录等操作,将会产生重大影响。OS不知道你正在运行数据库,它只是知道你想MMAP一些东西并给它最佳的访问效果。幸运的是,该算法是由一些非常聪明的人写的,因此只要搜索结果可以在缓存命中,运行的也不错,但是OS调度写入时不会考虑你的存储布局,甚至是你的索引和数据之间的差异。这当然不能推断出什么样的数据保持在缓存中或预先载入,因为它不知道你的数据是什么或在哪里。

  其实,类似MongoDBTao这样的天才有很多,多数的数据库都使用了一些非常好的想法:Cassandra的一致性协议,Redis疯狂的数据结构,或Hadoop的数据处理能力。MongoDB拥有mmap,不必设计自己的缓存算法或写入策略,并利用一切尽可能简单的实现,让你快速进入市场并专注于你的销售基准,应对你的竞争对手,或者并发学习。对比之前,你会更有吸引力。到那个时候你可能已经变现或者编写了一个真正意义上的数据库,在任何情况下,你的客户都会被锁定,他们百依百顺以适应你的设计决策。但是请不要忽视,你正在向Oracle和IBM看齐,这并不是巧合。

  就像上文所说,MongoDB还存在许多需要改善的地方。需要关注的是,当你专注于存储引擎并忽略更广泛的持久性策略问题,杀手级应用应该类似于处理在线游戏中的用户数据:在给定的时间段中拥有一个一致的工作集,相对于整个数据库来说可能很小,读写操作都发生在同一个工作集上,你有大量的读取相对于写入来说,客户端为你做了大量的计算,如果你想获取更灵活的数据结构模式,你可以将其转换成一个关系模型,使用类似hstore或JSON列来填充图,或者像HBase或者Cassandra那样使用blobs/text来储存文档,但是绝对不会像使用MongoDB那么糟糕。

  通常意义上的NoSQL最佳实践

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

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

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

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

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

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

  MongoDB最佳实践

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

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

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

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

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

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

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

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

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

  小编结语:

  更多内容尽在课课家教育!

赞(26)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程