mongodb源码分析(十九)mongos的初始化以及连接池分配回收

本文探讨了MongoDB的mongos组件,作为分片系统的中心角色,它处理所有请求并转发到合适的mongod实例。文章主要分析了mongos的初始化过程,并详细讲解了连接池的分配和回收机制,为后续深入理解mongos的查询、操作以及自动分片和负载均衡奠定了基础。
摘要由CSDN通过智能技术生成

       mongos是mongodb提供的自动分片组件,在提供分片功能的mongodb系统中,几乎所有的请求都将通过mongos转发到mongod中,然后mongos再汇总,最后返回给客户端.本来就来分析分析mongos的初始化,为后面通过mongos的查询,删除,修改,增加记录 mapreduce aggregate以及mongos的自动分片与负载均衡做准备.下面来看代码,其入口为mongo\s\server.cpp中的main,去掉其中处理命令行参数部分,直接从其正式的开始函数runMongosServer入手.

static bool runMongosServer( bool doUpgrade ) {
    pool.addHook( new ShardingConnectionHook( false ) );//mongos使用连接池管理连接,这里设置连接池的回调函数,对于ShardingConnectionHook(false)时仅在创建新的连接时做验证工作,验证用户名以及密码
    pool.setName( "mongos connectionpool" );
    shardConnectionPool.addHook( new ShardingConnectionHook( true ) );//对于这里ShardingConnectionHook参数为true则需要根据连接的类型,若为master(单服务器) set(replset模式)则需要向连接默认发送命令setShardVersion,传递自己的ServerID(一个OID类型,自动生成),后面将会用到这个ServerID,将mongos错误转发的数据转发回mongs中,让其正确的转发到相应的mongod中,这个部分后面专门会用一篇文章谈到.
    shardConnectionPool.setName( "mongos shardconnection connectionpool" );
    // Mongos shouldn't lazily kill cursors, otherwise we can end up with extras from migration
    DBClientConnection::setLazyKillCursor( false );
    ReplicaSetMonitor::setConfigChangeHook( boost::bind( &ConfigServer::replicaSetChange , &configServer , _1 ) );
    if ( ! configServer.init( configdbs ) ) {//configServer的初始化,设置configserver的地址.
        return false;
  
    if ( ! configServer.ok( true ) ) {//连接configserver,确保能够连接configserver
        return false;
    }
    {
        class CheckConfigServers : public task::Task {
            virtual string name() const { return "CheckConfigServers"; }
            virtual void doWork() { configServer.ok(true); }
        };
        task::repeat(new CheckConfigServers, 60*1000);//这里每过60秒检查一次configserver是否可连接
    }
    int configError = configServer.checkConfigVersion( doUpgrade );//更新config版本,只能从2版本升级到3版本,动作简单来说是备份原来的数据
    if ( configError ) {//然后读取其数据,根据最新的3版本将数据写入到collection中,不再深入分析
        return false;
    }
    configServer.reloadSettings();//读取configserver中的设置,确保部分数据建立了索引.
    init();
#if !defined(_WIN32)
    CmdLine::launchOk();
#endif
    if ( !noHttpInterface )
        boost::thread web( boost::bind(&webServerThread, new NoAdminAccess() /* takes ownership */) );
    MessageServer::Options opts;
    opts.port = cmdLine.port;
    opts.ipList = cmdLine.bind_ip;
    start(opts);//开始启动服务.
    // listen() will return when exit code closes its socket.
    dbexit( EXIT_NET_ERROR );
    return true;
}
runMongoServer->ConfigServer::init
    bool ConfigServer::init( vector<string> configHosts ) {
        string hn = getHostName();
        set<string> hosts;
        for ( size_t i=0; i<configHosts.size(); i++ ) {
            string host = configHosts[i];
            hosts.insert( getHost( host , false ) );//服务器地址,不带端口
            configHosts[i] = getHost( host , true );//服务器地址,带端口
        }
        for ( set<string>::iterator i=hosts.begin(); i!=hosts.end(); i++ ) {
            string host = *i;
            bool ok = false;
            for ( int x=10; x>0; x-- ) {//通过getnameinfo解析服务器,
                if ( ! hostbyname( host.c_str() ).empty() ) {
                    ok = true;
                    break;
                }
                sleepsecs( 10 );
            }
            if ( ! ok )
                return false;
        }
        _config = configHosts;//保存配置
        string fullString;
        joinStringDelim( configHosts, &fullString, ',' );//将所有服务器地址连接起来
        _primary.setAddress( ConnectionString( fullString , ConnectionString::SYNC ) );//10gen建议生产环境中不要只使用一台configserver,这里多台server按照sync模式工作,就是所有请求处理同时发往这里设置的多台服务器上.
        return true;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值