日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Mongodb源碼分析之Mongos分析

MongoDB提供了auto-sharding 功能。因?yàn)槠涫莂uto-sharding,即mongodb通過(guò)mongos(一個(gè)自動(dòng)分片模塊,用于構(gòu)建一個(gè)大規(guī)模的可擴(kuò)展的數(shù)據(jù)庫(kù)集群,這個(gè)集群可以并入動(dòng)態(tài)增加的機(jī)器)自動(dòng)建立一個(gè)水平擴(kuò)展的數(shù)據(jù)庫(kù)集群系統(tǒng),將數(shù)據(jù)庫(kù)分表存儲(chǔ)在sharding的各個(gè)節(jié)點(diǎn)上。

我們提供的服務(wù)有:網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、青白江ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的青白江網(wǎng)站制作公司

一個(gè)mongodb集群包括一些shards(包括一些mongod進(jìn)程),mongos路由進(jìn)程,一個(gè)或多個(gè)config服務(wù)器

下面是一些相關(guān)詞匯說(shuō)明:

Shards :每一個(gè)shard包括一個(gè)或多個(gè)服務(wù)和存儲(chǔ)數(shù)據(jù)的mongod進(jìn)程(mongod是MongoDB數(shù)據(jù)的核心進(jìn)程)典型的每個(gè)shard開(kāi)啟多個(gè)服務(wù)來(lái)提高服務(wù)的可用性。這些服務(wù)/mongod進(jìn)程在shard中組成一個(gè)復(fù)制集

Chunks:Chunk是一個(gè)來(lái)自特殊集合中的一個(gè)數(shù)據(jù)范圍,(collection,minKey,maxKey)描敘一個(gè)chunk,它介于minKey和maxKey范圍之間。例如chunks 的maxsize大小是100M,如果一個(gè)文件達(dá)到或超過(guò)這個(gè)范圍時(shí),會(huì)被切分到2個(gè)新的chunks中。當(dāng)一個(gè)shard的數(shù)據(jù)過(guò)量時(shí),chunks將會(huì)被遷移到其他的shards上。同樣,chunks也可以遷移到其他的shards上

Config Servers : Config服務(wù)器存儲(chǔ)著集群的metadata信息,包括每個(gè)服務(wù)器,每個(gè)shard的基本信息和chunk信息Config服務(wù)器主要存儲(chǔ)的是chunk信息。每一個(gè)config服務(wù)器都復(fù)制了完整的chunk信息。

今天要介紹的源碼主要是Mongos的主入口函數(shù)的執(zhí)行流程,首先我們打開(kāi)Mongos的項(xiàng)目(可通過(guò)打開(kāi)源碼db\db_10.sln加載所有項(xiàng)目),如下圖:

注:如果要調(diào)試mongos,需要設(shè)置一個(gè)mongod進(jìn)程和一個(gè)Config Server,形如:

d:\mongodb>bin>mongod --dbpath d:\mongodb\db\ --port 27012

d:\mongodb>bin>mongod --configsvr --dbpath d:\mongodb\db\ --port 27022

然后在vs2010中配置相應(yīng)的boost路徑信息及啟動(dòng)參數(shù)信息,如下圖:

#p#

