Penso che la principale differenza che posso descrivere sia legata ai formati orientati ai record rispetto alle colonne. I formati orientati ai record sono ciò a cui siamo tutti abituati: file di testo, formati delimitati come CSV, TSV. AVRO è leggermente più freddo di quelli perché può cambiare lo schema nel tempo, ad esempio aggiungendo o rimuovendo colonne da un record. Altri trucchi di vari formati (in particolare la compressione inclusa) implicano se un formato può essere diviso, ovvero puoi leggere un blocco di record da qualsiasi parte del set di dati e sapere ancora che è schema? Ma ecco maggiori dettagli sui formati colonnari come Parquet.
Parquet e altri formati colonnari gestiscono una situazione Hadoop comune in modo molto efficiente. È comune avere tabelle (set di dati) con molte più colonne di quelle che ci si aspetterebbe in un database relazionale ben progettato - un centinaio di duecento colonne non è insolito. Questo perché spesso usiamo Hadoop come luogo per denormalizzare i dati da formati relazionali - sì, ottieni molti valori ripetuti e molte tabelle tutte appiattite in una sola. Ma diventa molto più facile interrogare poiché tutti i join sono stati elaborati. Vi sono altri vantaggi come la conservazione dei dati sullo stato nel tempo. Quindi comunque è comune avere un carico di colonne in una tabella.
Diciamo che ci sono 132 colonne, e alcune di esse sono campi di testo davvero lunghi, ognuna diversa da una all'altra e consuma forse 10K per record.
Mentre interrogare queste tabelle è facile con il punto di vista SQL, è comune che tu voglia ottenere una serie di record basati solo su alcune di quelle centinaia di colonne. Ad esempio, potresti desiderare tutti i record di febbraio e marzo per i clienti con vendite> $ 500.
Per fare ciò in un formato di riga, la query dovrebbe scansionare ogni record del set di dati. Leggi la prima riga, analizza il record in campi (colonne) e ottieni la data e le colonne delle vendite, includilo nel tuo risultato se soddisfa la condizione. Ripetere. Se hai 10 anni (120 mesi) di storia, stai leggendo ogni singolo disco solo per trovare 2 di quei mesi. Naturalmente questa è una grande opportunità per usare una partizione per anno e mese, ma anche così, stai leggendo e analizzando 10K di ogni record / riga per quei due mesi solo per scoprire se le vendite del cliente sono> $ 500.
In un formato colonnare, ogni colonna (campo) di un record viene memorizzata con altre del suo genere, distribuite su molti blocchi diversi sul disco: colonne per anno insieme, colonne per mese insieme, colonne per il manuale del dipendente del cliente (o altro testo lungo) e tutti gli altri che rendono tali record così grandi tutti nel loro posto separato sul disco, e ovviamente colonne per le vendite insieme. Bene, data e mesi sono numeri, così come le vendite: sono solo pochi byte. Non sarebbe bello se dovessimo leggere solo pochi byte per ogni record per determinare quali record corrispondessero alla nostra query? Archiviazione colonnare in soccorso!
Anche senza partizioni, scansionare i piccoli campi necessari per soddisfare la nostra query è super veloce: sono tutti in ordine per record e hanno tutte le stesse dimensioni, quindi il disco cerca molto meno dati controllando i record inclusi. Non c'è bisogno di leggere il manuale del dipendente e altri campi di testo lunghi: ignorali. Quindi, raggruppando le colonne tra loro, anziché le righe, puoi quasi sempre scansionare meno dati. Vincere!
Ma aspetta, migliora. Se la tua query avesse bisogno solo di conoscere quei valori e alcuni altri (diciamo 10 delle 132 colonne) e non si interessasse a quella colonna del manuale del dipendente, una volta che avesse scelto i record giusti per restituirla, ora dovrebbe solo andare torna alle 10 colonne necessarie per rendere i risultati, ignorando gli altri 122 dei 132 nel nostro set di dati. Ancora una volta, saltiamo molte letture.
(Nota: per questo motivo, i formati colonnari sono una scelta pessima quando si eseguono trasformazioni diritte, ad esempio, se si uniscono tutte e due le tabelle in un unico grande set di risultati che si sta salvando come nuova tabella, i sorgenti verranno comunque scansionati completamente, quindi non ci sono molti vantaggi nelle prestazioni di lettura e, poiché i formati colonnari devono ricordare di più su dove si trovano le cose, usano più memoria di un formato di riga simile).
Un altro vantaggio del colonnare: i dati sono distribuiti in tutto. Per ottenere un singolo record, puoi avere 132 lavoratori ciascuno che leggono (e scrivono) dati da / a 132 luoghi diversi su 132 blocchi di dati. Yay per la parallelizzazione!
E ora per il copertoncino: gli algoritmi di compressione funzionano molto meglio quando riescono a trovare schemi ripetitivi. Potresti comprimere AABBBBBBCCCCCCCCCCCCCCCC
come 2A6B16C
ma ABCABCBCBCBCCCCCCCCCCCCCC
non diventare così piccolo (beh, in realtà, in questo caso lo farebbe, ma fidati di me :-)). Quindi, ancora una volta, meno lettura. E anche scrivere.
Quindi leggiamo molti meno dati per rispondere a domande comuni, è potenzialmente più veloce da leggere e scrivere in parallelo e la compressione tende a funzionare molto meglio.
Colonnare è fantastico quando il tuo lato di input è grande e il tuo output è un sottoinsieme filtrato: da grande a piccolo è fantastico. Non altrettanto vantaggioso quando input e output sono più o meno gli stessi.
Ma nel nostro caso, Impala ha risposto alle nostre vecchie query Hive che sono state eseguite in 5, 10, 20 o 30 minuti e si è conclusa la maggior parte in pochi secondi o un minuto.
Spero che questo aiuti a rispondere almeno in parte alla tua domanda!