MongDB分佈式集羣可以對數據進行備份,提升數據安全性,以及提升集羣提升讀寫服務的能力和數據存儲能力。主要經過副本集(replica)對數據進行備份,經過分片(sharding)對大的數據進行分割,分佈式存儲在不一樣節點上。mongodb
副本集由若干臺服務器組成,分爲三種角色:主服務器、副服務器、仲裁服務器。根據集羣搭建的需求,仲裁服務器不是必需的。主服務器提供主要的對外讀寫的功能,副服務器做爲備份。當主服務器不可用時,其他服務器根據投票選出一個新的主服務器,提供讀寫功能。所以,副本集能夠提升集羣的可用性。數據庫
分片主要是爲減少高數據量和高吞吐量的數據庫應用對單機性能形成的壓力。將大的數據分片存儲在不一樣節點上,外部讀寫只操做相應的一個或一小部分節點,一次減小每一個分片節點村春的數據量和處理的請求數 。安全
其中每一個分片是一個副本集,副本集的結構以下圖 服務器
注意:在生產環境中,配置服務器務必使用三個,而不是一個;每一個分片節點都部署成副本集,而不是一個單獨的Mongo服務器架構
配置文件用於在啓動mongod時加載配置,也可使用該命令行啓動項,不過配置項不少的時候,命令行參數不少。因此應該把配置項都寫到配置文件中。每一個節點都有一個配置文件。app
配置文件主要包括如下配置項:分佈式
如下以部署一個有三個節點(一個primary,一個secondary, 一個arbiter)1rs0的副本集爲例,並假設三個節點的hostname是:hostname_primary:1111, hostname_secondary:2222, hostname_arbiter:3333。其中端口號按需求定;另外,假設三個節點配置文件的路徑分別爲:config_path_primary, config_path_secondary, config_path_arbiter。此時,配置文件中不該該設置keyFile和auth兩個配置項
replSet配置項應該設置爲rs0,不然在下面的步驟中會遇到下面的錯誤函數
{ "ok" : 0, "errmsg" : "Attempting to initiate a replica set with name rs0, but command line reports rs1; rejecting", "code" : 93 }
部署步驟:性能
1.啓動三個節點ui
mongod -f config_path_primary mongod -f config_path_secondary mongod -f config_path_arbiter
2.在primary節點所在的機器登錄上primary節點
mongo --port 1111
3.初始化
rs.initiate({_id : "rs0", members : [{_id : 0, host : "hostname_primary:1111"}]})
結果應該以下
{"ok" : 1}
4.添加secondary節點
rs.add("hostname_secondary:2222")
結果以下
{"ok" : 1}
5.添加仲裁節點
rs.addArb("hostname_arbiter:3333")
結果仍是以下:
{"ok" : 1}
到了這裏,一個三個節點的副本集rs0就部署好了^-^,若是須要部署更多節點,執行步驟4。
如今運行
rs.conf()
能夠看到以下結果:
{ "_id" : "rs1", "version" : 3, "members" : [ { "_id" : 0, "host" : "localhost:4094", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 1, "host" : "localhost:4095", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 2, "host" : "localhost:4096", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatTimeoutSecs" : 10, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } } }
分片部署就是要將幾個不一樣的副本集聯繫起來。如今部署一個有三個配置服務器,一個mongos,一個分片的集羣。
1.部署配置服務器,三個配置服務器的配置文件分別爲:配置服務器也是mongod實例,因此須要在配置文件中指示其做爲配置服務器運行,加上選項
configsvr=true
不該該有選項
replSet=rs0
由於它不是做爲副本集的節點運行。
設三個配置服務器的hostname分別爲: hostname_config_1, hostname_config_2, hostname_config_3,端口分別爲:4444, 5555, 6666
啓動三個配置服務器:
mongod -f config_path_conf1 mongod -f config_path_conf2 mongod -f config_path_conf3
2.部署mongos服務器,設其hostname爲host_name_mongos,端口爲8888。其配置文件路徑爲config_path_mongos,因爲mongos不存儲數據,因此不須要dbpath 選項。同時因爲mongos要從配置服務器上獲取集羣的配置信息,因此須要制定配置服務器的hostname和端口,加上選項configdb
configdb = hostname_config_1:4444, hostname_config_2 : 5555, hostname_config_3 : 6666
啓動mongos服務器
mongos -f config_path_mongos
注意這裏是mongos,不是mongod。不是我打錯字了!
3.在mongos所在機器登錄mongos服務器
mongo –port 8888
此時,運行
sh.status()
你會發現,shards一項裏什麼都沒有,這是由於咱們尚未給這個集羣加分片。
4.添加rs0成爲集羣的分片
sh.addShard("rs0/hostname_primary:1111")
這裏括號裏面只須要是副本集名加上一個副本集中的成員便可,不必定要是primary節點。如:
sh.addShard("rs0/hostname_secondary:2222") sh.addShard("rs0/hostname_arbiter:3333")
也是能夠的。若是獲得以下結果:
{「shardAdded」 : 「rs1」, 「ok」 : 1}
那麼添加分片節點成功了。如今再運行
sh.status()
獲得的結果爲
sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("559f7fc9d8cec40f5a0f7609") } shards: { "_id" : "rs0", "host" : "rs0/hostname_primary:1111,hostname_secondary:2222" } balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" }
shards不爲空了,rs成爲了一個shard節點
權限認證是很是重要的,生產環境中的集羣必需有權限認證,並且須要比較嚴格的權限認證。
1.建立第一個用戶
在上面部署成功的集羣上執行如下步驟,在數據庫admin中建立第一個具備最高root權限的用戶root:
use admin db.createUser({user : "root", pwd : "q,.wemr213oiz923*(*LNY", roles : [{role : "root", db : "admin"}]})
2.關閉全部上面部署的節點,能夠用
db.shutdownServer()
也能夠暴力kill
3.產生keyFile,並複製到每一個運行集羣節點的服務器上。
openssl rand -base64 741 > mongodb-keyfile chmod 600 mongodb-keyfile
4.在每一個節點的配置文件中加上選項:
keyFile = <key_file_path>
5.在出mongos外的全部節點的配置文件中加上選項
auth = true
6.重啓全部節點,到此權限認證已經搞完了,如今就能夠插入數據庫,並按需求添加用戶,賦予相應的權限。進行認證受權的函數爲db.auth(), 例如:
db.auth("root", "<password>")
此時擁有root權限,能夠進行一切操做。