MongoDB系列-複製集(Replica Set)應用部署(生產、測試、開發環境)

  經過在不一樣的計算機上託管mongod實例來儘量多地保持成員之間的分離。將虛擬機用於生產部署時,應將每一個mongod實例放置在由冗餘電源電路和冗餘網絡路徑提供服務的單獨主機服務器上,並且儘量的將副本集的每一個成員部署到本身的計算機綁定到標準的MongoDB端口27017。
  其中三個成員節點的副本集提供足夠的冗餘以承受大多數網絡分區和其餘系統故障。這些collection集合還具備足夠的容量用於許多分佈式讀取操做。副本集應始終具備奇數個成員。這確保選舉順利進行。mongodb

部署時考慮的問題:shell

  • 創建虛擬專用網絡。確保您的網絡拓撲經過局域網路由單個站點內的成員節點之間的全部流量。
  • 配置訪問控制以防止從未知客戶端到副本集的鏈接。
  • 配置網絡和防火牆規則,以便僅在默認的MongoDB端口上容許傳入和傳出的數據包,而且僅在部署中容許。
  • 確保可經過可解析的DNS或主機名訪問副本集的每一個成員節點。您應該正確配置DNS名稱,或者設置系統的/etc/hosts文件以反映此配置。
  • 每一個成員必須可以鏈接到每一個其餘成員。

NOTE:若是可能,請使用邏輯DNS主機名而不是IP地址,尤爲是在配置副本集成員或分片集羣成員時。邏輯DNS主機名的使用避免了因爲IP地址更改而致使的配置更改。數據庫

生產環境中禁用訪問控制時部署副本集的步驟

  1. IP綁定:使用bind_ip選項可確保MongoDB偵聽來自配置地址上的應用程序的鏈接。在綁定到非本地主機(例如可公開訪問的)IP地址以前,請確保已保護您的羣集免受未經受權的訪問。例如,如下mongod實例綁定到localhost和主機名TestHostname,它與ip地址198.51.100.1相關聯:數組

    mongod --bind_ip localhost,TestHostname
    複製代碼

    要鏈接到此實例,遠程客戶端必須指定主機名或其關聯的IP地址198.51.100.1:服務器

    mongo --host TestHostname
     mongo --host 198.51.100.1
    複製代碼
  2. 建立MongoDB存儲數據文件的目錄,在/etc/mongod.conf中存儲的配置文件或相關位置中指定mongod配置。網絡

  3. 使用適當的選項啓動副本集的每一個成員。對於每一個成員,使用如下設置啓動mongod實例:併發

  • 將replication.replSetName選項設置爲副本集名稱(若是您的應用程序鏈接到多個副本集,則每一個集合應具備不一樣的名稱,某些驅動程序按副本集名稱對副本集進行鏈接)。分佈式

  • 將net.bindIp選項設置爲hostname / ip或逗號分隔的hostnames / ips列表,以及配置部署所需的其餘配置。學習

    如下示例經過--replSet和--bind_ip命令行選項指定副本集名稱和ip綁定:測試

    mongod --replSet "rs0" --bind_ip localhost,<hostname(s)|ip address(es)>
    複製代碼

    對於<hostname(s)| ip address(es)>,指定遠程客戶端(包括副本集的其餘成員)可用於鏈接的mongod實例的主機名和/或IP地址。 或者,也能夠在配置文件中指定副本集名稱和IP地址,要使用配置文件啓動mongod,請使用--config選項指定配置文件的路徑:

    replication:
         replSetName: "rs0"
      net:
         bindIp: localhost,<hostname(s)|ip address(es)>
    
      mongod --config <path-to-config>
    複製代碼
  1. 使用mongo shell鏈接到其中一個mongod實例,從運行其中一個mongod的同一臺機器(在本教程中爲mongodb0.example.net)啓動mongo shell。 要在默認端口27017上鍊接到監聽localhost的mongod,只需指令mongo。

  2. 啓動副本集,僅在副本集的一個且僅一個mongod實例上運行rs.initiate(),如在副本集成員0上運行rs.initiate():

    rs.initiate( {
        _id : "rs0",
        members: [
           { _id: 0, host: "mongodb0.example.net:27017" },
           { _id: 1, host: "mongodb1.example.net:27017" },
           { _id: 2, host: "mongodb2.example.net:27017" }
        ]
     })
    複製代碼
  3. 查看副本集配置,使用rs.conf()顯示副本集配置對象。如副本集配置對象相似於如下內容:

    {
        "_id" : "rs0",
        "version" : 1,
        "protocolVersion" : NumberLong(1),
        "members" : [
       {
          "_id" : 0,
          "host" : "mongodb0.example.net:27017",
          "arbiterOnly" : false,
          "buildIndexes" : true,
          "hidden" : false,
          "priority" : 1,
          "tags" : {
    
          },
          "slaveDelay" : NumberLong(0),
          "votes" : 1
       },
       {
          "_id" : 1,
          "host" : "mongodb1.example.net:27017",
          "arbiterOnly" : false,
          "buildIndexes" : true,
          "hidden" : false,
          "priority" : 1,
          "tags" : {
    
          },
          "slaveDelay" : NumberLong(0),
          "votes" : 1
       },
       {
          "_id" : 2,
          "host" : "mongodb2.example.net:27017",
          "arbiterOnly" : false,
          "buildIndexes" : true,
          "hidden" : false,
          "priority" : 1,
          "tags" : {
    
          },
          "slaveDelay" : NumberLong(0),
          "votes" : 1
       }
    
    ],
    "settings" : {
       "chainingAllowed" : true,
       "heartbeatIntervalMillis" : 2000,
       "heartbeatTimeoutSecs" : 10,
       "electionTimeoutMillis" : 10000,
       "catchUpTimeoutMillis" : -1,
       "getLastErrorModes" : {
    
       },
       "getLastErrorDefaults" : {
          "w" : 1,
          "wtimeout" : 0
       },
       "replicaSetId" : ObjectId("585ab9df685f726db2c6a840")
      }
     }
    複製代碼
  4. 確保副本集具備主副本,使用rs.status()查看複製集的主節點。

