当前位置:首页>资讯 >渠道商圈 > 创业故事>不要总是依赖机器 MongoDB扩展彰显分片功夫

不要总是依赖机器 MongoDB扩展彰显分片功夫

2012-12-22 责任编辑:未填 浏览数:未显示 中贸商网-贸易商务资源网

核心提示:  Johannes Brandstettercs目前是omSysto GmbH开发运营总监,曾担任11 IT经理;致力于MongoDB、Hadoop、AWS上的项目研究。  纵

  Johannes Brandstettercs目前是omSysto GmbH开发运营总监,曾担任1&1 IT经理;致力于MongoDB、Hadoop、AWS上的项目研究。

  纵观****的应用程序建模和基础设施**实现的设计,很容易的发现一个问题:如果需要性能的**增长并适应从0到千万请求的自由缩放,只有一条路可走 —— 横向扩展(Scale Out)!

  扩展通常是描述给系统添加更多资源的方法。需要从两个方面区别:

  纵向扩展(Scale vertically/up)

  纵向扩展意味着给系统中单个节点增加资源,代表性的添加有单计算机的CPU或者内存提升。

  横向扩展(Scale horizontally/out)

  横向扩展意味着增加系统中节点的数目,比如说给一个分布式软件应用程序中添加计算机。举个简单的例子,将Web服务器系统中的服务器从1个提升到3个。

  使用MongoDB,你可以根据你的需求从两个方面去扩展:专注读操作或是写操作的提升。

  10gen告诉了我们一些扩展选项:

  “自带横向扩展能力,MongoDB允许用户**的建立和提高他们的应用程序。通过自动分片,你可以轻松的将数据分配到不同的节点上。副本集提供高可靠性,跨数据中心实现节点故障自动转移和恢复。”

  听起来不错,事实上呢?现在开始着手把2400万条数据导入由6个节点组成的MongoDB集群,这里使用的是自动分片:

  

 

  从上图看结果并不是很好,呈现出很不均匀的写入性能。假专注于单个节点的性能,情况比上面看起来更加的糟糕:

  

 

  分别点击查看大图

  这里不仅要看到所有节点上不均匀的写入速度,还要看到节点间每秒写入操作的巨大差别。有一瞬间Node2达到 4000 insert/s的,而那个时刻node5只有 740 insert/s !

  为什么会这样?我们使用mongoimport监视了整个导入过程发现:开始的一段时间内一切运行的很好,我们的集群也提供了一个很好的吞吐量;但是随着时间的推移,速度在逐渐的减缓。而通过mongostat,我们不难发现:有时候几秒内许多节点并没有分配到任何数据。

  想了解原因,我们必须要看一下MongoDB的分片机制。这里不得不看一下3个基本组件:

  1. MongoDB Sharding Router(mongos)

  所有通往集群的连接都由mongos选择,分片对应用层来说是完全透明的 —— 通过Transparent Query Routing进行路由。

  2. Mongo Config Server

  决定元数据中某个部分该分配到哪个对应的节点上。

  3. Mongo Shard Node

  用来支撑数据的普通mongod进程。

  那么要把数据储存到这样的集群中,你必须去做元数据查询来核对当前的数据该写到哪个节点上。然而即使每次写入前去决定目标节点会产生一定的开销,这里的性能损失也不该来的如此之大。

  但是现实就是这么残酷!这里要提起的就是Mongo Config Server,也就是必须要告诉MongoDB哪个范围的数据需要被用来分片。这就是传说中的“shard key”!同样如果你在shard key上做了个错误的决定,将会引起一系列的麻烦。当然为了简洁明了,这里选择一个我们认为很适合我们数据类型的shard key。

  那么MongoDB现在做的就是在内部把数据放入所谓的“chunk” —— 很像固定大小的data bucket。这样一来每个chunk中都包含了一定范围的数据并且只是一定容量的数据(默认64MB)。当我们把数据导入数据库,这些chunk将会被注入数据,一旦数据装满就会被MongoDB分割。这样一来必定会发生下面两种情况:

  新的元数据必须被写入配置好的服务器

  Balancer必须考虑某个chunk是否要转到另一个节点上

  现在我们就有必要关注一下第二点了!因为我们并没有告诉MongoDB任何shard key相关或者是怎么分布的,MongoDB在分片前则必须进行**的预估然后尝试将数据平均的分配到分片中。它通过在任何给定时间内保持所有节点上 chunk数量相同这一策略来保障数据的平均分配。在MongoDB 2.2中,新迁移阈值被引进并成功的将平衡集群带来的影响降到**。然而Mongo同样不知道shard key的范围和分布,那么就很可能发生热点区域 —— 很大一部分的数据被写入了同一个分片,因此也只在同一个节点上。

  既然我们知道了问题的所在,我们是否能够做点什么?

  数据预分割

  想做数据预分割必须对你将要导入的数据有充分的认识,所以取代让MongoDB完成chunk的选择你需要亲自动手。取决于你shard key的选择,你既可以使用一个脚本生成相关的命令(一个不错的用例)也可以使用MongoDB文档提供的方法。无论如何你都将完成对MongoDB chunk分配位置的告知:

  db.runCommand({split:"mydb.mycollection",middle:{shardkey:value}});

  当然你还可以强制MongoDB给chunk分配相应的节点。同样这取决于你的用例及应用程序对数据的读取方式。这里需要注意的是保留数据的局部性。

  增加chunk大小

  文档中有具体的chunk大小说明:

  1. 小的chunk以频繁迁移为代价获取数据更均匀的分布,这样会给Query Routing Layer增加更多的开销。

  2. 大的chunk会显著的减少迁移,不管是从网络设计还是从内部Query Routing Layer开销上都会带来收益。当然这些收益是以潜在的数据分布不均为代价。

  而为了能让MongoDB能运行的足够快,这里把chunk的大小提升为1GB。当然这是建立在对自己数据的了解上,所以务必让chunk的大小来的更有价值。

  关闭Balancer

  既然我们已经给chunk指定了具体节点,并且不希望在这过程中有新chunk的建立;我们可以使用以下的命令来关闭Balancer:

  1.

  useconfig

  2.

  db.settings.update({_id:"balancer"},{$set:{stopped:true}},true);

  选择正确的shard key

  Shard key是节点分布的核心。详情点击这里获得shard key相关的建议。在MongoDB 2.4中还支持MongoDB自主选择哈希shard key的选项。

  通过这些努力,导入情况如下:

  

 

  上图为集群中一个节点上的速率。当然还是有一些缝隙,因为数据不是**均与的进入。但总的来这是一个很大的提升,整个集群上的导入速度达到每秒4608次插入;现在导入速度只受到节点间网络接口的限制。

  总结

  天下没有免费的午餐!想获得卓越的性能,就必须亲力亲为。

  原文链接:Scaling MongoDB – Know your Sharding Kung Fu (编译/仲浩 王旭东/审校)

  欢迎关注@CSDN云计算微博,了解更多云信息。

  本文为CSDN编译整理,未经允许不得转载。如需转载请联系market@csdn.net

  (责任编辑:leonlee07)

分享到:
阅读上文 >> 债券评级自己动手 基金自建“避雷手册”
阅读下文 >> 辰州矿业高溢价收购负资产 危机矿山找矿

大家喜欢看的

  • 品牌
  • 资讯
  • 展会
  • 视频
  • 图片
  • 供应
  • 求购
  • 商城

版权与免责声明:

凡注明稿件来源的内容均为转载稿或由企业用户注册发布,本网转载出于传递更多信息的目的;如转载稿涉及版权问题,请作者联系我们,同时对于用户评论等信息,本网并不意味着赞同其观点或证实其内容的真实性;


本文地址:http://news.ceoie.com/show-159081.html

转载本站原创文章请注明来源:中贸商网-贸易商务资源网

微信“扫一扫”
即可分享此文章

友情链接

服务热线:0311-89210691 ICP备案号:冀ICP备2023002840号-2