高可用的MongoDB集羣【轉】

剛接觸MongoDB,就要用到它的集羣,只能硬着頭皮短期去看文檔和嘗試自行搭建。遷移歷史數據更是讓人惱火,近100G的數據文件,導入、清理垃圾數據執行的速度蝸牛同樣的慢。趁着這個時間,把這幾天關於Mongod集羣相關的內容整理一下。大概介紹一下MongoDB集羣的幾種方式:Master-Slave、Relica Set、Sharding,並作簡單的演示。css

使用集羣的目的就是提升可用性。高可用性H.A.(High Availability)指的是經過儘可能縮短因平常維護操做(計劃)和突發的系統崩潰(非計劃)所致使的停機時間,以提升系統和應用的可用性。它與被認爲是不間斷操做的容錯技術有所不一樣。HA系統是目前企業防止核心計算機系統因故障停機的最有效手段。node

HA的三種工做方式:mongodb

  • 主從方式 (非對稱方式)數據庫

    工做原理:主機工做,備機處於監控準備情況;當主機宕機時,備機接管主機的一切工做,待主機恢復正常後,按使用者的設定以自動或手動方式將服務切換到主機上運行,數據的一致性經過共享存儲系統解決。json

  • 雙機雙工方式(互備互援)bash

    工做原理:兩臺主機同時運行各自的服務工做且相互監測狀況,當任一臺主機宕機時,另外一臺主機當即接管它的一切工做,保證工做實時,應用服務系統的關鍵數據存放在共享存儲系統中。服務器

  • 集羣工做方式(多服務器互備方式)markdown

    工做原理:多臺主機一塊兒工做,各自運行一個或幾個服務,各爲服務定義一個或多個備用主機,當某個主機故障時,運行在其上的服務就能夠被其它主機接管架構

<!--more-->mongoose

主從架構(Master-Slave)


Mater-Slaves

主從架構通常用於備份或者作讀寫分離。由兩種角色構成:

  • 主(Master)

    可讀可寫,當數據有修改的時候,會將oplog同步到全部鏈接的salve上去。

  • 從(Slave)

    只讀不可寫,自動從Master同步數據。

特別的,對於Mongodb來講,並不推薦使用Master-Slave架構,由於Master-Slave其中Master宕機後不能自動恢復,推薦使用Replica Set,後面會有介紹,除非Replica的節點數超過50,才須要使用Master-Slave架構,正常狀況是不可能用那麼多節點的。

還有一點,Master-Slave不支持鏈式結構,Slave只能直接鏈接Master。Redis的Master-Slave支持鏈式結構,Slave能夠鏈接Slave,成爲Slave的Slave。

下面演示一下搭建過程:

1>. 啓動Master

mongod --port 2000 --master --dbpath masterdb/

2>. 啓動Slave

mongod --port 2001 --slave --source 127.0.0.1:2000 --dbpath slavedb/

3>. 給Master裏面導入數據,查看Master和Slave的數據。你會發現導入Master的數據同時也會在Slave中出現。

mongoimport --port 2000 -d test -c dataset dataset.json
mongo --port 2000 test db.dataset.count() > 25359
mongo --port 2001 test db.dataset.count() > 25359

4>. 試一下Master和Slave的寫操做。你會發現,只有Master才能夠對數據進行修改,Slave修改時候會報錯。

mongo --port 2001 test db.dataset.drop() > Error: drop failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" } mongoimport --port 2001 -d test -c dataset dataset.json > Failed: error checking connected node type: no reachable servers

副本集架構(Replica Set)

爲了防止單點故障就須要引副本(Replication),當發生硬件故障或者其它緣由形成的宕機時,可使用副本進行恢復,最好可以自動的故障轉移(failover)。有時引入副本是爲了讀寫分離,將讀的請求分流到副本上,減輕主(Primary)的讀壓力。而Mongodb的Replica Set都能知足這些要求。

Replica Set的一堆mongod的實例集合,它們有着一樣的數據內容。包含三類角色:

  • 主節點(Primary)

    接收全部的寫請求,而後把修改同步到全部Secondary。一個Replica Set只能有一個Primary節點,當Primar掛掉後,其餘Secondary或者Arbiter節點會從新選舉出來一個主節點。默認讀請求也是發到Primary節點處理的,須要轉發到Secondary須要客戶端修改一下鏈接配置。

  • 副本節點(Secondary)

    與主節點保持一樣的數據集。當主節點掛掉的時候,參與選主。

  • 仲裁者(Arbiter)

    不保有數據,不參與選主,只進行選主投票。使用Arbiter能夠減輕數據存儲的硬件需求,Arbiter跑起來幾乎沒什麼大的硬件資源需求,但重要的一點是,在生產環境下它和其餘數據節點不要部署在同一臺機器上。

注意,一個自動failover的Replica Set節點數必須爲奇數,目的是選主投票的時候要有一個大多數才能進行選主決策。

應用客戶端

客戶端鏈接單個mongod和副本集的操做是相同,只須要配置好鏈接選項便可,好比下面是node.js鏈接Replica Set的方式:

mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);
Primary和Secondary搭建的Replica Set

Primary和Secondary搭建的Replica Set

奇數個數據節點構成的Replica Set,下面演示精典的3個數據節點的搭建過程。

1> 啓動3個數據節點,--relSet指定同一個副本集的名字

