基於Mongodb進行分布式資料存放區

來源:互聯網
上載者:User

        註:本文是研究Mongodb分布式資料存放區的副產品,通過本文的相關步驟可以將一個大表中的資料分布到幾個mongo伺服器上。

       MongoDB的1.6版本中auto-sharding功能基本穩定並可以嘗試放到生產環境下使用。因為其是auto-sharding,即mongodb通過mongos(一個自動分區模組,用於構建一個大規模的可擴充的資料庫叢集,這個叢集可以併入動態增加的機器)自動建立一個水平擴充的資料庫叢集系統,將資料庫分表格儲存體在sharding的各個節點上。

       一個mongodb叢集包括一些shards(包括一些mongod進程),mongos路由進程,一個或多個config伺服器 

      (註:本文的測試案例需求64位的mongo程式,因為我在32位的mongo沒成功過)。 

       下面是一些相關詞彙說明:
       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資訊。

       接著看一下要配置的測試環境資訊:

       類比2個shard服務和一個config服務, 均運行在10.0.4.85機器上,只是連接埠不同
       Shard1:27020
       Shard2:27021
       Config:27022
       Mongos啟動時預設使用的27017連接埠

       在C,D,E磁碟下分別建立如下檔案夾:

               mongodb\bin 

               mongodb\db

 

       然後用CMD命令列依次開啟相應檔案夾下的mongd檔案:

       c:\mongodb\bin\mongod --dbpath c:\mongodb\db\ --port 27020

       d:\mongodb\bin\mongod --dbpath d:\mongodb\db\ --port 27021

       e:\mongodb\bin\mongod --configsvr --dbpath e:\mongodb\db\ --port 27022          (注:config設定管理員)

 

      啟動mongos時,預設開啟了27017連接埠

      e:\mongodb\bin\mongos --configdb 10.0.4.85:27022

 

      然後開啟mongo:

      E:\mongodb\bin>mongo   斷行符號  (有時加連接埠會造成下面的addshard命令出問題)

      > use admin
          switched to db admin
      > db.runCommand( { addshard : "10.0.4.85:27020", allowLocal : 1, maxSize:2 , minKey:1, maxKey:10} )  

         --添加sharding,maxsize單位是M,此處設定比較小的數值只為示範sharding效果

         { "shardAdded" : "shard0000", "ok" : 1 }
      > db.runCommand( { addshard : "10.0.4.85:27021", allowLocal : 1, minKey:1000} )
         { "shardAdded" : "shard0001", "ok" : 1 }      

          註:如果要移除sharding,可用下面寫法

          db.runCommand( { removeshard : "localhost:10000" } );

 

      > db.runCommand({listshards:1});   查看shard節點列表     

      {
        "shards" : [
                {
                        "_id" : "shard0000",
                        "host" : "10.0.4.85:27020"
                },
                {
                        "_id" : "shard0001",
                        "host" : "10.0.4.85:27021"
                }
        ],
        "ok" : 1
      }

 

 

       接下來建立相應資料庫並設定其"可以sharding",建立自動切片的庫user001:

       > config = connect("10.0.4.85:27022")
       > config = config.getSisterDB("config")
       > dnt_mongodb=db.getSisterDB("dnt_mongodb");
           dnt_mongodb
       > db.runCommand({enablesharding:"dnt_mongodb"})
          { "ok" : 1 }        註:一旦enable了個資料庫,mongos將會把資料庫裡的不同資料集放在不同的分區上。除非資料集被分區(下面會設定),否則一個資料集的所有資料將放在一個分區上。

       > db.printShardingStatus();

   --- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
      { "_id" : "shard0000", "host" : "10.0.4.85:27020" }
      { "_id" : "shard0001", "host" : "10.0.4.85:27021" }
  databases:
        { "_id" : "admin", "partitioned" : false, "primary" : "config" }
        { "_id" : "dnt_mongodb", "partitioned" : true, "primary" : "shard0000" }

 

  

       > db.runCommand( { shardcollection : "dnt_mongodb.posts1", key : {_id : 1}, unique: true } )             { "collectionsharded" : "dnt_mongodb.posts1", "ok" : 1 }     

        --使用shardcollection 命令分隔資料集,key自動產生 [必須為唯一索引unique index]。 

        如果要進行GridFS sharding,則需進行如下設定:
            db.runCommand( { shardcollection : "dnt_mongodb.attach_gfstream.chunks", key : { files_id : 1 } } )
            {"ok" : 1} ,更多內容參見http://eshilin.blog.163.com/blog/static/13288033020106215227346/

 

              > db.printShardingStatus()

   --- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
      { "_id" : "shard0000", "host" : "localhost:27020" }
      { "_id" : "shard0001", "host" : "localhost:27021" }
  databases:
        { "_id" : "admin", "partitioned" : false, "primary" : "config" }
        { "_id" : "user001", "partitioned" : true, "primary" : "shard0000" }
                dnt_mongodb.posts1e chunks:
                        { "name" : { $minKey : 1 } } -->> { "name" : { $maxKey :
 1 } } on : shard0000 { "t" : 1000, "i" : 0 

 

                        下面我用一個工具來批量向dnt_mongodb資料庫的 posts1表中匯入資料,大約是16萬條資料。匯入處理程序中mongos會顯示類似如下資訊:

      Tue Sep 07 12:13:15 [conn14] autosplitting dnt_mongodb.posts1 size: 47273960 shard: ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 1|0 min: { _id: MinKey } max: { _id: MaxKey } on: { _id: 19 }(splitThreshold 47185920)
Tue Sep 07 12:13:15 [conn14] config change: { _id: "4_85-2010-09-07T04:13:15-0", server: "4_85", time: new Date(1283832795994), what: "split", ns: "dnt_mongodb.posts1", details: { before: { min: { _id: MinKey }, max: { _id: MaxKey } }, left: { min: { _id: MinKey }, max: { _id: 19 } }, right: { min: { _id: 19 }, max: {_id: MaxKey } } } }
      Tue Sep 07 12:13:16 [conn14] moving chunk (auto): ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 1|1 min: { _id: MinKey } max: { _id: 19 } to: shard0001:10.0.4.85:27021 #objects: 0
      Tue Sep 07 12:13:16 [conn14] moving chunk ns: dnt_mongodb.posts1 moving ( ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 1|1 min: { _id: MinKey }max: { _id: 19 }) shard0000:10.0.4.85:27020 -> shard0001:10.0.4.85:27021
       Tue Sep 07 12:13:23 [WriteBackListener] ~ScopedDBConnection: _conn != null
       Tue Sep 07 12:13:23 [WriteBackListener] ERROR: splitIfShould failed: ns: dnt_mongodb.posts1 findOne has stale config
       Tue Sep 07 12:13:28 [WriteBackListener] autosplitting dnt_mongodb.posts1 size: 54106804 shard: ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 2|1min: { _id: 19 } max: { _id: MaxKey } on: { _id: 71452 }(splitThreshold 47185920)
       Tue Sep 07 12:13:28 [WriteBackListener] config change: { _id: "4_85-2010-09-07T04:13:28-1", server: "4_85", time: new Date(1283832808738), what: "split", ns: "dnt_mongodb.posts1", details: { before: { min: { _id: 19 }, max: { _id: MaxKey }}, left: { min: { _id: 19 }, max: { _id: 71452 } }, right: { min: { _id: 71452 }, max: { _id: MaxKey } } } }

 

             在完成自動sharding之後,可以使用mongo看一下結果:       > use dnt_mongodb
          switched to db dnt_mongodb
       > show collections
          posts1
          system.indexes
       > db.posts1.stats(){
        "sharded" : true,
        "ns" : "dnt_mongodb.posts1",
        "count" : 161531,
        "size" : 195882316,
        "avgObjSize" : 1212.6608267143768,
        "storageSize" : 231467776,
        "nindexes" : 1,
        "nchunks" : 5,
        "shards" : {
                "shard0000" : {
                        "ns" : "dnt_mongodb.posts1",
                        "count" : 62434,
                        "size" : 54525632,
                        "avgObjSize" : 873.3323509626165,
                        "storageSize" : 65217024,
                        "numExtents" : 10,
                        "nindexes" : 1,
                        "lastExtentSize" : 17394176,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 2179072,
                        "indexSizes" : {
                                "_id_" : 2179072
                        },
                        "ok" : 1
                },
                "shard0001" : {
                        "ns" : "dnt_mongodb.posts1",
                        "count" : 99097,
                        "size" : 141356684,
                        "avgObjSize" : 1426.4476623913943,
                        "storageSize" : 166250752,
                        "numExtents" : 12,
                        "nindexes" : 1,
                        "lastExtentSize" : 37473024,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 3424256,
                        "indexSizes" : {
                                "_id_" : 3424256
                        },
                        "ok" : 1
                }
        },
        "ok" : 1
      } 

 

     

       通過上面的結果,可以出現16萬條記錄均分在了兩個sharding上,其中shard0000中有62434條,shard0001中有99097條。下面看一下這兩個sharding-chunk的分布情況(圖中的錯誤提示‘輸入字串格式不正確’主要因為運行環境與編譯器使用的環境不同,一個是64,一個是32位系統):

 

          

      

      可以看到資料被按區間自動分割開了,有點像sqlserver的資料分區表,只不過這是自動完成的(目前我沒找到可以手工指定區間上下限的方式,如有知道的TX可以跟我說一下)。當然在本文中的測試中,共有5個chunk,其中4個位於shard0001,這種情況可以在每次測試過程中會發生變化,包括兩個sharding被分配的記錄數。另外就是在mongodb移動過程前後會在shard0000上產生一個檔案夾,裡麵包括一些bson檔案,名字形如(表格+日期等資訊):

       post-cleanup.2010-09-07T04-13-31.1.bson

      該檔案主要包括一些資料庫,表結構及相關記錄等資訊,我想應該是用於資料恢複備份啥的。

 

      好的,今天的內容就先到這裡了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.