MongoDB提供了auto-sharding 功能。因為其是auto-sharding,即mongodb通過mongos(一個自動分片模塊,用於構建一個大規模的可擴展的數據庫集群,這個集群可以並入動態增加的機器)自動建立一個水平擴展的數據庫集群系統,將數據庫分表存儲在sharding的各個節點上。
一個mongodb集群包括一些shards(包括一些mongod進程),mongos路由進程,一個或多個config服務器
下面是一些相關詞匯說明:
Shards : 每一個shard包括一個或多個服務和存儲數據的mongod進程(mongod是MongoDB數據的核心進程)典型的每個shard開啟多個服務來提高服務的可用性。這些服務/mongod進程在shard中組成一個復制集
Chunks: Chunk是一個來自特殊集合中的一個數據范圍,(collection,minKey,maxKey)描敘一個chunk,它介於minKey和maxKey范圍之間。例如chunks 的maxsize大小是100M,如果一個文件達到或超過這個范圍時,會被切分到2個新的chunks中。當一個shard的數據過量時,chunks將會被遷移到其他的shards上。同樣,chunks也可以遷移到其他的shards上
Config Servers : Config服務器存儲著集群的metadata信息,包括每個服務器,每個shard的基本信息和chunk信息Config服務器主要存儲的是chunk信息。每一個config服務器都復制了完整的chunk信息。
今天要介紹的源碼主要是Mongos的主入口函數的執行流程,首先我們打開Mongos的項目(可通過打開源碼dbdb_10.sln加載所有項目),如下圖:
注:如果要調試mongos,需要設置一個mongod進程和一個Config Server,形如:
d:mongodb>bin>mongod --dbpath d:mongodbdb --port 27012
d:mongodb>bin>mongod --configsvr --dbpath d:mongodbdb --port 27022
然後在vs2010中配置相應的boost路徑信息及啟動參數信息,如下圖:
下面開始正文。首先打開mongos項目中的server.cpp文件,找到下面方法:
int main(int argc, char* argv[]) {
try {
return _main(argc, argv);
}
catch(DBException& e) {
cout << "uncaught exception in mongos main:" << endl;
cout << e.toString() << endl;
}
catch(std::exception& e) {
cout << "uncaught exception in mongos main:" << endl;
cout << e.what() << endl;
}
catch(...) {
cout << "uncaught exception in mongos main" << endl;
}
return 20;
}
該方法是mongos的主函數,代碼很簡,它主要是try方式執行_main方法,下面是_main的執行流程:
int _main(int argc, char* argv[]) {
static StaticObserver staticObserver;
mongosCommand = argv[0];
//聲明options信息描述對象
po::options_description options("General options");
po::options_description sharding_options("Sharding options");
po::options_description hidden("Hidden options");
po::positional_options_description positional;
CmdLine::addGlobalOptions( options , hidden );
//添加sharding選項描述信息
sharding_options.add_options()
( "configdb" , po::value<string>() , "1 or 3 comma separated config servers" )
( "test" , "just run unit tests" )
( "upgrade" , "upgrade meta data version" )
( "chunkSize" , po::value<int>(), "maximum amount of data per chunk" )
( "ipv6", "enable IPv6 support (disabled by default)" )
( "jsonp","allow JSONP access via http (has security implications)" )
;
options.add(sharding_options);
.....
在完成option描述信息的初始化操作之後,下面就開始對啟動命令行參數進行分析和執行了,如下:
.....
// parse options
po::variables_map params;
//對argc,argv進行分析並轉換成params,以便下面使用
if ( ! CmdLine::store( argc , argv , options , hidden , positional , params ) )
return 0;
// The default value may vary depending on compile options, but for mongos
// we want durability to be disabled.
cmdLine.dur = false;
//如果是help
if ( params.count( "help" ) ) {
cout << options << endl;
return 0;
}
//如果是版本信息
if ( params.count( "version" ) ) {
printShardingVersionInfo();
return 0;
}
//如要設置chunkSize
if ( params.count( "chunkSize" ) ) {
Chunk::MaxChunkSize = params["chunkSize"].as<int>() * 1024 * 1024;
}
......
//必選項,設置configdb信息
if ( ! params.count( "configdb" ) ) {
out() << "error: no args for --configdb" << endl;
return 4;
}
vector<string> configdbs;
//對參數configdb進行分割 (以,分割 )
splitStringDelim( params["configdb"].as<string>() , &configdbs , , );
//mongodb強制為1或3,具體原因不明
if ( configdbs.size() != 1 && configdbs.size() != 3 ) {
out() << "need either 1 or 3 configdbs" << endl;
return 5;
}
// we either have a seeting were all process are in localhost or none is
for ( vector<string>::const_iterator it = configdbs.begin() ; it != configdbs.end() ; ++it ) {
try {
// 根據地址參數實例化HostAndPort對象,如地址不合法則拋出異常
HostAndPort configAddr( *it );
if ( it == configdbs.begin() ) {
grid.setAllowLocalHost( configAddr.isLocalHost() );