2012-12-17 14 views
50

Il framework di aggregazione introdotto in mongodb 2.2 presenta miglioramenti delle prestazioni speciali rispetto alla mappa/riduzione?Il framework Mongodb Aggregation è più veloce di map/reduce?

Se sì, perché, come e quanto?

(già ho fatto un test per me, e la performance era quasi lo stesso)

+1

"quasi" lo stesso? Con quali parametri? La tua osservazione è fondamentalmente inutile. E stai confrontando gatto e mucche. Inoltre, sai che il MR è ancora limitato al single-threading .... quindi: domanda inutile e quindi -1 –

+0

@ user1833746 È una domanda, non voglio spiegare i miei benchmark. Ho chiesto di conoscere nuove risposte a questo interrogato. Si prega di votare per consentire agli altri di rispondere. –

+0

hai visto questa domanda (e le risposte)? http://stackoverflow.com/questions/12139149/mapreduce-with-mongodb-really-really-slow-30-hours-vs-20-minutes-in-mysql-for –

risposta

61

ogni test che ho gestito personalmente (anche utilizzando i propri dati) mostra l'aggregazione come un multipl Più veloce della mappa si riduce, e di solito è più veloce di un ordine di grandezza.

Basta prendere 1/10 dei dati che hai postato (ma piuttosto di cancellare la cache del SO, prima di riscaldare la cache - perché voglio misurare le prestazioni dell'aggregazione, e non quanto tempo ci vuole per pagina nei dati) I ottenuto questo:

MapReduce: 1,058ms
aggregazione quadro: 133ms

Rimozione del $ partita dal quadro aggregazione e {query:} da MapReduce (perché entrambi sarebbe solo utilizzare un indice e che non è quello che vogliamo per misurare) e il raggruppamento dell'intero set di dati per key2 ho ottenuto:

MapReduce: 18,803ms
aggregazione quadro: 1,535ms

Quelli sono molto in linea con i miei precedenti esperimenti.

+0

per ulteriori commenti su questo vedi risposta a http://stackoverflow.com/questions/12139149/mapreduce-with-mongodb-really-really-slow-30-hours-vs-20-minutes-in-mysql-for –

+0

Grazie per aver risposto alla prima parte della domanda! E la seconda parte? Perché e come? Hai qualcosa da aggiungere per questo? Grazie per qualsiasi input. – Jeach

+1

questo è coperto nei documenti - ma in poche parole, l'aggregazione viene eseguita in modo nativo nel server (C++), MapReduce genera thread javascript separati per eseguire il codice JS. –

7

Il mio punto di riferimento:

== generazione dati ==

Generare 4 milioni di file (con python) facile con circa 350 byte. Ogni documento ha queste chiavi:

  • tasto1, key2 (due colonne casuali per testare indicizzazione, uno con cardinalità del 2000, e uno con cardinalità 20)
  • longdata: una lunga serie per aumentare la dimensione di ciascun documentare
  • valore: un numero semplice (const 10) per testare l'aggregazione

 
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) 
dimensione dei dati totale era circa 6GB in Mongo. (E 2GB in Postgres)

Test == ==

ho fatto qualche test, ma uno è sufficiente per i risultati a confronto:

NOTA: Server viene riavviato, e la cache del sistema operativo viene pulito dopo ogni query, per ignorare l'effetto della memorizzazione nella cache.

DOMANDA: aggregate tutte le righe con key1=somevalue (circa 200K righe) e sommare value per ciascuna mappa key2

  • /ridurre 10,6 sec
  • aggreate 9.7 sec
  • gruppo 10,3 sec

domande:

mappa/ridurre:

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'} })

aggregato:

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

gruppo:

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

+4

non è una struttura di aggregazione, è parte di una mappa/riduzione. Ecco perché ha una funzione di riduzione. Vedi la differenza qui: http://docs.mongodb.org/manual/reference/command/group/ e http://docs.mongodb.org/manual/reference/aggregation/#_S_group Se stavi usando una struttura di aggregazione si chiami db.collection.aggregate ([pipeline]) –

+0

Ho un suggerimento: perché non estrai la query ed esegui la stessa cosa su tutta la tua collezione e vedi se c'è una differenza nelle prestazioni. –

+3

un altro problema con il benchmark è la cache del sistema operativo cancellata? Quindi stavi misurando il tempo necessario per inserire i dati nella RAM. Nani i numeri delle prestazioni reali e non è uno scenario realistico. –

Problemi correlati