在之前的一篇文章中,介绍了mongos的启动流程,在那篇文章的结尾,介绍了mongos使用balancer来进行均衡,今天就继续讲其实现方式。
首先我们看一下Balancer及相关实现策略的类图:
可以看到Balancer类里包含一个BalancerPolicy,其指向一个均衡策略,该策略会实现查找并收集要迁移的chunk。
这里先看一下Balancer的类定义,如下:
可以看出balancer继承自BackgroundJob,所以它是以后台方式运行的。了解了该类的方法和属性之后,下面我们着手看一下mongos主函数中启动balancer.go()的调用流程。因为balancer继承自BackgroundJob,所以还要看一下BackgroundJob里go()方法的执行代码, 如下:
上面代码最终会将执行流程转到balancer类的run()方法,如下
上面方法中主要是先构造链接串,进而构造连接实例(注:这里使用了链接池的概念,我会在后续章节中专门介绍其实现机制)。之后刷新sharding中的相关信息(确保其有效性),之后调用_doBalanceRound()方法来收集可能要迁移的chunk(s)信息并最终完成迁移(使用_moveChunks方法)。
下面我们就着重看一下这两个方法的具体实现.
首先是_ doBalanceRound方法:
上面的_doBalanceRound方法主要构造shardLimitsMap,shardToChunksMap这两个实例对象集合(map<>类型),其中:
shardLimitsMap:用于收集shard集合中一些“起数量限制”作用的参数,如maxsize,draining,hasOpsQueued等,因为这几个参数如果超出范围或为true时,相应shard 是不可以提供迁移服务的。
shardToChunksMap:用于收集当前shard中的chunk信息,以便后面的遍历操作。
收集了这些信息之后,通过调用 _policy->balance()方法来找出可能需要迁移的chunk().
下面就看一下该均衡策略的具体实现(具体内容参见注释):
上面方法通过计算各个shard中的当前chunk数量来推算出那个shard相对较空,并将其放到to(目标shard),之后对可能要迁移的chunk进行校验,这里使用了pickChunk()方法,该方法具体实现如下:
完成了校验之后,得到的就是真正要迁移的chunk的启始地址,之后就可以进行迁移了。到这里,我们还要将执行流程跳回到Balancer::run()方法里,看一下最终完成迁移工作的方法movechunk()的实现流程:
上面代码就是依次遍历要迁移的chunk,分别根据其ns信息获取相应的ChunkManager(该类主要执行chunk的管理,比如CRUD等),之后就通过该ChunkManager找出当前chunk中最小的值(min:参见chunk.h文件,我这里把min,max理解为当前chunk中最小和最大记录对象信息)chunk信息,并开始迁移。
按照惯例,这里还是用一个时序列来大体回顾一下balancer的执行流程,如下:
![](http://daizhj.cnblogs.com/images/cnblogs_com/daizhj/mongodb_balancer_sequence.png)
好了,今天的内容就先到这里了。
原文链接: http://www.cnblogs.com/daizhj/archive/2011/05/23/mongos_balancer_source_code.html
作者: daizhj, 代震军
微博: http://t.sina.com.cn/daizhj
Tags: mongodb,c++,balance,chunk,shard,source code