2015-09-02 16 views
10

Mam problem z diagnozowaniem problemu, w którym wnioski mojej aplikacji Java do MongoDB nie są kierowane do najbliższej repliki i mam nadzieję, że ktoś może pomóc. Zacznę od wyjaśnienia mojej konfiguracji.Routing Mongos z ReadPreference = NEAREST

Konfiguracja:

Używam instancji MongoDB w produkcji, która jest Sharded ReplicaSet. Jest to obecnie tylko jeden fragment (nie został wystarczająco duży, aby wymagać podziału). Ten pojedynczy fragment jest wspierany przez 3-węzłowy zestaw replik. 2 węzły zestawu replik znajdują się w naszym głównym centrum danych. Trzeci węzeł znajduje się w naszym drugorzędnym centrum danych i nie może zostać węzłem głównym.

Uruchomimy naszą aplikację produkcyjną jednocześnie w obu centrach danych, jednak instancja w naszym drugorzędnym centrum danych działa w trybie "tylko do odczytu" i nigdy nie zapisuje danych w MongoDB. Obsługuje tylko żądania klientów dotyczące odczytów istniejących danych. Celem tej konfiguracji jest zapewnienie, że jeśli nasze główne centrum danych ulegnie awarii, nadal będziemy obsługiwać ruch z odczytem klienta.

Nie chcemy marnować całego tego sprzętu w naszym drugorzędnym centrum danych, więc nawet w szczęśliwych chwilach aktywnie ładujemy saldo części naszego ruchu tylko do odczytu do instancji naszej aplikacji uruchomionej w drugorzędnym centrum danych. Ta instancja aplikacji jest skonfigurowana z readPreference = NEAREST i jest wskazywana na instancję mongos działającą na localhost (wersja 2.6.7). Instancja mongo jest oczywiście skonfigurowana tak, aby wskazywała na nasz zestaw replik 3-węzłowych.

Z 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" } 

od węzła pracy awaryjnej z 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" : {}} 
    } 
} 

Problem:

Problemem jest to, że wnioski, które uderzają to Mongos w naszym Wtórne centrum danych wydaje się być kierowane do repliki działającej w naszym głównym centrum danych, a nie do najbliższego węzła, który działa w e wtórnego centrum danych. Powoduje to znaczne opóźnienie sieci i powoduje słabą wydajność odczytu.

Rozumiem, że mongos decyduje, który węzeł w replice ustawić, aby skierować żądanie do, i ma honorować ReadPreference z mojego żądania sterownika java. Czy istnieje polecenie, które mogę uruchomić w powłoce mongos, aby zobaczyć status zestawu replik, w tym czasy pingowania do węzłów? Lub w jakiś sposób zobaczyć rejestrowanie żądań przychodzących, które wskazują węzeł w replicaSet, który został wybrany i dlaczego? Jakakolwiek rada w jaki sposób zdiagnozować główną przyczynę mojego problemu?

+0

Jak dokładnie zapobiega się, aby serwer w drugim centrum danych stał się podstawowym? Czy mógłbyś opublikować wyjście 'sh.status()' i 'rs.status()'? –

+0

Uniemożliwiasz węzłowi stanie się głównym z priorytetem = 0 http://docs.mongodb.org/master/core/replica-set-priority-0-member/#replica-set-secondary-only-members – skelly

+0

Istnieje kilka sposoby zapobiegania, aby węzeł stał się pierwotny, chciał tylko upewnić się, że nie jest ukryty. ;) Interesujący problem ... –

Odpowiedz

4

Jeśli zacznę Mongos z flagą -vvvv (4x gadatliwy) to jestem przedstawiane z życzeniem routing informacji zawartych w plikach dzienników, w tym informacji na temat preferencji wykorzystany i odczytu host, na który kierowane były żądania. na przykład:

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

Podczas konfigurowania preferencji odczytu, gdy ReadPreference = NEAREST system nie szuka minimalnego opóźnienia sieci, ponieważ może zadecydować, że podstawowa jest najbliższa, jeśli połączenie sieciowe jest poprawne. Jednak najbliższy tryb odczytu, w połączeniu z zestawem znaczników, wybiera pasujący element z najniższym opóźnieniem sieci. Nawet najbliższy może być jednym z podstawowych lub drugorzędnych. Zachowanie użytkowników mongo podczas konfigurowania preferencji, a także opóźnień sieci, nie jest tak jasno wyjaśnione w oficjalnych dokumentach.

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

nadzieję, że to pomaga