下面開(kāi)始正文。首先打開(kāi)mongos項(xiàng)目中的server.cpp文件,找到下面方法:

 
 
 
 
  1. int main(int argc, char* argv[]) {  
  2.     try {  
  3.         return _main(argc, argv);  
  4.     }  
  5.     catch(DBException& e) {  
  6.         cout << "uncaught exception in mongos main:" << endl;  
  7.         cout << e.toString() << endl;  
  8.     }  
  9.     catch(std::exception& e) {  
  10.         cout << "uncaught exception in mongos main:" << endl;  
  11.         cout << e.what() << endl;  
  12.     }  
  13.     catch(...) {  
  14.         cout << "uncaught exception in mongos main" << endl;  
  15.     }  
  16.     return 20;  

該方法是mongos的主函數(shù),代碼很簡(jiǎn),它主要是try方式執(zhí)行_main方法,下面是_main的執(zhí)行流程:

 
 
 
 
  1. int _main(int argc, char* argv[]) {  
  2.     static StaticObserver staticObserver;  
  3.     mongosCommand = argv[0];  
  4.     //聲明options信息描述對(duì)象  
  5.     po::options_description options("General options");  
  6.     po::options_description sharding_options("Sharding options");  
  7.     po::options_description hidden("Hidden options");  
  8.     po::positional_options_description positional;  
  9.     CmdLine::addGlobalOptions( options , hidden );  
  10.     //添加sharding選項(xiàng)描述信息  
  11.     sharding_options.add_options()  
  12.     ( "configdb" , po::value() , "1 or 3 comma separated config servers" )  
  13.     ( "test" , "just run unit tests" )  
  14.     ( "upgrade" , "upgrade meta data version" )  
  15.     ( "chunkSize" , po::value(), "maximum amount of data per chunk" )  
  16.     ( "ipv6", "enable IPv6 support (disabled by default)" )  
  17.     ( "jsonp","allow JSONP access via http (has security implications)" )  
  18.     ;  
  19.     options.add(sharding_options);  
  20.     ..... 

在完成option描述信息的初始化操作之后,下面就開(kāi)始對(duì)啟動(dòng)命令行參數(shù)進(jìn)行分析和執(zhí)行了,如下:

 
 
 
 
  1. .....  
  2.     // parse options  
  3.     po::variables_map params;  
  4.     //對(duì)argc,argv進(jìn)行分析并轉(zhuǎn)換成params,以便下面使用  
  5.     if ( ! CmdLine::store( argc , argv , options , hidden , positional , params ) )  
  6.         return 0;  
  7.     // The default value may vary depending on compile options, but for mongos  
  8.     // we want durability to be disabled.  
  9.     cmdLine.dur = false;  
  10.     //如果是help  
  11.     if ( params.count( "help" ) ) {  
  12.         cout << options << endl;  
  13.         return 0;  
  14.     }  
  15.     //如果是版本信息  
  16.     if ( params.count( "version" ) ) {  
  17.         printShardingVersionInfo();  
  18.         return 0;  
  19.     }  
  20.     //如要設(shè)置chunkSize  
  21.     if ( params.count( "chunkSize" ) ) {  
  22.         Chunk::MaxChunkSize = params["chunkSize"].as() * 1024 * 1024;  
  23.     }  
  24.     ......  
  25.     //必選項(xiàng),設(shè)置configdb信息  
  26.     if ( ! params.count( "configdb" ) ) {  
  27.        out() << "error: no args for --configdb" << endl;  
  28.        return 4;  
  29.     }  
  30.     vector configdbs;  
  31.     //對(duì)參數(shù)configdb進(jìn)行分割 (以','分割 )  
  32.     splitStringDelim( params["configdb"].as() , &configdbs , ',' );  
  33.     //mongodb強(qiáng)制為1或3,具體原因不明  
  34.     if ( configdbs.size() != 1 && configdbs.size() != 3 ) {  
  35.         out() << "need either 1 or 3 configdbs" << endl;  
  36.         return 5;  
  37.     }  
  38.     // we either have a seeting were all process are in localhost or none is  
  39.     for ( vector::const_iterator it = configdbs.begin() ; it != configdbs.end() ; ++it ) {  
  40.         try {  
  41.             // 根據(jù)地址參數(shù)實(shí)例化HostAndPort對(duì)象,如地址不合法則拋出異常  
  42.             HostAndPort configAddr( *it );  
  43.             if ( it == configdbs.begin() ) {  
  44.                 grid.setAllowLocalHost( configAddr.isLocalHost() );  
  45.             }  
  46.             //不允許在configdbs出現(xiàn)本地地址,注:如果configdb中全部為本地地址  
  47.             //(實(shí)際用處不大)時(shí)不會(huì)執(zhí)行下面if邏輯  
  48.             if ( configAddr.isLocalHost() != grid.allowLocalHost() ) {  
  49.                 out() << "cannot mix localhost and ip addresses in configdbs" << endl;  
  50.                 return 10;  
  51.             }  
  52.         }  
  53.         catch ( DBException& e) {  
  54.             out() << "configdb: " << e.what() << endl;  
  55.             return 9;  
  56.         }  
  57.     } 

上面完成了對(duì)命令行參數(shù)分析之后,接下來(lái)mongos要加載綁定幾個(gè)hook:

 
 
 
 
  1. // set some global state  
  2. //添加對(duì)鏈接池hook的綁定(shardingConnectionHook對(duì)象引用),以最終調(diào)用其onHandedOut方法  
  3. pool.addHook( &shardingConnectionHook );  
  4. //設(shè)置鏈接池名稱  
  5. pool.setName( "mongos connectionpool" );  
  6. //不設(shè)置“延遲kill游標(biāo)”  
  7. DBClientConnection::setLazyKillCursor( false );  
  8. //設(shè)置當(dāng)replicaSet配置修改時(shí)的hook對(duì)象(replicaSetChangey方法會(huì)更新鏈接對(duì)象信息  
  9. ReplicaSetMonitor::setConfigChangeHook( boost::bind( &ConfigServer::replicaSetChange , &configServer , _1 ) ); 

上面的hook主要是在mongos主程序啟動(dòng)完成后,在運(yùn)行期間執(zhí)行一些數(shù)據(jù)操作時(shí)執(zhí)行某些額外操作。從代碼可以看出,mongos使用了鏈接池功能以提升獲取鏈接的效率,具體實(shí)現(xiàn)機(jī)制我會(huì)在后緒章節(jié)中加以闡述。代碼中的ReplicaSetMonitor類為一個(gè)維護(hù)和獲取有效復(fù)制集的監(jiān)視類,它提供了獲取有效master,slave 的方法。完成這一步綁定后,接著mongos就會(huì)對(duì)config server信息進(jìn)行初始化和升級(jí)操作了,如下:

 
 
 
 
  1. //顯示sharding版本信息  
  2. printShardingVersionInfo();  
  3. //實(shí)始化configServer  
  4. if ( ! configServer.init( configdbs ) ) {  
  5.     cout << "couldn't resolve config db address" << endl;  
  6.     return 7;  
  7. }  
  8. if ( ! configServer.ok( true ) ) {  
  9.     cout << "configServer startup check failed" << endl;  
  10.     return 8;  
  11. }  
  12. //檢查Config版本信息(必要時(shí)進(jìn)行升級(jí)操作)  
  13. int configError = configServer.checkConfigVersion( params.count( "upgrade" ) );  
  14. if ( configError ) {  
  15.     if ( configError > 0 ) {  
  16.         cout << "upgrade success!" << endl;  
  17.     }  
  18.     else {  
  19.         cout << "config server error: " << configError << endl;  
  20.     }  
  21.     return configError;  
  22. }  
  23. //重新設(shè)置config db信息(包括shard中chunk的min,lastmod信息)  
  24. configServer.reloadSettings(); 

***就是啟動(dòng)偵聽(tīng)服務(wù),這里mongos啟動(dòng)了兩個(gè)偵聽(tīng)服務(wù)器,一個(gè)是以線程方式啟動(dòng),用于接收授權(quán)的用戶操作信息,另一個(gè)則是普遍的循環(huán)偵聽(tīng)服務(wù),用于偵聽(tīng)客戶端message如下:

 
 
 
 
  1. //初始化一些Signals信息,用于處理程序退出,中斷等情況  
  2. init();  
  3. //以線程方式啟動(dòng)webserver,循環(huán)偵聽(tīng)授權(quán)訪問(wèn)的 message信息,詳見(jiàn)dbwebserver.cpp文件中allowed方法  
  4. boost::thread web( boost::bind(&webServerThread, new NoAdminAccess() /* takes ownership */) );  
  5. MessageServer::Options opts;  
  6. opts.port = cmdLine.port;  
  7. opts.ipList = cmdLine.bind_ip;  
  8. start(opts);//啟動(dòng)message服務(wù)器,偵聽(tīng)客戶端message  
  9. dbexit( EXIT_CLEAN );  
  10. return 0; 

到這里,main代碼就介紹完了,但上面代碼段中的start才是啟動(dòng)balancer來(lái)均衡各個(gè)shard間chunk的操作,所以我們接著再看一下該方法的實(shí)現(xiàn):

 
 
 
 
  1. void start( const MessageServer::Options& opts ) {  
  2.     setThreadName( "mongosMain" );//設(shè)置線程名稱  
  3.     installChunkShardVersioning();//綁定chunk shard版本控制信息  
  4.     balancer.go();//均衡shard 中chunk(節(jié)點(diǎn))信息,詳情參見(jiàn) balance.cpp的run()方法  
  5.     cursorCache.startTimeoutThread();//對(duì)空閑(過(guò)期)游標(biāo)進(jìn)行清除操作  
  6.     log() << "waiting for connections on port " << cmdLine.port << endl;  
  7.     ShardedMessageHandler handler;  
  8.     MessageServer * server = createServer( opts , &handler );//構(gòu)造server對(duì)象  
  9.     server->setAsTimeTracker();  
  10.     server->run();//啟動(dòng)message服務(wù)  

好了,今天的內(nèi)容到這里就告一段落了,在接下來(lái)的文章中,將會(huì)介紹balancer的實(shí)現(xiàn)方式和操作流程。

原文鏈接:http://www.cnblogs.com/daizhj/archive/2011/05/16/2022041.html

【編輯推薦】

  1. Mongodb源碼分析--內(nèi)存文件映射(MMAP)
  2. 走進(jìn)MongoDB的世界 展開(kāi)MongoDB的學(xué)習(xí)之旅
  3. 淺析Mongodb源碼之游標(biāo)Cursor
  4. 野心勃勃的NoSQL新貴 MongoDB應(yīng)用實(shí)戰(zhàn)
  5. MongoDB與CouchDB全方位對(duì)比

名稱欄目:Mongodb源碼分析之Mongos分析
標(biāo)題來(lái)源:http://m.5511xx.com/article/ccdogic.html