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<CandidateChunk> 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<CandidateChunkPtr>* candidateChunks );
/**
* 逐个迁移chunk.并返回最终迁移的chunk数量
* @param candidateChunks 可能需要迁移的chunks
* @return number of chunks effectively moved
*/
int _moveChunks( const vector<CandidateChunkPtr>* 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<JobStatus> 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语言 ,