2017-11-02 34 views
5

Odkryliśmy kilka duplikatów dokumentów w jednym z naszych indeksów Elasticsearch i nie byliśmy w stanie ustalić przyczyny. Istnieją dwie kopie każdego z dotkniętych dokumentów i mają dokładnie te same pola: _id, _type i .Powielanie dokumentów w indeksie Elasticsearch z tym samym _uid

GET Żądanie /index-name/document-type/document-id prostu zwraca jeden egzemplarz, ale szukając dokumentu z zapytaniem jak to zwraca dwa wyniki, co jest dość zaskakujące:

POST /index-name/document-type/_search 
{ 
    "filter": { 
    "term": { 
     "_id": "document-id" 
    } 
    } 
} 

Agregacja na polu _uid również identyfikuje duplikaty dokumentów :

POST /index-name/_search 
{ 
    "size": 0, 
    "aggs": { 
    "duplicates": { 
     "terms": { 
     "field": "_uid", 
     "min_doc_count": 2 
     } 
    } 
    } 
} 

Wszystkie duplikaty znajdują się na różnych odłamkach. Na przykład dokument może mieć jedną kopię w elemencie głównym 0 i jedną kopię w elemencie głównym 1. Zweryfikowaliśmy to, uruchamiając kwerendę zbiorczą powyżej dla każdego fragmentu po kolei, używając preference parameter: nie znaleziono żadnych duplikatów w jednym pliku czerep.

Nasze najlepsze przypuszczenie jest takie, że coś poszło nie tak z routingiem, ale nie rozumiemy, w jaki sposób kopie mogły zostać przekierowane na różne odłamki. Zgodnie z routing documentation, domyślne trasowanie jest oparte na identyfikatorze dokumentu i powinno konsekwentnie kierować dokument do tego samego fragmentu.

Nie używamy niestandardowych parametrów routingu, które przesłoniłyby domyślny routing. Sprawdziliśmy to dwukrotnie, upewniając się, że duplikaty dokumentów nie mają pola _routing.

Nie definiujemy również żadnych relacji rodzic/dziecko, które wpłynęłyby również na routing. (Patrz np. this question in the Elasticsearch forum, który ma takie same objawy, jak nasz problem. Nie uważamy, że przyczyna jest taka sama, ponieważ nie ustalamy żadnych rodziców dokumentu).

Naprawiliśmy natychmiastowy problem poprzez ponowne indeksowanie do nowego indeksu, który zgniecenia duplikatów dokumentów. Nadal mamy stary indeks do debugowania.

Nie znaleźliśmy sposobu na replikację problemu. Nowy indeks poprawnie indeksuje dokumenty i próbowaliśmy ponownie wykonać zadanie przetwarzania całonocnego, które również aktualizuje dokumenty, ale nie utworzyło więcej duplikatów.

Klaster ma 3 węzły, 3 odłamki podstawowe i 1 replikę (czyli 3 odłamki repliki). minimum_master_nodes jest ustawiony na 2, co powinno zapobiec problemowi split-brain. Używamy Elasticsearch 2.4 (co wiemy, że jest stare - planujemy wkrótce uaktualnić).

Czy ktoś wie, co może spowodować te duplikaty? Czy masz jakieś sugestie dotyczące sposobów debugowania go?

Odpowiedz

3

Znaleźliśmy odpowiedź! Problem polegał na tym, że indeks niespodziewanie przełączył algorytm mieszania używany do rutowania, co spowodowało, że niektóre zaktualizowane dokumenty były przechowywane w różnych skorupach do ich oryginalnych wersji.

GET żądanie /index-name/_settings ujawnił sposób:

"version": { 
    "created": "1070599", 
    "upgraded": "2040699" 
}, 
"legacy": { 
    "routing": { 
    "use_type": "false", 
    "hash": { 
     "type": "org.elasticsearch.cluster.routing.DjbHashFunction" 
    } 
    } 
} 

"1070599" odnosi się do Elasticsearch 1.7 i "2040699" to ES 2.4.

Wygląda na to, że indeks próbował uaktualnić się z 1,7 na 2.4, mimo że był już uruchomiony 2.4. Jest to problem opisany tutaj: https://github.com/elastic/elasticsearch/issues/18459#issuecomment-220313383

Uważamy, że to jest to, co się stało, aby wywołać zmiany:

  1. Powrót kiedy zmodernizowane indeks z ES 1.7 do 2.4, zdecydowaliśmy się nie uaktualnić Elasticsearch in- miejsce, ponieważ spowoduje to przestój. Zamiast tego stworzyliśmy oddzielny klaster ES 2.4.

    Załadowaliśmy dane do nowego klastra za pomocą narzędzia, które skopiowało wszystkie ustawienia indeksu, a także dane, w tym ustawienie version, które jest ustawiane jako you should not set in ES 2.4.

  2. Podczas rozwiązywania niedawnego problemu zdarzyło się, że zamknęliśmy i ponownie otwieramy indeks. Z reguły zachowuje on wszystkie dane, ale z powodu niepoprawnego ustawienia version spowodowało, że Elasticsearch uznało, że uaktualnienie zostało przetworzone.

  3. ES automatycznie ustawia ustawienie legacy.routing.hash.type z powodu fałszywego uaktualnienia. Oznaczało to, że wszelkie dane indeksowane po tym punkcie używały starego DjbHashFunction zamiast domyślnego Murmur3HashFunction, który był używany do pierwotnego trasowania danych.

Oznacza to, że reindeksowanie danych do nowego indeksu było właściwe, aby rozwiązać problem. Nowy indeks ma poprawne ustawienie wersji i nie ma ustawień funkcji skrótu tradycyjnego:

"version": { 
    "created": "2040699" 
}