PDA

Visualizza la versione completa : Perl e la manipolazione di dati


gmesturini
30-11-2005, 11:07
Ciao a tutti,

mi trovo qui per via della leggendaria potenza di Perl in ambito di manipolazione di dati. Le mie conoscenze di Perl - in una scala che va da 0 a 10 - assumono un livello di... si, diciamo 0. Mi è stata proposta una sfida, che consiste nel caricare ~80 GB di dati in 60 minuti in un DB, ad una media quindi ~20 MB al secondo. Assumendo che i dati sorgenti necessitano di pulizia ed aggregazione, e che questo già di per se inibisce il raggiungimento dei livelli prestazionali sopra citati, devo comunque studiare il metodo più veloce per svolgere questo sporco lavoro.

Pensate alla situazione peggiore dei dati:

- Record con strutture differenti in uno stesso file
- Date prive dell'informazione sul secolo, espresse come DDMMYY
- Stringhe NULL valorizzare con sequenza di blanks
- Date NULL valorizzate con sequenza di zeri
- Cifre NULL valorizzate con sequenza di zeri

e avrete un'idea vaga di quello che mi aspetta. La pulizia che devo effettuare

- Separare i record in file diversi per struttura
- Dare per scontato che le date siano comprese tra l'anno 2000 e il 2099
- Indicare i valori NULL in modo cristiano
- Effettuare qualche tipo di aggregazione

consiste nel rendere digeribili i dati da una routine di caricamento che può essere la DB2 Load (per DB2) o la SQLLoader (per Oracle) - ancora non è stato deciso quale DB verrà utilizzato.

Mi ero messo a sviluppare un parser in Java, quando su più forum mi hanno consigliato di utilizzare Perl oppure Awk, che per questo tipo di lavori sono i più indicati.

1. Siete anche voi della stessa idea? (Perl > Java)
2. Esiste un qualche tutorial che mi permetta di capire quali sono le potenzialità di Perl nella manipolazione dei dati?
3. Perl (essendo un linguaggio di scripting) è un interpretato? Se si, quindi, è al 100% portabile? (da Windows ad AIX per esempio...)
4. Essendo un interpretato, non dovrebbe essere più lento di Java che può produrre semicompilati o compilati?

Grazie mille in anticipo per l'aiuto

Jo

Mich_
30-11-2005, 11:47
Provo a rispondere (per quel poco che so), poi ci sono altri forumisti che ne sanno di piu`.

Se cerchi la velocita`, Perl non e` la soluzione migliore:sicuramente C/C++ sono piu` veloci.

Comunque quello che interessa di piu`, per il tuo problema, e` la velocita` di accesso al database. Quindi dato che sia Perl che C/C++ hanno bisogno di librerie, devi verificare l'efficienza delle librerie che usi.
Anche la velocita` di accesso al disco (80 GB non stanno in memoria) e` una fonte di possibili ritardi importanti.

Poi dipende anche dal tipo di database che devi usare. Sia per Perl che per C ci sono librerie pronte per tutti i maggiori database.

Non conosco java a fondo, ma credo che le librerie per i DB ci siano anche per Java. Invece non credo che java sia piu` veloce; e` vero che e` semicompilato, ma il "semi" che manca ha necessita` della JVM, che non e` il massimo dell'efficienza, di solito (ma dipende dalla piattaforma).

Perl e` intrpretato (ma esistono anche dei compilatori), come dici tu.
Purtroppo tra linux e windows ci sono delle differenze (sul sito di shishii dovrebbero esserci segnalate).
Oltre alla differenza dell'estensione (in windows obbligatoria) e della prima riga (in linux obbligatoria), c'e` una diferente gestione dei file: in linux devi usare il flock(), che windows fa in automatico. Naturalmente dipende se il database cui accedi e` dedicato alla applicazione o no.

Non so se c'e` un tutorial di Perl. Pero` la documentazione e` fatta bene (ma serve un background di programmazione per poterla capire).

gmesturini
30-11-2005, 12:12
Innanzitutto grazie per la risposta e la tempestività.

Per quanto riguarda l'accesso al database, ricorrerò all'uso di utility fornite dal vendor. Nel caso di DB2 (ad esempio) verrà usata la Load, utility che non si avvale dell'utilizzo dello statement di INSERT, bensì effettua una copia binaria dei data-pages del database, infinitamente più veloce.

Il compito di Perl (o C, o C++ che sia) dovrebbe essere soltanto quello di prendere il file sorgente, smanettarlo pesantemente e produrre un'altro file a dare in pasto all'utility di caricamento. L'introduzione di un parser Perl (o quello che sarà) si rende necessaria dal momento che i dati del file sorgente sono organizzati in modo pessimo, impossibili da dare in pasto ad una utility di caricamento così come sono. Ad esempio: nel caso della Load di DB2 è necessario che i file posizionali da caricare contengano record con struttura omogenea (la Load accessa una sola mappa a giro), e quindi già un semplice smistamento dei record per produrre file omogenei è necessario. Inoltre credo (spero) non esista al mondo DB che accetti date prive di informazioni sul secolo, mentre invece il mio file sorgente ha quasi tutte le date espresse in DDMMYY, dando per scontanto che gli anni siano collocati tra il 2000 e il 2099: devo perciò compiere l'odioso lavoro di incollare un '20' davanti a tutti gli YY. Questo è un altro motivo per il quale è necessario preprocessare il file dati. Ce ne sono altri, che ho descritto nel primo messaggio.

