设为首页 加入收藏

TOP

Mongodb源码分析--Mongos之balancer(均衡)
2014-11-23 22:08:21 来源: 作者: 【 】 浏览:0
Tags:Mongodb 源码 分析 --Mongos balancer 均衡

html">在之前的一篇文章中,介绍了mongos的启动流程,在那篇文章的结尾,介绍了mongos使用balancer来进行均衡,今天就继续讲其实现方式。

首先我们看一下Balancer及相关实现策略的类图:

\
可以看到Balancer类里包含一个BalancerPolicy,其指向一个均衡策略,该策略会实现查找并收集要迁移的chunk。

这里先看一下Balancer的类定义,如下:


//balace.h
class Balancer : public BackgroundJob {
public:
Balancer();
virtual ~Balancer();
// BackgroundJob methods
virtual void run();
virtual string name() const { return "Balancer"; }

private:
typedef BalancerPolicy::ChunkInfo CandidateChunk;
typedef shared_ptr CandidateChunkPtr;

//mongos名称(hostname:port)
string _myid;

// Balancer 启动时间
time_t _started;

// 前移的chunks数量
int _balancedLastTime;

// 均衡策略(确定要迁移的chunks)
BalancerPolicy* _policy;

//初始化,检查balancer 能否链接到servers.该方法可能抛出网络异常
bool _init();

/**
* 收集关于shards及chunks的信息,以及可能需要迁移的chunks
* @param conn: 指向config server(s)连接
* @param candidateChunks (IN/OUT): 可能需要迁移的chunks
*/
void _doBalanceRound( DBClientBase& conn, vector* candidateChunks );

/**
* 逐个迁移chunk.并返回最终迁移的chunk数量
* @param candidateChunks 可能需要迁移的chunks
* @return number of chunks effectively moved
*/
int _moveChunks( const vector* candidateChunks );

/*在config server(s)中标记并前balancer为活动状态.*/
void _ping( DBClientBase& conn );

//当configdb中的所有服务均可用时,返回true
bool _checkOIDs();
};


可以看出balancer继承自BackgroundJob,所以它是以后台方式运行的。了解了该类的方法和属性之后,下面我们着手看一下mongos主函数中启动balancer.go()的调用流程。因为balancer继承自BackgroundJob,所以还要看一下BackgroundJob里go()方法的执行代码, 如下:

//background.cpp 线程方式运行下面的jobBody方法
BackgroundJob& BackgroundJob::go() {
boost::thread t( boost::bind( &BackgroundJob::jobBody , this, _status ) );
return *this;
}

////background.cpp. Background object can be only be destroyed after jobBody() ran
void BackgroundJob::jobBody( boost::shared_ptr status ) {
....
const string threadName = name();
if( ! threadName.empty() )
setThreadName( threadName.c_str() );

try {
run();//到这里,mongos开始执行子类balancer中的run方法
}
....

if( status->deleteSelf )
delete this;
}

上面代码最终会将执行流程转到balancer类的run()方法,如下

void Balancer::run() {

/* this is the body of a BackgroundJob so if we throw
here were basically ending the balancer thread prematurely */
while ( ! inShutdown() ) {

if ( ! _init() ) {//检查balancer是否链到config server和其它shard上
log() << "will retry to initialize balancer in one minute" << endl;
sleepsecs( 60 );
continue;
}

break;
}
//构造链接串信息
ConnectionString config = configServer.getConnectionString();
//声明分布式锁
DistributedLock balanceLock( config , "balancer" );

while ( ! inShutdown() ) {//一直循环直到程序中断或关闭

try {

// 判断chunk均衡功能是否有效
if ( ! grid.shouldBalance() ) {
log(1) << "skipping balancing round because balancing is disabled" << endl;
sleepsecs( 30 );
continue;
}
&nbs

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇我也要学C语言-第十五章:指针与.. 下一篇Mongodb源码分析--链接池(ConnPoo..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: