当前位置:数据库 > mongodb >>

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语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,