2013-03-10 13 views
5

Mam mały zestaw replik trzech serwerów mongod (16GB RAM każdy, przynajmniej 4 rdzenie procesora i prawdziwe dyski twarde) i jeden dedykowany arbiter. Replikowane dane zawierają obecnie około 100 000 000 rekordów. Prawie wszystkie te dane znajdują się w jednej kolekcji z indeksem na _id (automatycznie wygenerowany identyfikator Mongo) i date, który jest natywnym polem daty w Mongo. Okresowo usunąć stare wpisy z tej kolekcji za pomocą indeksu datę, coś takiego (od powłoki Mongo):MongoDB bardzo wolno usuwa

db.repo.remove({"date" : {"$lt" : new Date(1362096000000)}}) 

to działa, ale działa bardzo, bardzo powoli. Jeden z moich węzłów ma wolniejsze I/O niż dwa pozostałe, mając tylko jeden napęd SATA. Kiedy ten węzeł jest pierwotny, usuwanie trwa około 5-10 dokumentów/sek. Korzystając z polecenia rs.stepDown(), zdegradowałem wolniejszą podstawową i wymuszono wybory, aby uzyskać wersję podstawową z lepszymi wejściami/wyjściami. Na tym serwerze otrzymuję około 100 dokumentów/sek.

Moje główne pytanie brzmi: czy powinienem się tym przejmować? Nie mam numerów sprzed replikacji, ale wiem, że usuwanie było znacznie szybsze. Zastanawiam się, czy synchronizacja zestawu replik powoduje oczekiwanie I/O, czy też jest jakaś inna przyczyna. Byłbym całkowicie zadowolony z tymczasowego wyłączenia aktualizacji synchronizacji i indeksu, dopóki nie zakończy się instrukcja usuwania, ale nie wiem jak to zrobić w tej chwili. Z jakiegoś powodu, kiedy wyłączę dwa z trzech węzłów, pozostawiając tylko jeden węzeł i arbitra, pozostały węzeł jest zdegradowany, a zapisy są niemożliwe (czy arbiter nie powinien tego rozwiązać?).

Aby podać ogólne informacje o wydajności, po upuszczeniu i ponownym utworzeniu indeksu daty skanowanie wszystkich dokumentów 100M trwa około 15 minut.

+0

powód, dla którego nie można wyłączyć dwa swoimi czterema węzłami jest to, że nie może być podstawowym bez większością dostępnego zestawu. Dlaczego, tak przy okazji, macie czterech członków? Nie potrzebujesz arbitra z trzema węzłami w zestawie replik. –

+0

Mam cię - mam tylko cztery węzły w tej chwili, ponieważ 5th ​​węzeł brakuje dysku twardego i usuwa go z klastra :) Jak na ironię, ja wychowany arbitra pomóc gwarancję zawsze będzie zwycięzcą w wyborach master. W każdym razie, arbiter jest małą maszyną wirtualną, której używam również w przypadku innych niskich zasobów, takich jak serwery konfiguracji w innych klastrach. – SteveK

+0

potrzebne arbitra, gdy miał cztery węzły (na pięć głosów), ale po wyjęciu piąty węzeł z zestawu replik należy usunąć arbitra, jak również tak, że trzeba będzie trzech członków lewo. –

Odpowiedz

7

Dzieje się tak dlatego, że mimo

db.repo.remove({"date" : {"$lt" : new Date(1362096000000)}}) 

wygląda jednego polecenia to faktycznie działającej na wielu dokumentów - Aż spełnienia tego zapytania.

Podczas korzystania z replikacji każda operacja zmiany musi być zapisana w specjalnej kolekcji w bazie danych local o nazwie oplog.rs - oplog dla skrótu.

Oplog musi mieć wpis dla każdego usuniętego dokumentu, a każdy z tych wpisów musi zostać zastosowany do oploku na każdym drugorzędnym drukarce zanim będzie mógł również usunąć ten sam rekord.

Jedna rzecz, którą mogę zasugerować, to: TTL indexes - będą one "automatycznie" usuwać dokumenty w oparciu o datę/ustawioną datę ważności - w ten sposób nie będziesz mieć jednego ogromnego usunięcia, a zamiast tego będą w stanie rozłożyć obciążenie więcej z czasem.

+0

Dzięki za wyjaśnienie, to ma wiele sensu. Nie wiedziałem też o indeksach TTL - wygląda na niesamowitą funkcję! – SteveK

+0

Nie jestem pewien, czy to rozwiązanie jest dokładne. W dokumentach Mongo na https://docs.mongodb.org/manual/core/index-ttl/ stwierdza: "W zestawach replik, wątek tła TTL usuwa tylko dokumenty w podstawowym. Jednak wątek tła TTL działa na wtórnikach Wtórni członkowie replikują operacje usuwania z podstawowego. " Czy to nie znaczy, że nie ma różnicy w wydajności OPLOG z TTL w porównaniu z operacją ręczną? – Nucleon

+0

Różnica polega na tym, że wątek TTL działa co minutę w poszukiwaniu dokumentów do usunięcia. Użytkownik w tym przypadku uruchamiał jeden wielki błąd, aby usunąć je wszystkie naraz. TTL właśnie rozrzuca usuwanie przez dłuższy czas, więc co minutę robisz mniejsze porcje. Zakłada to, że wygaśnięcie jest na polu, które jest "na minutę" dokładne. –

1

Inna sugestia, że ​​nie może ci pasuje, ale to optymalne rozwiązanie dla mnie:

  1. drop indeksami z kolekcji
  2. iteracyjne nad wszystkich wpisów z id zbierania i przechowywania tych rekordów do usunięcia w tablicy pamięci
  3. każdym razem tablica jest na tyle duża (dla mnie było 10K rekordów), usunąłem te zapisy przez identyfikatory
  4. odbudować indeksami

Jest to najszybszy sposób, ale wymaga zatrzymania systemu, który był odpowiedni dla mnie.

Powiązane problemy