[Linux] mongodb 初步--2/3

URL Link //n.sfs.tw/10607

2017-01-13 12:22:56 By 張○○

群組文章
[Linux] mongodb 初步--1/3  安裝及基本操作

[Linux] mongodb 初步--2/3 叢集

[Linux] mongodb 初步--3/3 權限和幫助

使用mongodb的一些大小事:關於叢集。

個人認為一個好的資料庫叢集應該有下面的特性:

因此,在使用mongo的叢集時,一定要先把他給搞懂,以下的文字都是用我的話寫的,如有疑問或錯誤歡迎討論。

一、名詞解釋

1. replica set 複本組(我給他的中文名)

    複本組是非同步的主要/隨從資料庫」型式,再加上自動的失敗復原功能,簡單的來說,就是「主從式」的架構。

2. sharding 切片
    sharding是指一個「切片的方法」,這個方法可使資料庫藉由自動分割的方式平行擴展。叢集資料庫中每一個單元叫shard(一個切片),叢集資料庫可由數個切片組成;每一個切片中可包含一個複本組或是一個結點所組成。

3. Sharded Cluster 切片的叢集

  將許多的分散的資料庫程式集合在一起,看起來就像只有一個資料庫的方法叫叢集。mongodb採用切片的方法來叢集,所以叫切片的叢集(Sharded Cluster)。
  這個方法,就像是政府目前推行的「單一窗口」,讓洽公的民眾不必打電話轉來轉去找不到承辦單位,由統一的窗口單位幫你轉到能幫你處理事情的單位。

4. oplog(operations log) 操作記錄

  不由分說,這個東西就是管理叢集資料庫的操作,它其實是一個包裝過的資料表(capped collection),裡面記錄所有修改的操作以供所有的複本組同步使用,每個複本組中的結點都會複製一份oplog來維持同步,Linux中預設會用磁碟空間的5%,如果資料庫拿來存檔案的話,空間不宜太小以策安全。

二、規畫

這是我的規畫

規畫的考量

三、設定

因為只有三台伺服器,所以暫時只設定rs1和rs2這兩個複本組,爾後有增加伺服器時,再增加設定rs3, rs4.....

1. 建立資料庫目錄
[SERVER1]

# cd /var/lib/mongo/

# mkdir rs1data

# mkdir config

# chown mongod:mongod rs1data

# chown mongod:mongod config

[SERVER2], [SERVER3]

# cd /var/lib/mongo/

# mkdir rs1data

# mkdir rs2data

# mkdir config

# chown mongod:mongod rs1data

# chown mongod:mongod rs2data

# chown mongod:mongod config

2. 建立複本組

將oplog設為2G
[SERVER1]
# mongod --shardsvr --replSet rs1 --port 28001 --dbpath /var/lib/mongo/rs1data --oplogSize 2000 --logpath /var/lib/mongo/rs1.log --logappend --fork

[SERVER2], [SERVER3]
# mongod --shardsvr --replSet rs1 --port 28001 --dbpath /var/lib/mongo/rs1data --oplogSize 2000 --logpath /var/lib/mongo/rs1.log --logappend --fork
# mongod --shardsvr --replSet rs2 --port 28002 --dbpath /var/lib/mongo/rs2data --oplogSize 2000 --logpath /var/lib/mongo/rs2.log --logappend --fork

3. 初始化複本組

分別連到複本組rs1及rs2其中一個node:

[rs1]

# mongo 163.17.38.80:28001

MongoDB shell version: 2.2.2

connecting to: 163.17.38.80:28001/test

> cfg={ _id : 'rs1', members : [   {_id:0, host: '163.17.38.80:28001'},  

 {_id:1, host: '163.17.38.81:28001'},   {_id:2, host: '163.17.38.84:28001'}, ] }

> rs.initiate(cfg);

{

        "info" : "Config now saved locally.  Should come online in about a minute.",

        "ok" : 1

}

[rs2]

# mongo 163.17.38.81:28002

MongoDB shell version: 2.2.2

connecting to: 163.17.38.80:28001/test

> cfg={ _id : 'rs2', members : [   {_id:0, host: '163.17.38.81:28002'},  

 {_id:1, host: '163.17.38.84:28002'},   ] }

> rs.initiate(cfg);

{

        "info" : "Config now saved locally.  Should come online in about a minute.",

        "ok" : 1

}

查看rs狀態:
> rs.status();

看誰是主要master
> db.isMaster()

更多指令
> rs.help();

