MongoDB ㄧ Replica Set 建立方法
高可用的必要性
NoSQL 大都有一項蠻特別的特性,被稱為「高可用 (High Availability)」。
何謂高可用?簡單地說,就是一種讓服務(幾乎)永遠不會下線的能力。
用嘴巴說是很簡單啦,但讓一個服務永不下線,背後存在許多問題。比方說下面這些:
- 伺服器會壞,壞了怎麼辦?
- 機房意外停電怎麼辦?
- 硬碟用久會損毀。就算有備份,也需要復原時間。
- 機器會需要定時更新換代,以便追上新一代電腦的規格。比方說硬碟空間可能不足,需要換成更大顆的。
- 軟體需要升級。
總之,不管原因為何,我們幾乎總是會碰到停機,這怎樣也避不開。
高可用的解方
為了一勞永逸地解決所有問題,各家提出的終極方案,大都集中在線上備份之上。
- 首先搞來多台機器,讓他們插電上線
- 所有資料都複製成數份副本,分散在不同的機器裡,並且隨時保持備份被更新到最新狀態
- 這些機器全都同時開機,掛在線上
- 如果一台機器掛了,就向其他機器討要備份
之所以說是「終極方案」的原因,除了它確實能解決問題之外,還因為它很貴。
顯然,為了滿足隨時最少有一份副本可用的高可用性,用戶必須要準備至少 2n 台甚至更多的機器,而且還得讓他們隨時上線燒電,佔用數以倍計的硬碟空間。
MongoDB 的 Replica Set
MongoDB 是 NoSQL 的一種,他也有提供這種高可用性架構。這在 MongoDB 的術語中被稱為 “Replica Set”。
老實說在更早期,MongoDB 還有一種叫作 Master Slave 的架構,不過那種作法已經過時。讀文件時讀到可以不用理它。
以下講講如何在 Linux 機器上起 Replica Set。
因為是測試用途,所以以下直接起在單台機器上。實際上 Replica Set 的多個服務,當然應該要起在不同的系統上面。
起服務 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 無關,隨意就好。
登入
接下來隨意登入一台服務。
mongo localhost:27021
在 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 闖關是行不通的。