簡體   English   中英

無法連接到與讀取首選項 Primary 匹配的副本集成員

[英]Unable to connect to a member of the replica set matching the read preference Primary

我有 3 個 mongodb 節點:primary、secondary 和 arbiter(版本 2.4.9)

我有 mongodb C# 驅動程序 1.8.3 我正在使用以下連接字符串:

連接字符串“mongodb://mongo2,mongo1,mongo3/?connect=replicaset&replicaset=myrs&readPreference=SecondaryPreferred”

記錄半情況時,驅動程序拋出異常:

無法連接到與讀取首選項 Primary 匹配的副本集成員

我的代碼:

        var client = new MongoClient(connectionString);
        var server = client.GetServer();
        var database = server.GetDatabase(dbName);
        var collection = database.GetCollection<T>(collectionName);
        collection.Insert(newDoc);

我究竟做錯了什么?

我懷疑這是因為您提供了錯誤的主機名。

這是您應該知道的一件事,可用的 mongo 實例列表不是來自您的連接字符串,而是來自第一個可用的 mongo 實例的返回結果。 例如,當驅動程序與實例 mongo1 通信時,它會獲取可用實例的列表,您可以使用以下命令獲取該列表:

rs.status()

在我的筆記本電腦中,它返回如下內容:

{
    "set" : "rs0",
    "date" : ISODate("2014-01-27T06:43:11Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "YX-ARCH:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 15894,
            "optime" : Timestamp(1390804960, 1),
            "optimeDate" : ISODate("2014-01-27T06:42:40Z"),
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "YX-ARCH:27011",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 31,
            "optime" : Timestamp(1390804960, 1),
            "optimeDate" : ISODate("2014-01-27T06:42:40Z"),
            "lastHeartbeat" : ISODate("2014-01-27T06:43:10Z"),
            "lastHeartbeatRecv" : ISODate("2014-01-27T06:43:10Z"),
            "pingMs" : 0,
            "syncingTo" : "YX-ARCH:27017"
        }
    ],
    "ok" : 1
}

這意味着有 2 個實例 YX-ARCH:27017 (Primary) & YX-ARCH:27011 (Secondary)。

現在的重點是,這些主機名必須可以在您的 IIS 服務器中解析,因為您的驅動程序將使用這些地址連接到 mongo 實例。

因此,如果主機名解析為 Internet IP,而您的 mongo 服務僅可用於 Intranet,您將永遠無法連接到它。 你會得到上面的錯誤。

還有一件事,不建議每次都創建一個新的 MongoClient 實例。 從文檔中您可以知道它是線程安全的類。 並且 MongoClient 被添加到驅動程序來管理副本集的東西。 因此,在我看來,您應該將其保留為單個實例對象。 因為每次創建新實例時,它都會嘗試從一個實例中獲取副本集設置,這對於效率來說並不是一件好事。

What am I doing wrong? 

我認為你不應該在連接字符串中聲明仲裁者。 Arbiter 並不是一個真正的節點,它不持有任何數據,它的任務是參與副本集的主節點(負責寫入的節點)的投票。

您添加仲裁器做得很好,因為沒有它,節點(和投票)是偶數,無論如何您都會面臨一些連接失敗的情況。 無論如何,您的問題與此無關。 你真的需要那個connect=replicaset嗎?

我對 C# 了解不多,但我讀到所有官方驅動程序的連接字符串都具有相同的格式,這也是 php 中的一個示例:

    $m = new MongoClient("mongodb://mongo1:27017,mongo2:27018/?replicaSet=myrs&readPreference=secondary");

你在測試最終的一致性嗎? 讓我知道你的想法,我沒有時間檢查它

不知道它是否區分大小寫,但要注意大寫字母replicaSet=myrs

我知道這個帖子已經過時了,但我上周遇到了這個問題,我解決了這個問題。

您必須檢查的幾件事:

  1. 如果您與mongodb的連接托管在connectionstrings.config 中,則&應該是&amp; 否則你會得到一個“實體問題”。
  2. 不要忘記添加mongodb端口27017
  3. 使用primaryPreffered不是secondaryPreferred - 如果您希望應用程序在正常情況下從主服務器讀取,但在主服務器不可用時允許從輔助服務器讀取過時。 這在故障轉移期間為您的應用程序提供了“只讀模式”。 使用secondaryPreferred是一種禁忌症。 此處的mongodb 官方文檔了解更多信息

  4. 顯而易見的是檢查副本集是否相互連接,這意味着存在仲裁成員,因此您會遇到該問題。 我敢打賭,如果您只放置 mongo1 並刪除其他副本集參數,它將完美運行。

  5. 正如yaoxing所提到的,如果您使用的是mongodb主機/名稱,請確保它們是正確的,進一步測試是使用MongoDB IP地址而不是主機/名稱,根據我的測試,這仍然可以工作。
  6. MongoDB的參數是大小寫敏感的,所以更好的保證您使用replicaSetreplicaset冒犯表示。
  7. 如果您有仲裁成員,則不必將其包含在您的連接中。
  8. 此外,您可以查看此 MongoDB 配置文章 它還包括加密,以備不時之需,但總的來說,如果所有要點都得到解決,您就不應該有這個問題。

對我來說,很少有 mongo 服務器崩潰,因此我看到了錯誤。 請檢查您的 mongo db 服務器連接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM