2015-09-02 3 views
10

Ich habe Probleme bei der Diagnose eines Problems, bei dem die Anforderungen meiner Java-Anwendung an MongoDB nicht an die nächste Replik weitergeleitet werden, und ich hoffe, dass jemand helfen kann. Lassen Sie mich zunächst meine Konfiguration erläutern.Mongos routing mit ReadPreference = NEAREST

Die Konfiguration:

Ich bin ein MongoDB Beispiel in der Produktion ausgeführt wird, der ein sharded ReplicaSet ist. Es ist derzeit nur ein einziger Shard (er ist noch nicht groß genug geworden, um einen Split zu benötigen). Dieser einzelne Shard wird von einem 3-Knoten-Replikat gesichert. In unserem primären Rechenzentrum befinden sich 2 Knoten des Replikatsets. Der dritte Knoten befindet sich in unserem sekundären Datencenter und darf nicht zum Master-Knoten werden.

Wir führen unsere Produktionsanwendung gleichzeitig in beiden Rechenzentren aus, die Instanz in unserem sekundären Rechenzentrum arbeitet jedoch im schreibgeschützten Modus und schreibt niemals Daten in MongoDB. Es dient nur Clientanforderungen für das Lesen vorhandener Daten. Das Ziel dieser Konfiguration besteht darin, sicherzustellen, dass bei Ausfall des primären Datencenters weiterhin Client-Leseverkehr bereitgestellt werden kann.

Wir möchten nicht alle diese Hardware in unserem sekundären Datencenter verschwenden. Daher laden wir auch in glücklichen Zeiten aktiv einen Teil unseres schreibgeschützten Datenverkehrs auf die Instanz unserer Anwendung im sekundären Rechenzentrum aus. Diese Anwendungsinstanz wird mit readPreference = NEAREST konfiguriert und wird auf eine mongos-Instanz verwiesen, die auf localhost (Version 2.6.7) ausgeführt wird. Die Mongo-Instanz ist offensichtlich so konfiguriert, dass sie auf unsere 3-Knoten-Replikatgruppe zeigt.

Aus mongos:

mongos> sh.status() 
--- Sharding Status --- 
sharding version: { 
"_id" : 1, 
"version" : 4, 
"minCompatibleVersion" : 4, 
"currentVersion" : 5, 
"clusterId" : ObjectId("52a8932af72e9bf3caad17b5") 
} 
shards: 
{ "_id" : "shard1", "host" : "shard1/failover1.com:27028,primary1.com:27028,primary2.com:27028" } 
databases: 
{ "_id" : "admin", "partitioned" : false, "primary" : "config" } 
{ "_id" : "test", "partitioned" : false, "primary" : "shard1" } 
{ "_id" : "MyApplicationData", "partitioned" : false, "primary" : "shard1" } 

Von dem Failover-Knoten des replicaset:

shard1:SECONDARY> rs.status() 
{ 
"set" : "shard1", 
"date" : ISODate("2015-09-03T13:26:18Z"), 
"myState" : 2, 
"syncingTo" : "primary1.com:27028", 
"members" : [ 
{ 
    "_id" : 3, 
    "name" : "primary1.com:27028", 
    "health" : 1, 
    "state" : 1, 
    "stateStr" : "PRIMARY", 
    "uptime" : 674841, 
    "optime" : Timestamp(1441286776, 2), 
    "optimeDate" : ISODate("2015-09-03T13:26:16Z"), 
    "lastHeartbeat" : ISODate("2015-09-03T13:26:16Z"), 
    "lastHeartbeatRecv" : ISODate("2015-09-03T13:26:18Z"), 
    "pingMs" : 49, 
    "electionTime" : Timestamp(1433952764, 1), 
    "electionDate" : ISODate("2015-06-10T16:12:44Z") 
}, 
{ 
    "_id" : 4, 
    "name" : "primary2.com:27028", 
    "health" : 1, 
    "state" : 2, 
    "stateStr" : "SECONDARY", 
    "uptime" : 674846, 
    "optime" : Timestamp(1441286777, 4), 
    "optimeDate" : ISODate("2015-09-03T13:26:17Z"), 
    "lastHeartbeat" : ISODate("2015-09-03T13:26:18Z"), 
    "lastHeartbeatRecv" : ISODate("2015-09-03T13:26:18Z"), 
    "pingMs" : 53, 
    "syncingTo" : "primary1.com:27028" 
}, 
{ 
    "_id" : 5, 
    "name" : "failover1.com:27028", 
    "health" : 1, 
    "state" : 2, 
    "stateStr" : "SECONDARY", 
    "uptime" : 8629159, 
    "optime" : Timestamp(1441286778, 1), 
    "optimeDate" : ISODate("2015-09-03T13:26:18Z"), 
    "self" : true 
} 
], 
"ok" : 1 
} 


shard1:SECONDARY> rs.conf() 
{ 
    "_id" : "shard1", 
    "version" : 15, 
    "members" : [ 
    { 
     "_id" : 3, 
     "host" : "primary1.com:27028", 
     "tags" : { 
      "dc" : "primary" 
     } 
    }, 
    { 
     "_id" : 4, 
     "host" : "primary2.com:27028", 
     "tags" : { 
      "dc" : "primary" 
     } 
    }, 
    { 
     "_id" : 5, 
     "host" : "failover1.com:27028", 
     "priority" : 0, 
     "tags" : { 
      "dc" : "failover" 
     } 
    } 
    ], 
    "settings" : { 
     "getLastErrorModes" : {"ACKNOWLEDGED" : {}} 
    } 
} 

Das Problem:

Das Problem ist, dass Anfragen, die dieses mongos Hit in unserem Das sekundäre Datencenter scheint zu einem Replikat weitergeleitet zu werden, das in unserem primären Datencenter ausgeführt wird, nicht zum nächsten Knoten, der in th ausgeführt wird Das sekundäre Datencenter. Dies verursacht eine erhebliche Netzwerklatenz und führt zu schlechter Leseleistung.

Mein Verständnis ist, dass die Mongos entscheidet, welcher Knoten in der Replik festgelegt, um die Anfrage an, und es soll die ReadPreference von meinem Java-Treiber-Anforderung zu erfüllen. Gibt es einen Befehl, den ich in der mongos-Shell ausführen kann, um den Status der Replikatgruppe zu sehen, einschließlich Ping-Zeiten zu Knoten? Oder eine Möglichkeit, die Protokollierung eingehender Anfragen zu sehen, die den Knoten im replySet angibt, der ausgewählt wurde und warum? Irgendein Rat überhaupt, wie man die Grundursache meines Problems diagnostiziert?

+0

Wie genau verhindern Sie, dass der Server im zweiten Rechenzentrum primär wird? Könnten Sie die Ausgabe von 'sh.status()' und 'rs.status()'? –

+0

Sie verhindern, dass ein Knoten primär wird mit Priorität = 0 http://docs.mongodb.org/master/core/replica-set-priority-0-member/#replica-set-secondary-only-members – skelly

+0

Es gibt mehrere Möglichkeiten, um zu verhindern, dass ein Knoten primär wird, wollten nur sicherstellen, dass er nicht versteckt war. ;) Interessantes Problem ... –

Antwort

4

Wenn ich mongos mit Flagge -vvvv (4x ausführlich) beginnen dann bin ich mit der Bitte Routing-Informationen in den Protokolldateien dargestellt, einschließlich Informationen über die Lese bevorzugt verwendet und die Host, an den Anforderungen weitergeleitet wurden. Beispiel:

2015-09-10T17:17:28.020+0000 [conn3] dbclient_rs say 
using secondary or tagged node selection in shard1, 
read pref is { pref: "nearest", tags: [ {} ] } 
    (primary : primary1.com:27028, 
    lastTagged : failover1.com:27028) 
4

Beim Konfigurieren der Lesevorgabe sucht das System bei der Verwendung von ReadPreference = NEAREST nicht nach einer minimalen Netzwerklatenz, da es sich bei einer ordnungsgemäßen Netzwerkverbindung als nächstgelegene Instanz entscheiden kann. Der nächste Lesemodus wählt jedoch, wenn er mit einem Markierungssatz kombiniert wird, das übereinstimmende Element mit der niedrigsten Netzwerklatenz aus. Sogar der nächste kann primärer oder sekundärer Art sein. Das Verhalten von Mongos bei der Konfiguration von Präferenzen und hinsichtlich der Netzwerklatenz wird in den offiziellen Dokumenten nicht so klar erklärt.

http://docs.mongodb.org/manual/core/read-preference/#replica-set-read-preference-tag-sets

hoffe, das hilft

Verwandte Themen