2011-08-01 29 views
7

Używam intensywnego pisania w MongoDB do aplikacji internetowej i uzyskuję z tego wyjątkowo niską wydajność. W związku z tym jestem przekonany, że problem ma więcej wspólnego z naszym kodem, konfiguracją i/lub użytkowaniem niż z samym Mongo.Niezwykle słaba wydajność MongoDB w aplikacjach wymagających dużej ilości zapisu

Mam zamiar otworzyć głowę z młotem z rozpaczy, więc zastanawiałem się, czy ktokolwiek miałby coś przeciwko wynikom, które przygotowałem, aby zobaczyć, czy coś wydaje się problematyczne.

Kod nie jest zbyt skomplikowane (to w PHP, btw). To dość dużo -> find() i -> update(). Upewniłem się używać indeksów dla obu połączeń i potwierdziłem, że rzeczywiście były używane przez wykonanie explain() na zapytaniach.

Próbowałem 1 serwer (ec2 m2.2xlarge), 4 serwery (2 odłamki po 2 powtórzeń) i 9 serwerów (3 odłamki po 3 powtórzenia) i nie byłem w stanie wydobyć z nich zbyt wiele.

W dobrych momentach nie mogę uzyskać więcej niż 1500 zapisów na sekundę (wstaw + aktualizację). Najczęściej mam szczęście, że mogę osiągnąć łączną liczbę 100 wstawień/aktualizacji i zawsze mam duży "zablokowany%" i wiele zapytań w kolejce "qr | qw".

W tej chwili mam skrypt, który działa i jest indeksowany. Najgorsze jest to, że gdy patrzę na mongostat przez pewien czas, ilość pamięci RAM użytej w "res" wynosi około 50% dostępnej pamięci RAM serwera, a ilość pamięci RAM jest wystarczająca, aby pasować do indeksów wszystkich kolekcji. Nie ma powodu, dla którego to nie wypluje danych, jak szalone.

Musiałem przekodować aplikację już 2-3 razy, starając się znaleźć lepsze wzorce dostępu do danych. Czytałem wszystko, co mogłem przeczytać na temat indeksów, aktualizacji, kluczy odłamkowych, a co nie. Wszystkie serwery, na które instaluję mongo używają 8 dysków EBS najeżdżających na 10 instalacji z dodanymi dodatkami poprawiającymi wydajność (blockdev, noatime itp.).

Wiem, że problem jest na moim końcu i nie obwiniam mongodb. Wiem, że większe firmy niż ja używają go do zastosowań wymagających dużej ilości zapisu i że są absolutnie zachwycone (na przykład foursquare). W tym samym czasie po prostu nie rozumiem, co robię źle i dlaczego mam tak słabe wyniki, bez względu na to, co robię.

Informacje dodatkowe:

  • Wszystkie serwery (klient i serwer) z systemu Ubuntu 10.04 LTS z MongoDB 1.8.2
  • Wszystkie serwery są na EC2 Wschodzie i w tej samej strefie
  • Obecnie I wróciłem do serwera 1 m2.2xlgge (4 rdzenie, 34,2 GB RAM), dopóki nie znajdę problemu.

Odpowiedz

10

Pierwszy problem polega na tym, że dysk wydaje się być zajęty głównie czytaniem, a nie pisaniem. (na podstawie iostat). Twoje wykorzystanie wynosi znacznie ponad 50%, ale w zasadzie wszystkie są odczytywane.

Jeśli przyjrzę się twoim statystykom DB, masz 35 GB indeksów i 41 GB danych w 133 GB przydzielonych plików. 133 GB jest dość blisko twojego numeru mapped w mongostat.Zatem suma danych, do których masz dostęp, wynosi około 120 GB lub około 4x RAM.

Zazwyczaj 4x to idealnie cienki stosunek. Jednak w twoim przypadku masz indeksy przekraczające pamięć RAM. To okazuje się być punktem "spadku" wydajności w MongoDB.

Jeśli uzyskiwany jest losowy dostęp do indeksu, większość lub wszystkie indeksy znajdują się w pamięci. Oznacza to, że większość danych nie jest w pamięci i musi być "stronicowana" z dysku. Możesz to zobaczyć na ciężkim dysku, który czytasz.

Wiem, że mówisz, że testowałeś z shardingiem, czy masz numery do tych testów? Czy dane prawidłowo rozłożyły się na wszystkie trzy odłamki?

Sharding powinien złagodzić twój problem, ponieważ dodajesz więcej pamięci RAM do bazy danych, ale musisz potwierdzić, że dane są rzeczywiście uszkodzone równomiernie i zachowują się poprawnie lub nie mogą rozwiązać problemu.

+2

+1 Warto również wspomnieć, że jeśli twoich aktualizacji nie da się wprowadzić w życie (ponieważ przerosły one przydzielone wolne miejsce), będą musiały zostać odczytane z dysku, do pamięci, zmodyfikowane i zapisane na końcu zbiór danych. –

Powiązane problemy