搭建高可用MongoDB叢集(二): 副本集

發表於2014-07-02

在上一篇文章《搭建高可用MongoDB叢集(一)——配置MongoDB》 提到了幾個問題還沒有解決。

  • 主節點掛了能否自動切換連線?目前需要手工切換。
  • 主節點的讀寫壓力過大如何解決?
  • 從節點每個上面的資料都是對資料庫全量拷貝,從節點壓力會不會過大?
  • 資料壓力大到機器支撐不了的時候能否做到自動擴充套件?

這篇文章看完這些問題就可以搞定了。NoSQL的產生就是為了解決大資料量、高擴充套件性、高效能、靈活資料模型、高可用性。但是光通過主從模式的架構遠遠達不到上面幾點,由此MongoDB設計了副本集和分片的功能。這篇文章主要介紹副本集

mongoDB官方已經不建議使用主從模式了,替代方案是採用副本集的模式,點選檢視 ,如圖:

mongorep1

 

那什麼是副本集呢?打魔獸世界總說打副本,其實這兩個概念差不多一個意思。遊戲裡的副本是指玩家集中在高峰時間去一個場景打怪,會出現玩家暴多怪物少的情況,遊戲開發商為了保證玩家的體驗度,就為每一批玩家單獨開放一個同樣的空間同樣的數量的怪物,這一個複製的場景就是一個副本,不管有多少個玩家各自在各自的副本里玩不會互相影響。 mongoDB的副本也是這個,主從模式其實就是一個單副本的應用,沒有很好的擴充套件性和容錯性。而副本集具有多個副本保證了容錯性,就算一個副本掛掉了還有很多副本存在,並且解決了上面第一個問題“主節點掛掉了,整個叢集內會自動切換”。難怪mongoDB官方推薦使用這種模式。我們來看看mongoDB副本集的架構圖:

mongorep2 (1)

 

由圖可以看到客戶端連線到整個副本集,不關心具體哪一臺機器是否掛掉。主伺服器負責整個副本集的讀寫,副本集定期同步資料備份,一但主節點掛掉,副本節點就會選舉一個新的主伺服器,這一切對於應用伺服器不需要關心。我們看一下主伺服器掛掉後的架構:mongorep3

副本集中的副本節點在主節點掛掉後通過心跳機制檢測到後,就會在叢集內發起主節點的選舉機制,自動選舉一位新的主伺服器。看起來很牛X的樣子,我們趕緊操作部署一下!
官方推薦的副本集機器數量為至少3個,那我們也按照這個數量配置測試。

1、準備兩臺機器 192.168.1.136、192.168.1.137、192.168.1.138。 192.168.1.136 當作副本集主節點,192.168.1.137、192.168.1.138作為副本集副本節點

2、分別在每臺機器上建立mongodb副本集測試資料夾

3、下載mongodb的安裝程式包

1
wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.8.tgz

注意linux生產環境不能安裝32位的mongodb,因為32位受限於作業系統最大2G的檔案限制。

mongorep4

 

4、分別在每臺機器上啟動mongodb

可以看到控制檯上顯示副本集還沒有配置初始化資訊。

5、初始化副本集

在三臺機器上任意一臺機器登陸mongodb

#定義副本集配置變數,這裡的 _id:”repset” 和上面命令引數“ –replSet repset” 要保持一樣。

#輸出

#輸出成功

#檢視日誌,副本集啟動成功後,138為主節點PRIMARY,136、137為副本節點SECONDARY

#輸出

整個副本集已經搭建成功了。

6、測試副本集資料複製功能

#輸出

7、測試副本集故障轉移功能

先停掉主節點mongodb 138,檢視136、137的日誌可以看到經過一系列的投票選擇操作,137 當選主節點,136從137同步資料過來。

檢視整個叢集的狀態,可以看到138為狀態不可達。

#輸出

再啟動原來的主節點 138,發現138 變為 SECONDARY,還是137 為主節點 PRIMARY。

8、java程式連線副本集測試。三個節點有一個節點掛掉也不會影響應用程式客戶端對整個副本集的讀寫!

目前看起來支援完美的故障轉移了,這個架構是不是比較完美了?其實還有很多地方可以優化,比如開頭的第二個問題:主節點的讀寫壓力過大如何解決?常見的解決方案是讀寫分離,mongodb副本集的讀寫分離如何做呢?

看圖說話:mongorep5

常規寫操作來說並沒有讀操作多,所以一臺主節點負責寫,兩臺副本節點負責讀。

1、設定讀寫分離需要先在副本節點SECONDARY 設定 setSlaveOk。
2、在程式中設定副本節點負責讀操作,如下程式碼:

讀引數除了secondary一共還有五個引數:primary、primaryPreferred、secondary、secondaryPreferred、nearest。

mongorep6

primary:預設引數,只從主節點上進行讀取操作;
primaryPreferred:大部分從主節點上讀取資料,只有主節點不可用時從secondary節點讀取資料。
secondary:只從secondary節點上進行讀取操作,存在的問題是secondary節點的資料會比primary節點資料“舊”。
secondaryPreferred:優先從secondary節點進行讀取操作,secondary節點不可用時從主節點讀取資料;
nearest:不管是主節點、secondary節點,從網路延遲最低的節點上讀取資料。

好,讀寫分離做好我們可以資料分流,減輕壓力解決了“主節點的讀寫壓力過大如何解決?”這個問題。不過當我們的副本節點增多時,主節點的複製壓力會加大有什麼辦法解決嗎?mongodb早就有了相應的解決方案。

看圖:

mongorep7

其中的仲裁節點不儲存資料,只是負責故障轉移的群體投票,這樣就少了資料複製的壓力。是不是想得很周到啊,一看mongodb的開發兄弟熟知大資料架構體系,其實不只是主節點、副本節點、仲裁節點,還有Secondary-Only、Hidden、Delayed、Non-Voting。

Secondary-Only:不能成為primary節點,只能作為secondary副本節點,防止一些效能不高的節點成為主節點。
Hidden:這類節點是不能夠被客戶端制定IP引用,也不能被設定為主節點,但是可以投票,一般用於備份資料。
Delayed:可以指定一個時間延遲從primary節點同步資料。主要用於備份資料,如果實時同步,誤刪除資料馬上同步到從節點,恢復又恢復不了。
Non-Voting:沒有選舉權的secondary節點,純粹的備份資料節點。

到此整個mongodb副本集搞定了兩個問題:

  • 主節點掛了能否自動切換連線?目前需要手工切換。
  • 主節點的讀寫壓力過大如何解決?

還有這兩個問題後續解決:

  • 從節點每個上面的資料都是對資料庫全量拷貝,從節點壓力會不會過大?
  • 資料壓力大到機器支撐不了的時候能否做到自動擴充套件?

做了副本集發現又一些問題:

  • 副本集故障轉移,主節點是如何選舉的?能否手動干涉下架某一臺主節點。
  • 官方說副本集數量最好是奇數,為什麼?
  • mongodb副本集是如何同步的?如果同步不及時會出現什麼情況?會不會出現不一致性?
  • mongodb的故障轉移會不會無故自動發生?什麼條件會觸發?頻繁觸發可能會帶來系統負載加重

 

 

 

相關文章