MongoDB學習札記第六篇之主從複製

mongo系列文章請看http://www.codefrom.com/p/mongodblinux


環境準備:mongodb

ubuntu12.0.4
mongodb3.0.3shell

主從複製是MongoDB中最多見的複製方式。這種方式很是靈活,可用於備份,故障恢復,讀擴展 等。
本次試驗中,咱們採用一個主節點,一個從節點。
首先先建立master和slave的目錄數據庫

lwb@ubuntu:~$ mkdir -p ~/mongoData/master
lwb@ubuntu:~$ mkdir -p ~/mongoData/slave

建立以後,啓動masterubuntu

lwb@ubuntu:~$ mongod --master --dbpath ~/mongoData/master/ --port 10000

而後再啓動slave安全

lwb@ubuntu:~$ mongod --dbpath  ~/mongoData/slave/ --port 10001 --slave --source localhost:10000

接着,鏈接到master的機器,bash

lwb@ubuntu:~$ mongo --host localhost --port 10000

往test數據庫的users集合裏面插入兩條數據:服務器

> db.users.find()
{ "_id" : ObjectId("55763d98db85929bb8addedf"), "username" : "lwb" }
{ "_id" : ObjectId("55764a694b24187a7a3c6693"), "username" : "mongodb master-slave" }

在master操做完成以後,在鏈接slave的mongodide

lwb@ubuntu:~$ mongo --host localhost --port 10001
MongoDB shell version: 3.0.3
connecting to: localhost:10001/test
Server has startup warnings:
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten]
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/   mm/transparent_hugepage/defrag is 'always'.
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten] **        We suggest set   ting it to 'never'
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten]
>
> show dbs
2015-06-08T19:09:17.770-0700 E QUERY    Error: listDatabases failed:{ "note" : "   from execCommand", "ok" : 0, "errmsg" : "not master" }
    at Error (<anonymous>)
    at Mongo.getDBs (src/mongo/shell/mongo.js:47:15)
    at shellHelper.show (src/mongo/shell/utils.js:630:33)
    at shellHelper (src/mongo/shell/utils.js:524:36)
    at (shellhelp2):1:1 at src/mongo/shell/mongo.js:47
>
> rs.slaveOk()
> 
> show dbs
local  0.078GB
test   0.078GB
>
> use test
switched to db test
> show collections
system.indexes
users
>
> db.users.find()
{ "_id" : ObjectId("55763d98db85929bb8addedf"), "username" : "lwb" }
{ "_id" : ObjectId("55764a694b24187a7a3c6693"), "username" : "mongodb master-slave" }

我遇到的問題及解決方法
問題一:學習

個人主從複製實驗分爲兩次進行,剛開始我配置的master的端口是 10000 ,salve的端口是10001 ; 後由於電腦內存使用率暴漲,90+% 。 因此關掉電腦重啓。問題就出如今這裏,重啓以後,我指定master端口的時候指定爲 27000 , 指定slave端口爲 27001 因此就出現了以下問題:terminating mongod after 30 seconds

2015-06-08T18:11:37.981-0700 I NETWORK  [initandlisten] waiting for connections on port 27001
2015-06-08T18:11:38.975-0700 I REPL     [replslave] repl: --source localhost:27000 != localhost:10000 from local.sources collection
2015-06-08T18:11:38.976-0700 I REPL     [replslave] repl: for instructions on changing this slave's source, see: 2015-06-08T18:11:38.976-0700 I REPL     [replslave] http://dochub.mongodb.org/co re/masterslave
2015-06-08T18:11:38.976-0700 I REPL     [replslave] repl: terminating mongod after 30 seconds
2015-06-08T18:12:08.976-0700 I CONTROL  [replslave] dbexit:  rc: 3

解決方法:
若是仔細觀察日誌的同窗應該會發現:

2015-06-08T18:11:38.975-0700 I REPL     [replslave] repl: --source localhost:27000 != localhost:10000 from local.sources collection

因此,在一開始的時候咱們已經爲slave指定了master的host和port,這個會插入到local.sources 這個集合的。因此,把master端口改爲10000就能夠了。

問題二

主從啓動以後,鏈接slave能夠成功連上,可是在slave中執行 show dbs 的時候就報錯了:

QUERY    Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

解決方法:

在報錯的slave機器上執行 rs.slaveOk()方法便可。

> rs.slaveOk()
> show dbs
local  0.078GB
test   0.078GB
> use test
switched to db test
> show collections
system.indexes
users
> db.users.find()
{ "_id" : ObjectId("55763d98db85929bb8addedf"), "username" : "lwb" }
{ "_id" : ObjectId("55764a694b24187a7a3c6693"), "username" : "mongodb master-sla

具體slaveOk方法是什麼意思?
rs.slaveOk()

Provides a shorthand for the following operation:

db.getMongo().setSlaveOk()
This allows the current connection to allow read operations to run on secondary members. See the readPref() method for more fine-grained control over read preference in the mongo shell.

Master-Slave安全
這個主從安全在 MongoDB官網說的很清楚。不能和普通的mongod權限驗證那樣。這裏除了須要加入 —auth 還須要加入 —keyFile 的驗證。

首先,咱們生成咱們的keyFile,根據官網提供的說明,這個keyfile是能夠任意內容的,只要保證全部集羣中的機器都擁有一樣的文件便可。在linux環境下,咱們經過

openssl rand -base64 741 > /usr/localhsot/mongodb/mongo-keyfile

這條命令來生成咱們的keyFile。 生成以後就能夠在啓動mongod的時候指定了。

首先先啓動 master

root@ubuntu:/usr/local/mongodb# mongod --master --dbpath ~/mongoData/master/ --port 10000 --auth --keyFile /usr/local/mongodb/mongo-keyfile

這裏在啓動的時候可能會遇到一些問題,我是在ubuntu環境下,因此常常操做要sudo,很繁瑣。所以,讓當前用戶得到root權限是頗有必要的。

在命令行模式執行 vi etc/passwd
個人用戶名是 lwb ,因此將lwb所在的行改爲
lwb:x:0:0:Ubuntu12.04,,,:/home/lwb:/bin/bash
原來的值是(將1000 改爲 0 便可): lwb:x:1000:1000:Ubuntu12.04,,,:/home/lwb:/bin/bash
修改完成以後重啓登陸就可讓當前用戶得到root權限了。

回到正題,在生成mongo-keyfile後,並指定keyFile參數來啓動mongod的時候,可能還會遇到另外一個問題:

root@ubuntu:~# mongod --master --dbpath ~/mongoData/master/ --port 10000 --auth --keyFile /usr/local/mongodb/mongo-keyfile
2015-06-08T21:34:43.864-0700 I ACCESS   permissions on /usr/local/mongodb/mongo-keyfile are too open

這個錯誤的意思是說 mongo-keyfile權限太大了,下降一下這個文件的權限。

root@ubuntu:/usr/local/mongodb# chmod 400 mongo-keyfile
root@ubuntu:/usr/local/mongodb# ll
total 84
drwxr-xr-x  4 root root  4096 Jun  8 21:34 ./
drwxr-xr-x 11 root root  4096 Jun  8 16:49 ../
-rw-r--r--  1 root root 34520 Jun  6 07:24 GNU-AGPL-3.0
-rw-r--r--  1 root root  1359 Jun  6 07:24 README
-rw-r--r--  1 root root 22660 Jun  6 07:24 THIRD-PARTY-NOTICES
drwxr-xr-x  2 root root  4096 Jun  6 07:24 bin/
drwxr-xr-x  3 root root  4096 Jun  7 13:02 data/
-r--------  1 root root  1004 Jun  8 21:34 mongo-keyfile

重啓一下mongod便可正常運行。

接着啓動slave

mongod --slave --dbpath ~/mongoData/slave/ --port 10001 --source localhost:10000 --auth --keyFile /usr/local/mongodb/mongo-keyfile

一切都順利的進行着。
使用建立的用戶操做master裏面的數據庫以及集合都是正常的。可是使用一樣的用戶操做slave的時候就有不正常了。仍是提示

QUERY    Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

這個錯誤上面已經提到了。解決方法也是同樣的。 rs.slaveOk() 執行完這條語句以後既能夠正常操做了。

能夠發現,用keyFile的方式啓動mongod服務器其實和日常啓動沒什麼區別,惟一的區別就是在啓動參數中指定了 --keyFile keyfile 而已。

具體怎麼建立用戶參考: MongoDB學習札記第二篇之mongodb安全

Sincerely!
參考

MongoDB權威指南

MongoDB官網Manual手冊

相關文章
相關標籤/搜索