2012-12-17 12 views
50

Czy struktura agregacyjna wprowadzona w mongodb 2.2, ma jakieś specjalne ulepszenia wydajności w stosunku do mapy/zmniejszenia?Czy framework Mongodb Aggregation jest szybszy niż map/reduce?

Jeśli tak, dlaczego i jak i ile?

(Już mam zrobić test dla siebie, a wydajność była prawie taka sama)

+1

"prawie" to samo? Z którymi benchmarkami? Twoja uwaga jest w zasadzie bezcelowa. Porównujesz kota i krowy. Ponadto sam wiesz, że MR nadal ogranicza się do pojedynczego wątku .... a więc: bezcelowe pytanie, a zatem -1 –

+0

@ user1833746 To jest pytanie, nie chcę wyjaśniać moich testów. Poprosiłem o nowe odpowiedzi na to pytanie. Zagłosuj, aby inni mogli odpowiedzieć. –

+0

Widziałeś to pytanie (i odpowiedzi)? http://stackoverflow.com/questions/12139149/mapreduce-with-mongodb-really-really-slow-30-hs-vs-20-minutes-in-mysql-for –

Odpowiedz

61

Każda próba osobiście mam uruchomić (w tym przy użyciu własnych danych) pokazuje strukturę agregacji będącą multipliksem e szybciej niż mapa zmniejsza się i zwykle jest o rząd wielkości szybszy.

Biorąc tylko 1/10 danych, które wysłałeś (ale zamiast wyczyścić pamięć podręczną systemu operacyjnego, najpierw podgrzewając pamięć podręczną - ponieważ chcę mierzyć wydajność agregacji, a nie jak długo zajmuje strona w danych) got to:

MapReduce: 1,058ms
Aggregation Framework: 133ms

Zdejmowanie $ mecz z ram agregacji i {query:} z mapreduce (ponieważ zarówno po prostu użyć indeksu, a nie to, co chcemy do pomiaru) i zgrupowanie całego zestawu danych kluczem 2 Mam:

mapreduce: 18,803ms
Agregacja ramowa: 1,535ms

Są to w dużej mierze zgodne z moich wcześniejszych doświadczeń.

+0

po dodatkowe komentarze na ten temat patrz odpowiedź na http://stackoverflow.com/questions/12139149/mapreduce-withmonmon-really-really-slow-30-hs-ss-20-minutes-in-mysql-for –

+0

Dzięki za udzielenie odpowiedzi na pierwszą część pytania! A co z drugą częścią? Dlaczego i jak? Czy masz coś do dodania? Dziękuję za wszelkie uwagi. – Jeach

+1

jest to omówione w dokumentach - ale w skrócie, agregacja działa natywnie na serwerze (C++), MapReduce spawnuje oddzielne wątki javascript, aby uruchomić kod JS. –

7

Moja odniesienia:

== Generation Dane ==

Generowanie 4million wiersze (z pytona) łatwo z około 350 bajtami. Każdy dokument posiada następujące klawisze:

  • key1, Klawisz2 (dwa losowe kolumny do testowania indeksowanie, jeden z liczności 2000, a jeden z liczności 20)
  • longdata: długi ciąg, aby zwiększyć rozmiar każdego udokumentować
  • wartość: prosty numer (const 10) do testowania agregacji

 
db = Connection('127.0.0.1').test # mongo connection 
random.seed(1) 
for _ in range(2): 
    key1s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(10)] 
    key2s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(1000)] 
    baddata = 'some long date ' + '*' * 300 
    for i in range(2000): 
     data_list = [{ 
       'key1': random.choice(key1s), 
       'key2': random.choice(key2s), 
       'baddata': baddata, 
       'value': 10, 
       } for _ in range(1000)] 
     for data in data_list: 
      db.testtable.save(data) 
Całkowita wielkość wynosiła około 6 GB danych w Mongo. (I 2GB w PostgreSQL)

== Testy ==

Zrobiłem kilka testów, ale wystarczy do wyników porównujących:

UWAGA: Serwer zostanie ponownie uruchomiony, a OS cache jest czyszczony po każde zapytanie, aby zignorować efekt buforowania.

zapytania: kruszywa wszystkie wiersze z key1=somevalue (około 200K wiersze) i sumują value dla każdego key2

  • mapę/zmniejszenia 10,6 s
  • aggreate 9,7 s
  • grupę 10,3 s

zapytania:

mapa/zmniejszenie:

db.testtable.mapReduce(function(){emit(this.key2, this.value);}, function(key, values){var i =0; values.forEach(function(v){i+=v;}); return i; } , {out:{inline: 1}, query: {key1: '663969462d2ec0a5fc34'} })

łączna:

db.testtable.aggregate({ $match: {key1: '663969462d2ec0a5fc34'}}, {$group: {_id: '$key2', pop: {$sum: '$value'}} })

grupa:

db.testtable.group({key: {key2:1}, cond: {key1: '663969462d2ec0a5fc34'}, reduce: function(obj,prev) { prev.csum += obj.value; }, initial: { csum: 0 } })

+4

grupa nie jest strukturą agregacji, jest częścią mapy/zmniejsz. Dlatego ma funkcję zmniejszania. Zobacz różnicę tutaj: http://docs.mongodb.org/manual/reference/command/group/ i http://docs.mongodb.org/manual/reference/aggregation/#_S_group Jeśli korzystałeś z frameworka agregacji, be call db.collection.aggregate ([pipeline]) –

+0

Mam sugestię: dlaczego nie wyślesz zapytania i uruchomisz to samo na całej kolekcji i zobaczysz, czy jest różnica w wydajności. –

+3

Kolejnym problemem z benchmarkiem jest wyczyszczenie pamięci podręcznej systemu operacyjnego? Więc mierzysz głównie czas potrzebny na przesłanie danych do pamięci RAM. Przekracza rzeczywiste liczby wydajności i nie jest to realistyczny scenariusz. –

Powiązane problemy