測試以及開發環境中複製集的應用部署

在此測試以及開發部署中,三個成員在同一臺計算機上運行。

  1. IP綁定:使用bind_ip選項可確保MongoDB偵聽來自配置地址上的應用程序的鏈接。在綁定到非本地主機(例如可公開訪問的)IP地址以前,請確保已保護您的羣集免受未經受權的訪問。例如,如下mongod實例綁定到localhost和主機名TestHostname,它與ip地址198.51.100.1相關聯:

    mongod --bind_ip localhost,TestHostname
    複製代碼

    要鏈接到此實例,遠程客戶端必須指定主機名或其關聯的IP地址198.51.100.1:

    mongo --host TestHostname
     mongo --host 198.51.100.1
    複製代碼
  2. 經過發出相似於如下內容的命令爲每一個成員建立必要的數據目錄,這將建立名爲「rs0-0」,「rs0-1」和「rs0-2」的目錄,它們將包含實例的數據庫文件,示例以下:

    mkdir -p / srv / mongodb / rs0-0 / srv / mongodb / rs0-1 / srv / mongodb / rs0-2
    複製代碼
  3. 經過發出如下命令在本身的shell窗口中啓動mongod實例:

    //不一樣的三個節點:
     mongod --replSet rs0 --port 27017 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/rs0-0 --smallfiles --oplogSize 128
     mongod --replSet rs0 --port 27018 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/rs0-1 --smallfiles --oplogSize 1284
     mongod --replSet rs0 --port 27019 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/rs0-2 --smallfiles --oplogSize 128
    複製代碼
  • 這將每一個實例做爲名爲rs0的副本集的成員啓動,每一個副本集都在不一樣的端口上運行,並使用--dbpath設置指定數據目錄的路徑。 若是已在使用上述端口,請選擇其餘的端口。
  • 實例綁定到localhost和主機的ip地址。
  • --smallfiles和--oplogSize設置可減小每一個mongod實例使用的磁盤空間。 [1]這是測試和開發部署的理想選擇,由於它能夠防止機器過載。 有關這些和其餘配置選項的更多信息,請參閱<配置文件選項>(docs.mongodb.com/manual/refe…)
  1. 經過mongo shell鏈接到其中一個mongod實例,須要經過指定端口號來指示哪一個實例。 假設選擇第一個,以下面的命令:

    mongo --port 27017
    複製代碼
  2. 在mongo shell中,使用rs.initiate()來啓動副本集,主要是在mongo shell環境中建立副本集配置對象,並用系統的主機名替換,而後將rsconf文件傳遞給rs.initiate(),如如下示例所示:

    rsconf = {
      _id: "rs0",
       members: [
     {
       _id: 0,
       host: "<hostname>:27017"
     },
     {
       _id: 1,
       host: "<hostname>:27018"
     },
     {
       _id: 2,
       host: "<hostname>:27019"
         }
        ]
      }
      rs.initiate( rsconf )
    複製代碼

6.經過發出rs.conf()命令顯示當前副本配置:rs.conf(),使用rs.status()操做隨時檢查副本集的狀態。副本集配置對象相似於如下內容:

{
    "_id" : "rs0",
     "version" : 1,
    "protocolVersion" : NumberLong(1),
    "members" : [
  {
     "_id" : 0,
     "host" : "<hostname>:27017",
     "arbiterOnly" : false,
     "buildIndexes" : true,
     "hidden" : false,
     "priority" : 1,
     "tags" : {

     },
     "slaveDelay" : NumberLong(0),
     "votes" : 1
  },
  {
     "_id" : 1,
     "host" : "<hostname>:27018",
     "arbiterOnly" : false,
     "buildIndexes" : true,
     "hidden" : false,
     "priority" : 1,
     "tags" : {

     },
     "slaveDelay" : NumberLong(0),
     "votes" : 1
  },
  {
     "_id" : 2,
     "host" : "<hostname>:27019",
     "arbiterOnly" : false,
     "buildIndexes" : true,
     "hidden" : false,
     "priority" : 1,
     "tags" : {

     },
     "slaveDelay" : NumberLong(0),
     "votes" : 1
  }
   ],
   "settings" : {
      "chainingAllowed" : true,
      "heartbeatIntervalMillis" : 2000,
      "heartbeatTimeoutSecs" : 10,
      "electionTimeoutMillis" : 10000,
      "catchUpTimeoutMillis" : -1,
      "getLastErrorModes" : {

  },
  "getLastErrorDefaults" : {
     "w" : 1,
     "wtimeout" : 0
  },
  "replicaSetId" : ObjectId("598f630adc9053c6ee6d5f38")
 }
}
複製代碼

仲裁節點添加到副本集

  仲裁節點是mongod實例,它們是副本集的一部分但不保存數據。仲裁節點參加選舉以打破關係。若是副本集具備偶數個成員,請添加仲裁者。
  仲裁節點具備最低的資源要求,不須要專用硬件。您能夠在應用程序服務器或監視主機上部署仲裁程序。不要在也承載副本集的主成員節點或輔助成員節點的系統上運行仲裁程序。
  仲裁節點不存儲數據,可是在將仲裁節點的mongod進程添加到副本集以前,仲裁節點將像任何其餘mongod進程同樣運行並啓動一組數據文件和一個完整大小的日誌。

  1. 爲仲裁節點建立數據目錄(例如storage.dbPath)。 mongod實例使用該目錄進行配置數據。 該目錄不會保存數據集。 例如,建立/ data / arb目錄:

    mkdir /data/arb
    複製代碼
  2. 啓動仲裁節點,指定數據目錄和要加入的副本集的名稱。 如下開始使用/ data / arb做爲dbPath和rs做爲副本集名稱的仲裁:

    mongod --port 27017 --dbpath /data/arb --replSet rs --bind_ip localhost,<hostname(s)|ip address(es)>

  3. 鏈接到主服務器並將仲裁服務器添加到副本集。,使用rs.addArb()方法,如如下示例所示,該示例假定m1.example.net是與仲裁節點的指定ip地址關聯的主機名:

    rs.addArb("m1.example.net:27017")  //此操做添加在m1.example.net主機上的端口27017上運行的仲裁器。
    複製代碼

單實例轉變爲複製集

  將獨立mongod實例轉換爲副本集的過程。使用獨立實例進行測試和開發,但始終在生產中使用副本集。該過程特定於不屬於分片羣集的實例。具體過程以下:

  1. 關閉單實例的mongod。

  2. 重啓實例。 使用--replSet選項指定新副本集的名稱。例如,如下命令將獨立實例做爲名爲rs0的新副本集的成員啓動。 該命令使用獨立的/ srv / mongodb / db0的現有數據庫路徑:

    mongod --port 27017 --dbpath /srv/mongodb/db0 --replSet rs0 --bind_ip localhost,<hostname(s)|ip address(es)>
    複製代碼
  3. 將mongo shell鏈接到mongod實例。

  4. 使用rs.initiate()啓動新的副本集:rs.initiate() 副本集如今能夠運行了。 要查看副本集配置,請使用rs.conf()。 要檢查副本集的狀態,請使用rs.status()。

增長新節點

  副本集最多能夠有七個投票成員。要將成員添加到已有七個投票成員的副本集,您必須將該成員添加爲無投票成員或從現有成員中刪除投票。您可使用這些過程將新成員添加到現有集。您還可使用相同的過程「從新添加」已刪除的成員。若是刪除的成員的數據仍然相對較新,很簡單地恢復。
  若是您有現有成員的備份或快照,則能夠將數據文件(例如dbPath目錄)移動到新系統,並使用它們快速啓動新成員。文件必須是來自同一副本集的成員的數據文件的有效副本。

準備數據目錄

在將新成員添加到現有副本集以前,請使用如下策略之一準備新成員的數據目錄:

  • 確保新成員的數據目錄不包含數據。新成員將複製現有成員的數據。
  • 若是新成員處於恢復狀態,則必須先退出併成爲輔助成員,而後MongoDB才能在複製過程當中複製全部數據。此過程須要時間,但不須要管理員干預。
  • 從現有成員手動複製數據目錄。新成員將成爲輔助成員,並將同步副本集的當前狀態。複製數據可能會縮短新成員成爲最新成員的時間。
  • 確保您能夠將數據目錄複製到新成員,並在oplog容許的窗口內開始複製。不然,新實例必須執行初始同步,這將徹底從新同步數據,如從新同步副本集的成員中所述。
  • 使用rs.printReplicationInfo()檢查副本集成員關於oplog的當前狀態。

