前言
一直沒搞清楚,Mongodb在三台Cluster Replicate-Set的情況下,到底需不需要Arbiter(兩台Data Node)。
能夠最有效的利用空間的最好的情況下是三台皆為Data Node,這樣我可以壞兩台才會變成Read-Only mode,否則使用Arbiter壞了一台就變成Read-Ony mode了。
問題是,如果三台皆為Data Node,任何一台FAIL,會導致投票失敗,而無法選出PRIMARY嗎?
答案是,可以使用3台皆為Data Node的模式,任何一台Node Fail(PRIMARY or SECONDARY) 都可以找到PRIMARY,完全不需要Arbiter。
MongoDB安裝
感謝此篇文章,但安裝過程中有些問題,因此,我重新寫了整個過程。
http://blog.toright.com/posts/4508/mongodb-replica-set-%E9%AB%98%E5%8F%AF%E7%94%A8%E6%80%A7%E6%9E%B6%E6%A7%8B%E6%90%AD%E5%BB%BA.html
環境
共有三台Server,分別為 mongodb01, mongodb02, mongodb03。
OS: Ubuntu 14.04.2
安裝套件
於三台Servers 安裝mongodb 3.0
sudo apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv 7F0CEB10
echo “deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org --force-yes
MongoDB需要hostname作為識別,因此三台Servers皆需要放置彼此的hostname作為識別。
編輯三台Servers的 /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.16.235.128 mongodb01
172.16.235.148 mongodb02
172.16.235.149 mongodb03
編輯三台Servers
sudo mkdir -p /var/lib/mongodb/rs-a
sudo chown -R mongodb:mongodb /var/lib/mongodb/rs-a
並編輯三台Servers的**/etc/mongod.conf
storage:
dbPath: /var/lib/mongodb/rs-a
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27019
bindIp: 0.0.0.0
restart 三台Servers
service mongod restart
到第一台Server編輯
mongo mongodb01:27019
繼續輸入如下 (第一台Server)
use admin
db.createUser( {
user: "myUserAdmin",
pwd: "<password>",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
});
db.createUser( {
user: "siteRootAdmin",
pwd: "<password>",
roles: [ { role: "root", db: "admin" } ]
});
第一台Server建立Key
openssl rand -base64 741 > /var/lib/mongodb/mongodb-keyfile
scp /var/lib/mongodb/mongodb-keyfile root@mongodb02:/var/lib/mongodb/mongodb-keyfile
scp /var/lib/mongodb/mongodb-keyfile root@mongodb03:/var/lib/mongodb/mongodb-keyfile
到每一台Server執行以下命令
chmod 600 /var/lib/mongodb/mongodb-keyfile
chown mongodb.mongodb /var/lib/mongodb/mongodb-keyfile
於三台Servers,編輯vim /etc/mongod.conf
security:
keyFile: /var/lib/mongodb/mongodb-keyfile
replication:
replSetName: rs-a
於三台Servers執行
sudo service mongod restart
到此MongoDB每一台的環境設定都好了,包含Cluster Key。
設定Cluster
到第一台Server
mongo mongodb01:27019
到第一台Server並執行以下
use admin
db.auth("siteRootAdmin", "<password>");
rs.initiate()
rs.conf()
不要退出,繼續執行
rs.add("mongodb02:27019")
rs.add("mongodb03:27019")
rs.status()
透過rs.status(),你可以查看到這三台Server的狀態,以本次實驗的狀態為
01 | 02 | 03 |
---|---|---|
PRIMARY | SECONDARY | SECONDARY |
如何登入設定並檢查Cluster狀態
進入任何一台Server執行以下,以01為例
mongo mongodb01:27019
use admin
db.auth("siteRootAdmin", "<password>");
rs.status()
Server Fail Over Testing
我測試了幾種Fail over情況藉以了解MongoDB對PRIMARY,SECONDARY,選擇的情況。
以下為測試結果。
status | 01 | 02 | 03 |
---|---|---|---|
X | PRIMARY | SECONDARY | SECONDARY |
FAIL01 | X | PRIMARY | SECONDARY |
BACK01 | SECONDARY | PRIMARY | SECONDARY |
FAIL02 | PRIMARY | X | SECONDARY |
FAIL02 FAIL01 | X | X | SECONDARY |
BACK01 FAIL02 | SECONDARY | X | PRIMARY |
FAIL02 FAIL03 | SECONDARY | X | X |
BACK03 FAIL02 | PRIMARY | X | SECONDARY |
BACK02 | PRIMARY | SECONDARY | SECONDARY |
單台Fail Over實驗
到底需不需要Arbiter來支援,三台MongoDB Servers的環境。
假設01 Fail,02與03會投票決定誰是PRIMARY。 理論上會有1/2的機會會投錯才是(同時投給對方,或投給自己)。
我們透過實驗來瞭解一下,我們每次都關閉PRIMARY,看是否其他兩台會繼承PRIMARY的工作。
最後,我們再啟動關閉的那台Server,在反覆的操作關閉PRIMARY的實驗。
ok表此次實驗,投票有找到PRIMARY。
test | result |
---|---|
1 | ok |
2 | ok |
3 | ok |
4 | ok |
5 | ok |
6 | ok |
7 | ok |
8 | ok |
9 | ok |
10 | ok |
11 | ok |
12 | ok |
在這12次的過程中,有幾次是兩台皆為SECONDARY,再過幾秒後(<10secs),才找到PRIMARY。換句話說,也有幾次一下子就找到PRIMARY。
因此,我猜,投票可能會產生皆為SECONDARY的狀態,但MongoDB會重新處理這樣的狀態,讓PRIMARY順利選出。
所以,答案是,在三台Cluster的情況下,Fail任何一台都可以找到PRIMARY。
當然如果Fail兩台,則剩下的唯一一台一定是SECONDARY(READ-ONLY)。
No comments:
Post a Comment