Friday, March 11, 2016

Shall we need Mongodb Arbiter in 3 nodes MongoDB cluster (Replca-Set)

mongodb3nodesrep

前言

一直沒搞清楚,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