mongodb複製集搭建

注:mongodb當前版本是3.4.3html

1.準備三個虛擬機作服務器

192.168.168.129:27017
192.168.168.130:27017
192.168.168.131:27017node

2.在三臺服務器上安裝mongodb服務

 詳細請見linux安裝mongodb(設置非root用戶和開機啓動)linux

3.修改配置,在mongodb.conf增長replSet配置,而後啓動服務便可

三個服務器的mongodb.conf中都須要加入replSet的指定,它們都屬於repl1複製集;

replSet中的S必定要大寫!mongodb

4.初始化複製集

登入任意一臺機器的mongodb執行,由於是全新的複製集,因此能夠任意進入一臺執行;要是一臺有數據,則須要在有數據上執行;要多臺有數據則不能初始化。


rs.initiate({_id:'repl1',members:[{_id:1,host:'192.168.168.129:27017'}]})
初始化參數說明:
_id:複製集名稱(第一個_id)
members:複製集服務器列表
_id:服務器的惟一ID(數組裏_id)
host:服務器主機
咱們操做的是192.168.168.129服務器,其中repl1便是複製集名稱,和mongodb.conf中保持一致,初始化複製集的第一個服務器將會成爲主複製集shell

經過rs.status()查看複製集狀態能夠看到,192.168.168.129:27017已被自動分配爲primary主複製集了

5.由主複製集添加從複製集


rs.add('192.168.168.130:27017'),增長192.168.168.130爲從節點,第一次執行add時報了一個錯,這個錯說的是找到192.168.168.130服務,是由於防火牆的緣由,咱們把192.168.168.130防火牆關掉(service iptables stop),當第二次執行add的時候就成功了。

注:爲了保證複製集中三個服務器之間正常鏈接,請保證三個服務器的防火牆都已關閉!數組

能夠看到192.168.168.130:27017成爲了secondary節點

6.由主複製集添加仲裁複製集


rs.addArb('192.168.168.131:27017')

能夠看到192.168.168.131:27017成爲了arbiter節點

7.測試複製集secondary節點數據複製功能

在primary(192.168.168.129:27017)上插入數據:服務器

  1. repl1:PRIMARY> db
  2. test
  3. repl1:PRIMARY> show collections
  4. repl1:PRIMARY>for(var i =0; i <4; i ++){db.user.insert({userName:'gxt'+i,age:i})}
  5. WriteResult({"nInserted":1})
  6. repl1:PRIMARY> show collections
  7. user
  8. repl1:PRIMARY> db.user.find()
  9. {"_id":ObjectId("5912e308e5c3987e4a8131e2"),"userName":"gxt0","age":0}
  10. {"_id":ObjectId("5912e308e5c3987e4a8131e3"),"userName":"gxt1","age":1}
  11. {"_id":ObjectId("5912e308e5c3987e4a8131e4"),"userName":"gxt2","age":2}
  12. {"_id":ObjectId("5912e308e5c3987e4a8131e5"),"userName":"gxt3","age":3}
  13. repl1:PRIMARY>

在secondary上查看是否已經同步:socket

  1. repl1:SECONDARY> db
  2. test
  3. repl1:SECONDARY> show collections
  4. 2017-05-10T03:14:54.665-0700 E QUERY [thread1]Error: listCollections failed:{
  5. "ok":0,
  6. "errmsg":"not master and slaveOk=false",
  7. "code":13435,
  8. "codeName":"NotMasterNoSlaveOk"
  9. }:
  10. _getErrorWithCode@src/mongo/shell/utils.js:25:13
  11. DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:805:1
  12. DB.prototype.getCollectionInfos@src/mongo/shell/db.js:817:19
  13. DB.prototype.getCollectionNames@src/mongo/shell/db.js:828:16
  14. shellHelper.show@src/mongo/shell/utils.js:762:9
  15. shellHelper@src/mongo/shell/utils.js:659:15
  16. @(shellhelp2):1:1
  17. repl1:SECONDARY> rs.slaveOk()
  18. repl1:SECONDARY> show collections
  19. user
  20. repl1:SECONDARY> db.user.find()
  21. {"_id":ObjectId("5912e308e5c3987e4a8131e2"),"userName":"gxt0","age":0}
  22. {"_id":ObjectId("5912e308e5c3987e4a8131e3"),"userName":"gxt1","age":1}
  23. {"_id":ObjectId("5912e308e5c3987e4a8131e4"),"userName":"gxt2","age":2}
  24. {"_id":ObjectId("5912e308e5c3987e4a8131e5"),"userName":"gxt3","age":3}
  25. repl1:SECONDARY>

經過db.user.find()查詢到和主複製集上同樣的數據,表示數據同步成功!測試

"errmsg" : "not master and slaveOk=false"錯誤說明:由於secondary是不容許讀寫的,若是非要解決,則執行:rs.slaveOk()

在arbiter上查看是否會有數據同步:spa

  1. repl1:ARBITER> db
  2. test
  3. repl1:ARBITER> show collections
  4. 2017-05-10T03:22:02.554-0700 E QUERY [thread1]Error: listCollections failed:{
  5. "ok":0,
  6. "errmsg":"not master and slaveOk=false",
  7. "code":13435,
  8. "codeName":"NotMasterNoSlaveOk"
  9. }:
  10. _getErrorWithCode@src/mongo/shell/utils.js:25:13
  11. DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:805:1
  12. DB.prototype.getCollectionInfos@src/mongo/shell/db.js:817:19
  13. DB.prototype.getCollectionNames@src/mongo/shell/db.js:828:16
  14. shellHelper.show@src/mongo/shell/utils.js:762:9
  15. shellHelper@src/mongo/shell/utils.js:659:15
  16. @(shellhelp2):1:1
  17. repl1:ARBITER> rs.slaveOk()
  18. repl1:ARBITER> show collections
  19. repl1:ARBITER> db.user.find()
  20. Error: error:{
  21. "ok":0,
  22. "errmsg":"node is not in primary or recovering state",
  23. "code":13436,
  24. "codeName":"NotMasterOrSecondary"
  25. }
  26. repl1:ARBITER>

咱們能夠看到,arbiter並無進行數據同步,由於仲裁節點只參與投票,不接收數據!

8.測試複製集主從節點故障轉移功能

關閉primary節點,查看其它兩個節點的狀況:

  1. repl1:PRIMARY>use admin
  2. switched to db admin
  3. repl1:PRIMARY> db.shutdownServer()
  4. server should be down...
  5. 2017-05-10T03:27:04.162-0700 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017(127.0.0.1) failed
  6. 2017-05-10T03:27:04.207-0700 I NETWORK [thread1]Socket recv()Connection reset by peer 127.0.0.1:27017
  7. 2017-05-10T03:27:04.208-0700 I NETWORK [thread1]SocketException: remote:(NONE):0 error:9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]
  8. 2017-05-10T03:27:04.208-0700 I NETWORK [thread1] reconnect 127.0.0.1:27017(127.0.0.1) failed failed
  9. >

咱們能夠看到192.168.168.130:27017從secondary變成了primary,故障轉移成功!不過如今這個複製集已沒有能夠同步數據的從節點了,但咱們能夠把192.168.168.129:27017從新啓動,這時129會變成secondary,這樣這個複製集就能夠正常工做了。

9.複製集經常使用方法總結

rs.initiate():複製集初始化,例如:rs.initiate({_id:'repl1',members:[{_id:1,host:'192.168.168.129:27017'}]})
rs.reconfig():從新加載配置文件,例如:

  1. rs.reconfig({_id:'repl1',members:[{_id:1,host:'192.168.168.129:27017'}]},{force:true})當只剩下一個secondary節點時,複製集變得不可用,則能夠指定force屬性強制將節點變成primary,而後再添加secondary節點

rs.status():查看複製集狀態
db.printSlaveReplicationInfo():查看複製狀況
rs.conf()/rs.config():查看複製集配置
rs.slaveOk():在當前鏈接讓secondary能夠提供讀操做
rs.add():增長複製集節點,例如:

  1. rs.add('192.168.168.130:27017')
  2. rs.add({"_id":3,"host":"192.168.168.130:27017","priority":0,"hidden":true})指定hidden屬性添加備份節點
  3. rs.add({"_id":3,"host":"192.168.168.130:27017","priority":0,"slaveDelay":60})指定slaveDelay屬性添加延遲節點
  4. priority:是優先級,默認爲1,若是想手動指定某個節點爲primary節點,則把對應節點的priority屬性設置爲全部節點中最大的一個便可

rs.remove():刪除複製集節點,例如:rs.remove('192.168.168.130:27017')
rs.addArb():添加仲裁節點,例如:

  1. rs.addArb('192.168.168.131:27017')或者rs.add({"_id":3,"host":"192.168.168.130:27017","arbiterOnly":true}),仲裁節點,只參與投票,不接收數據

屬性說明:

相關文章
相關標籤/搜索