Replication

將 MongoDB 副本集與遠端副本集同步

  • August 5, 2016

我想知道是否可以(在合理範圍內)將新的 MongoDB 副本集(RS)與目前生產的 RS 同步。

問題

我們有一個在 AWS 上執行的站點,它有自己的 MongoDB 副本集,我們正在努力將該站點遷移到 Google Cloud。我們希望在 Google Compute 上啟動一個單獨的 RS,以趕上 AWS RS,並在我們的 QA 生命週期中保持最新狀態,直到我們準備好將 DNS 切換到 Google。

我們最初嘗試將 Google 上的副本作為輔助伺服器添加到 AWS RS 以保持它們同步。我們的計劃是讓 AWS RS 離線,讓 Google RS 重新分配一個主節點,並在站點完全遷移後繼續作為唯一的 RS。

當其中一個 Google 副本被選為主副本並與我們目前的實時站點產生一些同步問題時,這會導致一些問題。

解決方案??

我一直在爭論是否可以從 AWS 主節點同步到 GCloud 主節點。這對 Mongo 可行嗎?然後 GCloud 主節點會正確複製到它的從節點嗎?

要麼…

有沒有人知道這個問題的更好的解決方案?

更新

嘗試將 Google 節點添加到伺服器後,我們沒有看到節點同步:

INFRA-GENERAL-00:SECONDARY> rs.status()
{
"set" : "INFRA-GENERAL-00",
"date" : ISODate("2016-08-03T00:22:37.275Z"),
"myState" : 2,
"term" : NumberLong(2),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
   {
       "_id" : 0,
       "name" : "****:27017",
       "health" : 0,
       "state" : 8,
       "stateStr" : "(not reachable/healthy)",
       "uptime" : 0,
       "optime" : {
           "ts" : Timestamp(0, 0),
           "t" : NumberLong(-1)
       },
       "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
       "lastHeartbeat" : ISODate("2016-08-03T00:22:35.205Z"),
       "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
       "pingMs" : NumberLong(0),
       "lastHeartbeatMessage" : "exception: field not found, expected type 16",
       "configVersion" : -1
   },
   {
       "_id" : 1,
       "name" : "****:27017",
       "health" : 0,
       "state" : 8,
       "stateStr" : "(not reachable/healthy)",
       "uptime" : 0,
       "optime" : {
           "ts" : Timestamp(0, 0),
           "t" : NumberLong(-1)
       },
       "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
       "lastHeartbeat" : ISODate("2016-08-03T00:22:34.728Z"),
       "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
       "pingMs" : NumberLong(0),
       "lastHeartbeatMessage" : "exception: field not found, expected type 16",
       "configVersion" : -1
   },
   {
       "_id" : 2,
       "name" : "****:27017",
       "health" : 0,
       "state" : 8,
       "stateStr" : "(not reachable/healthy)",
       "uptime" : 0,
       "optime" : {
           "ts" : Timestamp(0, 0),
           "t" : NumberLong(-1)
       },
       "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
       "lastHeartbeat" : ISODate("2016-08-03T00:22:35.248Z"),
       "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
       "pingMs" : NumberLong(0),
       "lastHeartbeatMessage" : "exception: field not found, expected type 16",
       "configVersion" : -1
   },
   {
       "_id" : 3,
       "name" : "****:27017",
       "health" : 1,
       "state" : 2,
       "stateStr" : "SECONDARY",
       "uptime" : 338,
       "optime" : {
           "ts" : Timestamp(1470169610, 1),
           "t" : NumberLong(2)
       },
       "optimeDate" : ISODate("2016-08-02T20:26:50Z"),
       "configVersion" : 175485,
       "self" : true
   }
],
"ok" : 1
}











INFRA-GENERAL-00:SECONDARY> rs.config()
2016-08-03T00:23:49.051+0000 E QUERY    [thread1] Error: Could not     retrieve replica set config: {
"ok" : 0,
"errmsg" : "not authorized on admin to execute command {     replSetGetConfig: 1.0 }",
"code" : 13
} :
rs.conf@src/mongo/shell/utils.js:1091:11
@(shell):1:1

看來我們無法將 Mongo 3.2 伺服器添加到 Mongo 2.4 集群,所以我們決定降級我們要遷移到的集群並考慮稍後升級。在我們的 Google 集群上降級到 Mongo 2.4 後,複製執行良好。

遷移到新系統時一個有用的策略是確保新集群中的所有伺服器都不能投票。這可以幫助您避免副本集經歷有偶數個成員的階段,這可能會破壞事情。更多關於非投票副本的資訊:https ://docs.mongodb.com/manual/tutorial/configure-a-non-voting-replica-set-member/

此外,正如@Adam C 所提到的,將新成員設置為優先級 0 很重要,這將防止他們被選為主要成員。(這似乎並沒有阻止他們參與選舉,所以我們使用了投票配置)

您可以按照最初的策略稍作調整:將 Google Compute (GC) 節點添加到目前副本集中並保持同步,直到準備好切換。您唯一需要更改的是將這些新的 GC 節點設置為優先級 0。他們將是該集合的正式成員,他們只是不能被選為主要成員(或觸發選舉)。

一旦您準備好切換到 Google 節點,您只需將優先級重置為 1(或任何您的正常值),然後退出或從集合中刪除 AWS 節點。您可以通過在發出降級之前賦予它們比 AWS 節點更高的優先級來保證 GC 節點被選為主節點。

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