Per quanto riguarda gli 80 GB, si tratta del caso peggiore, e sono da ripartire in n file (di dimensione e quantità ancora oscuri...) quindi non dovrebbero esserci problemi di memoria. Inoltre sto cercando di studiare una logica di pipeline (mentre la Load carica un file preprocessato, il parser può processarne un altro) e di parallelismo che dovrebbero semplificare un po' le cose. La macchina di produzione ha 64 processori (di cui posso prendermene una ventina) e 2 GB di RAM per ogni processore (totale 128 GB di RAM), e sinceramente spero con queste caratteristiche che non mi lasci a piedi. Purtroppo non so che tipo di supporto di memorizzazione di massa monti, e nel mio caso particolare l'accesso in lettura e scrittura al disco è un attore fondamentale.

Non sapendo però come organizzare le cose in Perl, non so di quanti step sarà composto il processo di caricamento - informazione necessaria per organizzare la pipeline.

Scarterei a priori qualunque utilizzo di librerie DBC per favorire le utility di caricamento proprietarie, in quanto l'uso massivo di INSERT (si parla di oltre 600 milioni di record) farebbe precipitare le prestazioni a zero, qualunque sia il linguaggio adottato. La copia binaria dei datapages invece (come ad esempio effettua la Load) accelera sensibilmente il processo di caricamento. Siete d'accordo?...

Gaetano Vituzzi
30-11-2005, 12:58
non vorrei dire una baggianata, ma questo potrebbe già essere utile come inizio: http://search.cpan.org/~mjd/Tie-File-0.96/lib/Tie/File.pm

gmesturini
30-11-2005, 13:08
Originariamente inviato da Gaetano Vituzzi
non vorrei dire una baggianata, ma questo potrebbe già essere utile come inizio: http://search.cpan.org/~mjd/Tie-File-0.96/lib/Tie/File.pm

non è una baggianata, difatti avevo già iniziato a girare su CPAN, trovando il link su http://www.perl.com - quello che stavo cercando di capire però è se qualcuno ha avuto esperienze sull'effettiva potenza di Perl in ambito di manipolazione dati, e se questa potenza può fare al caso mio dati i requisiti.

come ho detto ho già un embrione di parser, sviluppato però in Java. nel caso in cui qualcuno mi dica che - per questo tipo di mestiere - il Perl è indiscussamente il leader, allora sarei pronto a migrare - reference alla mano.

Gaetano Vituzzi
30-11-2005, 13:16
Originariamente inviato da gmesturini

come ho detto ho già un embrione di parser, sviluppato però in Java.

posta il diagramma di flusso di questo embrione!

shishii
30-11-2005, 19:26
Perl è dotatissimo nei campi della manipolazione di stringhe e di gestione di database.

Ho letto dei test che direbbero (ma non ho fatto controprove) che le espressioni regolari Perl sono veloci quanto quelle in C e molto più flessibili. Il che se vogliamo non è strano poichè la libreria Perl (interna) per le espressioni regolari è scritta in C e ottimizzato da anni di lavoro di affinamento.

concordo sul fatto che se riesci a produrre un file digeribile dagli strumenti di caricamento del DB di basso livello, cioè che bypassano l'SQL, guadagni molto tempo.

Perl è in grado di gestire bene anche files binari.

Per quanto riguarda la portabilità è ottima, tranne che lo script non faccia chiamate al sistema o a programmi esterni tramite cose come:
exec();
sysyem();
$var = ``;

gmesturini
01-12-2005, 14:39
Quello che sogno sarebbe il seguente processo, suddiviso il 3 step:

1. Parser Perl che accoppiando il file dati sorgente al rispettivo dizionario XML sia in grado di ripulire ogni mio file sorgente, producendo dei file puliti
2. Aggregatore Java per i calcoli sui dati, che prenda in pasto i file prodotti dal parser Perl e produca dei file che rispecchiano la struttura delle tabelle finali di aggregazione
3. Utility del DB per caricare i dati con API esposte tramite stored procedure

0. Il tutto wrappato in Java per gestire la pipe-line e il mutli-threading (in ogni caso devo esporre la funzionalità di caricamento con un EJB)

Perl possiede librerie interne per la lettura XML? Sono necessari moduli esterni? Secondo la vostra esperienza, se esistono dei moduli esterni per l'XML, quale giudicate il migliore? Per l'aggregazione avevo pensato a Java solo perché strutturato ad oggetti. Pensate che il Perl sia adatto ad eseguire anche aggregazioni - complesse - oppure condividete la mia scelta?

shishii
01-12-2005, 19:23
Non conosco java abbastanza per poterti dare info cosi complesse.

Perl abbonda di librerie XML e la scelta dipende da quello che devi fare. La documentazione è in genere molto chiara.

Perl è in grado di fare tutto anche da solo, per le prestazioni rispetto a Java non saprei dirti, penso che molto dipenda dal fatto se le librerie Perl che vai ad usare sono ottimizzate in C o sono Pure Perl (nel secondo caso portabili, ma più lente).

gmesturini
02-12-2005, 09:16
Java è object oriented, e per questo lo vedevo come candidato favorito rispetto a Perl per effettuare aggregazione di dati. Volendo usare una similitudine, direi che Perl è un fuoristrada, mentre Java è un'auto sportiva (non una formula 1, la formula 1 è il C++, ma comunque un'auto sportiva). La pulizia dei dati è sicuramente un lavoro offroad, quindi vedo in Perl la soluzione ideale. Mentre l'aggregazione prevede algoritmi puliti e complessi, zeppi di cicli e condizioni, per questo Java renderebbe le cose più semplici.

Loading