mongod --port 2001 --dbpath rs0-1 --replSet rs0
mongod --port 2002 --dbpath rs0-2 --replSet rs0
mongod --port 2003 --dbpath rs0-3 --replSet rs0

2> 鏈接到其中一個,配置Replica Set,同時正在執行rs.add的節點被選爲Primary。開發環境中<hostname>指的是機器名,生產環境下就是機器的IP。

mongo --port 2001 rs.initiate() rs.add("<hostname>:2002") rs.add("<hostname>:2003") rs.conf()

3> 鏈接Primary節點,導入數據成功。

mongoimport --port 2001 -d test -c dataset dataset.json mongo --port 2001 test db.dataset.count() > 25359

4> 默認狀況下,Secondary不能讀和寫。

mongo --port 2003 test db.dataset.count() > Error: count failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

注意,其中Secondary宕機,不受影響,若Primary宕機,會進行從新選主:


自動Failover
使用Arbiter搭建Replica Set

偶數個數據節點,加一個Arbiter構成的Replica Set,下面演示精典的2個數據節點加一個仲裁者的搭建過程。
特別的,生產環境中的Arbiter節點,須要修改一下配置:

journal.enabled = false smallFiles = true

使用Arbiter搭建Replica Set

1> 啓動兩個數據節點和一個Arbiter節點

mongod --port 2001 --dbpath rs0-1 --replSet rs0
mongod --port 2002 --dbpath rs0-2 --replSet rs0

mongod --port 2003 --dbpath arb --replSet rs0

2> 鏈接到其中一個,添加Secondary和Arbiter。當僅須要添加Aribiter的時候,只需鏈接當前Replica Set的Primary,而後執行rs.addArb

mongo --port 2001 rs.initiate() rs.add("<hostname>:2002") rs.addArb("<hostname>:2003") rs.conf()

數據分片架構(Sharding)

當數據量比較大的時候,咱們須要把數據分片運行在不一樣的機器中,以下降CPU、內存和IO的壓力,Sharding就是這樣的技術。數據庫主要由兩種方式作Sharding:縱向,橫向,縱向的方式就是添加更多的CPU,內存,磁盤空間等。橫向就是上面說的方式,如圖所示:

MongoDB的Sharding架構:

MongoDB的Sharding架構
MongoDB分片架構中的角色:
  • 數據分片(Shards)

    保存數據,保證數據的高可用性和一致性。能夠是一個單獨的mongod實例,也能夠是一個副本集。在生產環境下Shard是一個Replica Set,以防止該數據片的單點故障。全部Shard中有一個PrimaryShard,裏面包含未進行劃分的數據集合:

  • 查詢路由(Query Routers)

    mongos的實例,客戶端直接鏈接mongos,由mongos把讀寫請求路由到指定的Shard上去。一個Sharding集羣,能夠有一個mongos,也能夠有多mongos以減輕客戶端請求的壓力。

  • 配置服務器(Config servers)

    保存集羣的元數據(metadata),包含各個Shard的路由規則。

搭建一個有2個shard的集羣

1> 啓動兩個數據分片節點。在此僅演示單個mongod的方式,Replica Set相似。

mongod --port 2001 --shardsvr --dbpath shard1/
mongod --port 2002 --shardsvr --dbpath shard2/

2> 啓動配置服務器

mongod --port 3001 --dbpath cfg1/
mongod --port 3002 --dbpath cfg2/
mongod --port 3003 --dbpath cfg3/

3> 啓動查詢路由mongos服務器

mongos --port 5000 --configdb 127.0.0.1:3001,127.0.0.1:3002,127.0.0.1:3003

4> 鏈接mongos,爲集羣添加數據分片節點。

mongo --port 5000 amdmin

sh.addShard("127.0.0.1:2001") sh.addShard("127.0.0.1:2002")

若是Shard是Replica Set,添加Shard的命令:

sh.addShard("rsname/host1:port,host2:port,...") rsname - 副本集的名字

5> 能夠鏈接mongos進行數據操做了。

mongo --port 5000 test mongoimport.exe --port 5000 -d test dataset.json > 25359 `

數據的備份和恢復

MongodDB的備份有多種方式,這裏只簡單介紹一下mongodumpmongorestore的用法。

1> 備份和恢復全部db

mongodump -h IP --port PORT -o BACKUPPATH

mongorestore -h IP --port PORT BACKUPPATH

2> 備份和恢復指定db

mongodump -h IP --port PORT -d DBNAME -o BACKUPPATH mongorestore -h IP --port PORT -d DBNAME BACKUPPATH mongorestore -h IP --port PORT --drop -d DBNAME BACKUPPATH

3> 備份和恢復指定collection

mongodump -h IP --port PORT -d DBNAME -c COLLECTION -o xxx.bson mongorestore -h IP --port PORT -d DBNAME -c COLLECTION xxx.bson mongorestore -h IP --port PORT --drop -d DBNAME -c COLLECTION xxx.bson

小結

MongoDB的集羣能力仍是很強的,搭建還算是簡單。最關鍵的是要明白上面提到的3種架構的原理,才能用的駕輕就熟。固然不限於MongoDB,或許其餘數據庫也多多少少支持相似的架構。

參考資料

轉自

高可用的MongoDB集羣 - 簡書http://www.jianshu.com/p/2825a66d6aed

相關文章
相關標籤/搜索