4. 設置config server

[SERVER1], [SERVER2], [SERVER3]

# mongod --configsvr --port 28000 --dbpath /var/lib/mongo/config --logpath /var/lib/mongo/config.log --logappend --fork

到此為止config server 和複本組還沒有任可關聯,換句話說,複本組還不知道config server的存在。所以,接下來就是要配置route server,讓他和config server產生關聯。

5. 設置route server(mongos)

這裡我採用32MB(預設是64MB)作為chunksize,數字越大越不容易平均分散,數字越小效能會降低。

[SERVER1], [SERVER2], [SERVER3]

# mongos --configdb 163.17.38.80:28000,163.17.38.81:28000,163.17.38.84:28000 --port 27017 --chunkSize 32 --logpath /var/lib/mongo/mongos.log --logappend --fork

6. 組態 sharded cluster

最後要做的事,就是讓mongos知道有那些rs可以用,並把每個rs編成shard

連到任一台的mongos

# mongo 163.17.38.80:27017

mongos> use admin;
switched to db admin
mongos> db.runCommand( {addshard: "rs1/163.17.38.80:28001,163.17.38.81:28001,163.17.38.84:28001", 
    name: "sh1", maxsize:50});
{ "shardAdded" : "sh1", "ok" : 1 }
mongos> db.runCommand( {addshard: "rs2/163.17.38.81:28002,163.17.38.84:28002", 
    name: "sh2", maxsize:50});
{ "shardAdded" : "sh2", "ok" : 1 }
// 觀察我的切片
mongos> db.runCommand( { listshards : 1 } )
{
        "shards" : [
                {
                        "_id" : "sh2",
                        "host" : "rs2/163.17.38.81:28002,163.17.38.84:28002"
                },
                {
                        "_id" : "sh1",
                        "host" : "rs1/163.17.38.80:28001,163.17.38.81:28001,163.17.38.84:28001"
                }
        ],
        "ok" : 1
}
// 將資料庫拿來切片,執行這個指令後,該資料庫不同collection會被放在不同切片,但collection本身不再被切片
mongos> db.runCommand( { enablesharding: "<dbname>" } );
ex: 
mongos> db.runCommand( { enablesharding : "test" } );
{ "ok" : 1 }

 

7. 將collection 也切片

如果只有資料庫切片,遇到比較大的collection,就會有平均的問題出現。記得 enablesharding 的指令要先下後才執行這個指令。

它的寫法是

> db.runCommand({ shardCollection: "<db>.<collection>", key: <shardkey> });

這裡的 key 是指collection中再被切的依據方法

ex: 

mongos> use test
mongos> db.createCollection("c1");
{ "ok" : 1 }

 

備註

1. 要刪除一個執行中的 mongod # mongod --port 28001 --dbpath /var/lib/mongo/rs1data --shutdown

2. 如果在初始化複本組出現這樣的錯誤,請確定你的mongod有沒有正常啟動,或是被防火牆擋住了

> rs.initiate(cfg);

{ "errmsg" : "couldn't initiate : need all members up to initiate, not ok : 163.17.38.81:28001",   "ok" : 0 }

3. 查看rs的狀況

> db._adminCommand("replSetGetStatus")

如果出現  "errmsg" : "still initializing",就要去檢查錯誤的log,看看你的防火牆是不擋住了。

4. 查看切片狀態,有shards和databases

> db.printShardingStatus();
--- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
        {  "_id" : "sh1",  "host" : "rs1/163.17.38.80:28001,163.17.38.81:28001,163.17.38.84:28001" }
        {  "_id" : "sh2",  "host" : "rs2/163.17.38.81:28002,163.17.38.84:28002" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
        {  "_id" : "test",  "partitioned" : false,  "primary" : "sh1" }

感謝

台中市網路中心陳瑩光提的需求
[3] 這個文章對我的幫助最大,感謝阿里巴巴技術小組無私的提供方法

參考資料

[1] Mongodb http://www.mongodb.org/display/DOCS/Replica+Sets

[2] Replication http://www.mongodb.org/display/DOCS/Replication

[3] 配置mongodb分片群集  http://www.taobaodba.com/html/525_525.html

[4] http://www.elmerzhang.com/2011/03/mongodb-auto-sharding-introduction/

[5] Mongo DB Sharding 心得筆記 (一)  有各單元的解釋和平衡的說明 http://leehom59.blogspot.tw/2011/11/mongo-db-sharding.html


原文 2012-12-10 12:23:09