Background

MongoDB handles replication through an implementation called "replication sets". Replication sets in their basic form are somewhat similar to nodes in a master-slave configuration. A single primary member is used as the base for applying changes to secondary members.

在 MongoDB 的 Replication Sets中以下兩種角色:

  • Primary member: The primary member is the default access point for transactions with the replication set. It is the only member that can accept write operations.

  • Secondary members: A replication set can contain multiple secondary members. Secondary members reproduce changes from the oplog on their own data.

那整個 Replication Sets 還有幾種特色

  • Single Primary at any given time.

  • Write operations have to go to the primary, read doesn't.

  • When primary is down, you can't do any write operations. Primary is down的情況下會從Secondary members中選出一台當作Primary)

  • MongoDB doesn't offer eventual consistency in default. (所以必須要考慮清楚你要在MonogDB上運用何種服務)

Setting

Set Up DNS Resolution

$ sudo vim /etc/hosts

加入三台MongoDB Server的ip位置

127.0.0.1           localhost
123.456.789.111     mongo0
123.456.789.222     mongo1
123.456.789.333     mongo2

Create a new directory for storing data

建立一個讓 Replica Set 專用的全新資料庫目錄, 記得三台都要設定

$ sudo mkdir -p /var/lib/mongodb-rs
$ sudo chown -R mongodb:mongodb /var/lib/mongodb-rs

Set config file

設定 Replica Set 服務的 Mongod 設定檔

mongod.conf

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb-rs
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0

啟動MongoDB

$ sudo service mongod start
$ mongo mongo0 # 連到第一台做設定
use admin
db.createUser( {
    user: "myUserAdmin",
    pwd: "<password>",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  });
db.createUser( {
    user: "siteRootAdmin",
    pwd: "<password>",
    roles: [ { role: "root", db: "admin" } ]
  });

Security (Optional)

建立一個 Key,並且複製到每一台機器,之後每個 Mongod 實體會透過這把 Key 進行資料同步.

$ openssl rand -base64 741 > /var/lib/mongodb/mongodb-keyfile
$ chmod 600 /var/lib/mongodb/mongodb-keyfile
$ chown mongodb.mongodb /var/lib/mongodb/mongodb-keyfile

# copy to other machines, and remember u need to login to other machines and modify the privilege of the key
$ scp /var/lib/mongodb/mongodb-keyfile USER@mongo1:/home/USER
$ scp /var/lib/mongodb/mongodb-keyfile USER@mongo2:/home/USER

接著再更新 mongod.conf (三台都要), 多了security&replication

$ sudo vim /etc/mongod.conf

$ mongod.conf

# mongod.conf
# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb-rs
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
#processManagement:
security:
  keyFile: /var/lib/mongodb/mongodb-keyfile
#operationProfiling:
replication:
  replSetName: rs0

接著在重啟mongo(三台都要, 並且確定都能從local端連線)

$ sudo service mongod restart

Replica Set

連到第一台server

$ mongo mongo0
use admin
db.auth("siteRootAdmin", "<password>");
rs.initiate()
rs.conf()
# add new server into replication
rs.add("mongo1:27017")
rs.add("mongo2:27017")
rs.status()

最後可以透過 rs.status() 查看 Replica Set 設定狀態. 你會看到members裡面有三台機器就代表你設定成功了.

Reference