建立 MongoDB 高可用叢集
高可用是什麼?
新世代的 NoSQL 大都有一項蠻特別的特性,被稱為「高可用 (High Availability)」。
何謂高可用?簡單說來就是讓服務(幾乎)永遠不下線的能力。
用嘴巴說是很簡單啦,但讓一個服務永不下線,背後存在許多問題。比方說下面這些:
- 伺服器會壞,壞了怎麼辦?
- 機房意外停電怎麼辦?
- 硬碟用久會損毀。就算有備份,也需要復原時間。
- 機器會需要定時更新換代,以便追上新一代電腦的規格。比方說硬碟空間可能不足,需要換成更大顆的。
- 軟體需要升級的時候怎麼辦。
總之,不管原因為何,我們幾乎總是會碰到停機,這怎樣也避不開。
高可用的解方
為了一勞永逸地解決所有問題,各家提出的終極方案,大都集中在線上備份之上。
- 首先搞來多台機器,讓他們插電上線
- 所有資料都複製成數份副本,分散在不同的機器裡,並且隨時保持備份被更新到最新狀態
- 這些機器全都同時開機,放在線上
- 如果一台機器掛了,就向其他機器討要備份
之所以說是「終極方案」,這除了它確實能解決問題之外,還因為它很貴。想想就知,為了滿足隨時有一份副本可用的可用性,用戶必須要準備至少 2n 台甚至更多的機器,而且還得讓他們隨時上線燒電,並佔用數以倍計的硬碟空間。
MongoDB 的 Replica Set
終於進入今天的正題了
MongoDB 是 NoSQL 的一種,如同其他 NoSQL 他也同樣有提供這種高可用性架構。這在 MongoDB 的術語中被稱為 "Replica Set"。
註:老實說在更早期,MongoDB 還有一種叫作 Master Slave 的副本架構,不過那種作法已經過時。讀文件時讀到可以不用理它。
以下講講如何在 Linux 機器上起 Replica Set。
因為是測試用途,所以以下直接起在單台機器上。實際上 Replica Set 的多個服務,當然應該要起在不同的系統上--畢竟是備份嘛,放在同一台機器上沒啥作用。
1. 起服務 x3
mkdir rs01 -p
mongod --replSet "rs0" --dbpath "rs01" --port 27021 --smallfiles --fork --logpath rs01/log.txt
mkdir rs02 -p
mongod --replSet "rs0" --dbpath "rs02" --port 27022 --smallfiles --fork --logpath rs01/log.txt
mkdir rs03 -p
mongod --replSet "rs0" --dbpath "rs03" --port 27023 --smallfiles --fork --logpath rs01/log.txt
注意關鍵參數是 --replSet
,想要納入同一個 Replica Set 的服務,這個參數必須保持一致。
其他參數與 Replica Set 無關,隨意就好。
2. 登入
接下來隨意登入一台服務。
mongo localhost:27021
3. 在 Mongo Shell 中進行初始化
然後在 Mongo Shell 中輸入以下指令,進行 Replica Set 的初始化:
rs.initiate()
其實這一步可以直接輸入參數,一次到位,不過參數長長一大串怎樣都背不起來,所以不輸入讓它自行產生,之後再修改。小規模佈署時這樣比較方便。
▲ 初始化前沒有任何訊息。
▲ 初始化後的狀況,目前有一個節點。當然那就是自己。
注意上圖中 name
的地方,這也是 Replica Set 彼此的連線網路位置。
然後使用 rs.add()
加入其他機器。
rs.add("mongolab:27022")
rs.add("mongolab:27023")
如此就佈署完成了。相當簡單。有興趣的話可以故意 kill 掉一個服務,看看系統的處理狀況。
特註
上方指令中,我的機器名字叫 mongolab,您得改成您的機器名字。用 localhost 或 127.0.0.1 是行不通的。因為 Replica Set 只有分散佈署在多台不同的機器上時才有實際意義,所以他會判斷,一名用戶如果寫了 localhost 或 127.0.0.1 就是搞錯了狀況,應該要禁止執行。
除此之外,所有機器當然也都要能存取彼此。網路要通 Replica Set 才能順利建立。如果是指定 hostname 而非 ip 的狀況,每台機器也得能解譯全部的 hostnames 才行。
▲ 企圖用 localhost 闖關是行不通的。
以上,謝謝收看!