专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Go

第五一部分 架构篇 第十八章 MongoDB Sharding 架构(平衡)

发布时间:2011-06-29 18:23:14 文章来源:www.iduyao.cn 采编人员:星星草
第五部分 架构篇 第十八章 MongoDB Sharding 架构(平衡)

1、平衡简介

如果存在多个可用的分片,只要块得数量足够多,MongoDB就会把数据迁移到其他分片上,这个迁移过程叫做平衡(balancing),由叫做平衡器(balancer)的进程负责执行。

2、平衡工作流程

平衡器会把数据块从一个分片挪到另外一个分片上,其优点在于自动化,即你无需担心如何保持数据在分片间的均匀分布,这项工作已经由平衡器替你搞定,不过这也是它的缺点,因为自动意味着如果你不喜欢塔做负载均衡的方式,那只能算你不走运,如果不想让某个块存在于分片3上,你可以手动移动到分片2上,但是平衡器很可能把它再挪回分片3,你只能选择要么对集合重新分片(re-shard),要么关闭平衡化。

在此之前平衡器的算法还不是很智能,它每天基于分片整体大小来移动块,在不久的将来它将变得更加先进。

平衡器的目标不仅是要保持数据均匀分布,还要最小化被移动的数据量,因此触发平衡器需要很多条件,要触发一轮平衡,一个分片必须比块最小的分片多出至少9个块,到那时候,块就会被迁移出拥挤的分片,直到与其他分片平衡为止。

平衡器并不非常激进的原因在于MongoDB希望能够避免将相同数据来回移动,如果平衡器要平衡掉没一点微小的区别,那很可能会不停地浪费资源:分片1比分片2多两个块时,它就发送一个块给分片2,接着一些写操作落到分片2上,使得分片2又比分片1多出两个块,结果同一块数据又被折腾回去,通过等待更严重的不平衡发生,MongoDB能够最小化无意义的数据传输,要知道差9个块其实也不是那么不平衡,因为这还不到2GB数据呢?


说明:

如果如上图所示,每一点轻微的不平衡都被修正,则最终必然导致大量不必要的数据移动。


3、技巧

大家都希望通过看到数据移动来向自己证明分片可以工作,这产生了一个问题:触发一轮平衡所需的数据量远远比大多数人想象的大。

比如说正在尝试分片,于是写了一个命令行脚本来插入50万份文档到分片集合中:

for(i=0;i<500000;i++){
db.foo.insert({"_id":i,"x":1,"y:2"});
}
等插入完成,我应该能看见一些数据飞来飞去了,对不对?错,如果我看一眼数据库状态,就会发生还差得远呢?这些数据大致约40MB,这不够一个块,甚至不够一个块的1/4,前面讲到了一个块默认是200MB,真要想看到数据移动话,需要插入2GB数据,也就是2500万份这样的文档,或者说现在已插入数据的50倍。

开始使用分片时,人们希望看到数据到处移动,这是人的本性使然,尽管如此,在生产系统中你不会希望发生太多迁移,因为这种操作代价极其高昂,因此一方面我们希望看到迁移实际发生,而另外一方面事实又是如果它不是看上去慢慢得让人烦躁就不可能工作的很好,对于这个矛盾,MongoDB需要实现两个技巧,让分片更善解人意,同时又不对生产希望造成破性的影响。

  • 自定义块大小
第一次启动mongos时,可以声明--chunkSize N参数,其中N就是你想要的块大小,单位是MB,如果只是想试试分片,可以设置--chunkSize 1,这样只要插入几MB的数据就能看到迁移发生了。
  • 递增块大小
即使是部署一个真正的应用程序,要达到2GB看起也遥遥无期,所以对于前十几个块,MongoDB会特意自动降低块大小,从200MB降至64MB,而这就是为了更好地照顾一下用户的感受,一旦数据块多起来,它会自动把块大小递增回200MB。
  • 改变块大小
块大小可以通过启动时指定--chunkSize N参数或者修改config.settings集合并整体性重启来改变,尽管如此,除非是为了好玩试试1MB的块大小,否则别启动改动其大小。

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • ModernUI课程:定义一个Logo

    ModernUI教程:定义一个Logo ModernWindow的标题栏包含了一块区域用来显示自定义的窗体Logo: 这个窗体logo通过ModernWindow.LogoD...

  • Django忘记管理员账号和密码的解决方法

    Django忘记管理员账号和密码的解决办法 看着Django的教程学习搭建网站,结果忘记第一次创建的账号和密码了。结果搭建成功以后,一直...

  • GO语言小结(1)——基本知识

    GO语言总结(1)——基本知识 1、注释(与C++一样)   行注释://  块注释:/*   ...  */ 2、标识符   可以这么说,除了数字开头...

  • golang 惯用的文件读取方式

    golang 常用的文件读取方式 Golang 的文件读取方法很多,刚上手时不知道怎么选择,所以贴在此处便后速查。 一次性读取 小文件推荐一...

  • 查询深圳市通相关信息

    查询深圳通相关信息 用 HTTP.GET 从开放 API 中查询深圳通信息,然后将 JSON 数据存入结构体中,再格式化输出。 注意:获取的并不是实...

  • Go语言设计模式实践:结合(Composite)

    Go语言设计模式实践:组合(Composite) 关于本系列 这个系列首先是关于Go语言实践的。在项目中实际使用Go语言也有段时间了,一个体会就...

  • 列出索引和遍历目录

    列出目录和遍历目录 获取目录列表用 ioutil.ReadDir(),遍历目录用 filepath.Walk(),使用方法请参考文章示例。 示例代码: package ma...

  • io 包的惯用接口速记

    io 包的常用接口速记 我没有 C/C++ 基础,没有接口的概念,且从 Python 投奔而来,Python 的极简主义(一个结果往往只提供一个方法),让我在...

  • 代理服务扩充

    代理服务扩展 之前自己实现了一个代理服务,当时考虑的是只要支持SOCKS5就好了,因为我经常用CHROME,配合着SwitchySharp,体验还是很棒...

  • 文件的创造与打开

    文件的创建与打开 文件操作是个很重要的话题,使用也非常频繁,熟悉如何操作文件是必不可少的。Golang 对文件的支持是在 os package ...

热门推荐: