Replication

ssh 隧道上的 MongoDB 副本集

  • September 14, 2018

我正在嘗試存檔這樣的內容 在此處輸入圖像描述

dc1.com 上的 MongoDB 實例目前是獨立的,並且 On-Site 會定期通過 ssh 隧道上的 mongodump 拉取備份。

我現在想創建兩個實例,一個 On-Site,一個在第二個數據中心,並將這三個實例變成一個副本集,這樣備份幾乎是即時的。這樣,我將有一個現場備份和一個在第二個數據中心,這將始終是最新的。

如果 dc1.com 中的主要 MongoDB 實例失敗,那麼就是這樣,無法提供數據,這將需要手動修復,因為 On-Site 實例和輔助數據中心中的實例不應接管。這兩個也不是要被詢問的。他們在那裡只是作為備份。

我的問題是,當我將 –replSet 添加到主數據庫,然後添加 rs.initialize() 時,該實例不知何故不被辨識為綁定到本地主機,而是綁定到 172.17.0.1,這是 docker 介面,它我需要綁定到,以便容器可以連接到 MongoDB。如果我隨後嘗試通過rs.add("localhost:2001")dc2.com 上的實例添加成員,則會收到有關無法混合 localhost 和非 localhost 數據庫的錯誤。主實例被辨識為 172.17.0.1 而不是 localhost。

“副本集配置中的所有主機名都必須是本地主機引用,或者必須沒有;找到 2 個中的 1 個”

然後,我使用https://stackoverflow.com/questions/28843496/cant-initiate-replica-set-in-ubuntu來發出rs.initiate({_id:"rs0", members: [{"_id":1, "host":"127.0.0.1:1000"}]})強制將 dc1.com 上的副本集初始化綁定到本地主機的命令。但是,當我嘗試通過添加成員時,rs.add("localhost:2001")我仍然無法做到。它不再是主機名錯誤,而是另一個我不太記得的錯誤,因為我厭倦了嘗試並且不得不回滾所有內容。這就像連接被拒絕。當我這樣做時,在mongo --port 2001收到與“isMaster”相關的警告後,我會斷開連接。

是否可以創建這種設置?我要做的就是避免在 MongoDB 上使用 TLS 並將備份綁定到全域可訪問的介面(現場實例將位於防火牆後面,因此 0.0.0.0:1002 將無法公開訪問)

在不使用 TLS 的情況下,可以進行以下設置。

數據中心 1 是主數據中心。所有客戶端都只連接到這個。Datacenter 2 僅用於通過複製進行實時備份。On-Site 也僅用於通過複製進行實時備份。

此設置不適用於故障轉移,僅用於災難恢復。

數據中心 1:

MongoDB

mongod –bind_ip 127.0.0.1,172.17.0.1 –replSet test –port 2000 –rest –httpinterface –logpath data/replica/logs/log.txt –dbpath data/replica/wiredTiger –directoryperdb – storageEnginewiredTiger –wiredTigerDirectoryForIndexes –fork

127.0.0.1 用於 SSH 訪問,172.17.0.1 用於從 Docker 容器訪問。

SSH 隧道(此伺服器負責創建到數據中心 2 的隧道):

autossh -f -N -L 2001:localhost:2001 mongodb@dc-2.example.com

autossh -f -N -R 2000:localhost:2000 mongodb@dc-2.example.com

數據中心 2:

MongoDB

mongod –bind_ip 127.0.0.1 –port 2001 –replSet test –rest –httpinterface –logpath data/replica/logs/log.txt –dbpath data/replica/wiredTiger –directoryperdb –storageEnginewiredTiger – WiredTigerDirectoryForIndexes –fork

現場:

MongoDB

mongod –bind_ip 127.0.0.1 –port 2002 –replSet test –rest –httpinterface –logpath data/replica/logs/log.txt –dbpath data/replica/wiredTiger –directoryperdb –storageEnginewiredTiger – WiredTigerDirectoryForIndexes –fork

SSH 隧道(On-Site 負責創建到 Datacenter 1 的隧道,Datacenter 2 和 On-Site 之間不存在持久連接)

autossh -f -N -R 2002:localhost:2002 mongodb@dc-1.example.com

autossh -f -N -L 2000:localhost:2000 mongodb@dc-1.example.com


Datacenter 1 中的伺服器包含所有要複製的數據,Datacenter 2 和 On-Site 是空數據庫。

在 Datacenter 1 的機器上,我輸入mongo --port 2000,然後發出

rs.initiate(
  {
     _id: "test",
     version: 1,
     members: [
        { _id: 0, host : "localhost:2000", priority: 1, votes: 1 },
        { _id: 1, host : "localhost:2001", priority: 0, votes: 0, hidden: true },
        { _id: 2, host : "localhost:2002", priority: 0, votes: 0, hidden: true }
     ]
  }
)

我想priority: 0, votes: 0, hidden: true這裡的輔助伺服器是可選的,它可以滿足我的需求,只需將兩個輔助伺服器作為靜默、不可見的數據收集器的一部分,用於備份目的。我不確定更改它是否會產生任何副作用,因為有可能兩個輔助節點之間的連接應該可用,在這種情況下它不是可用的(他們看不到彼此)。

我可以slaveDelay在其中一個隱藏成員上使用 a 以使其滯後半天,但是由於我將通過 mongodump 從兩個隱藏數據庫中進行大量備份,因此這並不是必需的。

為了能夠通過 mongodb 工具連接到輔助節點,我需要發出一個rs.slaveOk()

客戶端無需更改任何內容,它們連接到172.17.0.1:2000.

我在數據中心 2 中測試了機器的重啟,在重啟期間我在數據庫中插入了新項目,大約 30 秒後,重啟的機器按預期同步到數據中心 1。

數據中心 1 有一個快速伺服器,具有大量 RAM 和 CPU,只有一點點 SSD 儲存,數據中心 2 有一點點 RAM,但有很多 HDD,所以這似乎是一個很好的解決方案。

引用自:https://dba.stackexchange.com/questions/173911