具體步驟

  1. 啓動新的mongod實例。 指定數據目錄和副本集名稱。 如下示例指定/ srv / mongodb / db0數據目錄和rs0副本集:

    mongod --dbpath /srv/mongodb/db0 --replSet rs0  --bind_ip localhost,<hostname(s)|ip address(es)>
    複製代碼

    能夠在mongod.conf配置文件中指定數據目錄,副本集名稱和ip綁定,並使用如下命令啓動mongod:

    mongod --config /etc/mongod.conf
    複製代碼
  2. 鏈接到副本集的主節點,只能在鏈接到主節點時添加成員。 若是不知道哪一個成員是主成員節點,請登陸到副本集的任何成員併發出db.isMaster()命令。

  3. 使用rs.add()將新成員添加到副本集。 將成員配置文檔傳遞給方法。 例如,要在主機mongodb3.example.net上添加成員,請發出如下命令:

    rs.add( { host: "mongodb3.example.net:27017", priority: 0, votes: 0 } )
    複製代碼
  4. 確保新成員已達到SECONDARY狀態。 要檢查副本集成員的狀態,請運行rs.status():rs.status()

  5. 一旦新添加的成員轉換爲SECONDARY狀態,請使用rs.reconfig()更新新添加的成員的優先級並根據須要進行投票。例如,若是rs.conf()返回mongodb3.example.net:27017的配置文檔做爲members數組中的第五個元素,要更新其優先級並投票爲1,請使用如下操做序列:

    var cfg = rs.conf();
     cfg.members[4].priority = 1
     cfg.members[4].votes = 1
     rs.reconfig(cfg)
    複製代碼

NOTE:當新添加的輔助節點的投票和優先級設置大於零時,在其初始同步期間,輔助節點仍然計爲投票成員,即便它不能提供讀取也不能成爲主節點,由於其數據還沒有一致。這可能致使大多數投票成員在線但不能選出主要成員的狀況。 要避免這種狀況,請考慮最初添加新的輔助優先級:0和投票:0。 而後,一旦成員轉換到SECONDARY狀態,使用rs.reconfig()更新其優先級和投票。

移除節點

使用rs.remove()移除過程

  1. 關閉要刪除的成員的mongod實例。 要關閉實例,請使用mongo shell和db.shutdownServer()方法進行鏈接。

  2. 鏈接到副本集的當前主節點。 要肯定當前主節點,請在鏈接到副本集的任何成員時使用db.isMaster()。

  3. 使用如下任一形式的rs.remove()刪除該成員:

    rs.remove( 「mongod3.example.net:27017」) rs.remove( 「mongod3.example.net」) NOTE:若是副本集須要選擇新的主節點,MongoDB可能會短暫地斷開shell。 在這種狀況下,shell會自動從新鏈接。 即便命令成功,shell也可能顯示DBClientCursor :: init call()失敗錯誤。

使用rs.reconfig()移除過程

  1. 關閉要刪除的成員的mongod實例。 要關閉實例,請使用mongo shell和db.shutdownServer()方法進行鏈接。

  2. 鏈接到副本集的當前主節點。 要肯定當前主節點,請在鏈接到副本集的任何成員時使用db.isMaster()。

  3. 發出rs.conf()方法以查看當前配置文檔並肯定要刪除的成員的成員數組中的位置,示例mongod_C.example.net位於如下配置文件的第2位:

    {
     "_id" : "rs",
     "version" : 7,
     "members" : [
         {
             "_id" : 0,
             "host" : "mongod_A.example.net:27017"
         },
         {
             "_id" : 1,
             "host" : "mongod_B.example.net:27017"
         },
         {
             "_id" : 2,
             "host" : "mongod_C.example.net:27017"
         }
     ]
    複製代碼

    }

  4. 將當前配置文檔分配給變量cfg,修改cfg對象以刪除該成員,並重啓新配置,示例以下:

    cfg = rs.conf()
     cfg.members.splice(2,1)
     rs.reconfig(cfg)
    複製代碼
  5. 要確認新配置是否生效,請發出rs.conf()。例如,輸出將是:

    {
         "_id" : "rs",
         "version" : 8,
         "members" : [
             {
                 "_id" : 0,
                 "host" : "mongod_A.example.net:27017"
             },
             {
                 "_id" : 1,
                 "host" : "mongod_B.example.net:27017"
             }
         ]
     }
    複製代碼

總結

  後續還有關於實踐中分片的搭建過程,以及分片和複製集原理分析。

最後可關注公衆號,一塊兒學習,天天會分享乾貨,還有學習視頻領取!

相關文章
相關標籤/搜索