2014-07-09 40 views
8

Sono impressionato dalla velocità di esecuzione delle trasformazioni, caricamento dei dati e facilità d'uso di Pandas e voglio sfruttare tutte queste belle proprietà (tra le altre) per modellare alcuni insiemi di dati di grandi dimensioni (~ 100-200k righe, < 20 colonne). L'obiettivo è quello di lavorare con i dati su alcuni nodi di calcolo, ma anche di fornire una vista dei set di dati in un browser tramite Flask.Pandas come memoria dati veloce per l'applicazione Flask

Attualmente sto utilizzando un database Postgres per archiviare i dati, ma l'importazione (proveniente dai file CSV) dei dati è lenta, noiosa e soggetta a errori e il recupero dei dati dal database e l'elaborazione non è molto Più facile. I dati non verranno mai modificati una volta importati (nessuna operazione CRUD), quindi ho pensato che fosse ideale per memorizzarli come diversi panda DataFrame (memorizzati nel formato hdf5 e caricati tramite pytables).

La domanda è:

(1) Si tratta di una buona idea e quali sono le cose a cui prestare attenzione? (Ad esempio, non mi aspetto che i problemi di concorrenza come DataFrame s siano (dovrebbero?) Essere apolidi e immutabili (curati dal lato dell'applicazione)). Per quale altro motivo bisogna essere sorvegliati?

(2) Come farei per mettere in cache i dati una volta che è stato caricato dal file hdf5 in un DataFrame, quindi non è necessario caricarlo per ogni richiesta client (almeno il datafram più recente/frequente). Flask (o werkzeug) ha una classe SimpleCaching, ma, internamente, raccoglie i dati e despassa i dati memorizzati nella cache all'accesso. Mi chiedo se sia necessario nel mio caso specifico (supponendo che l'oggetto memorizzato nella cache sia immutabile). Inoltre, è un metodo di caching così semplice da utilizzare quando il sistema viene distribuito con Gunicorn (è possibile avere dati statici (la cache) e richieste simultanee (processo differente?) Accedere alla stessa cache?).

Mi rendo conto che queste sono molte domande, ma prima di investire più tempo e costruire una dimostrazione di concetto, ho pensato di ottenere un feedback qui. Ogni pensiero è benvenuto.

+0

Interessante domanda. Mi occupo anche di grandi quantità di dati di sola lettura, e spesso mi chiedo un approccio snello e pragmatico per farlo. Posso chiederti quanti dischi hai a che fare? (Ho circa 300 milioni = circa 4 GB di dati) – Hexatonic

+0

È nell'intervallo di decine di migliaia (forse 100.000 al massimo). Mi sono stabilito con hdf5 e sono molto contento di questa decisione e dell'uso di Pandas (sono passati quasi 2 anni fa). La cosa buona di hdf5 e pytables è che puoi eseguire query su disco senza caricare l'intero file. Con il mio piccolo set di dati, tuttavia, non ho mai avuto bisogno di farlo (nel tuo caso potrebbe essere diverso). Sono rimasto particolarmente colpito dalla velocità di I/o di leggere un file hdf5 rispetto a una query sql. – orange

risposta

3

risposte a alcuni aspetti di quello che stai chiedendo:

Non è del tutto chiaro dalla descrizione se si hanno le tabelle nel database SQL solo, memorizzati come file HDF5 o entrambi. Un aspetto da tenere a mente è che se si utilizza Python 2.x e si creano i file tramite la classe HDFStore di pandas, tutte le stringhe verranno sottoposte a pickling, il che porterà a file abbastanza grandi. Ad esempio, puoi anche generare pandas DataFrame direttamente dalle query SQL utilizzando read_sql.

Se non sono necessarie operazioni relazionali, direi di abbandonare il server Postgre, se è già impostato e in futuro potrebbe essere necessario continuare a utilizzare il server SQL. La cosa bella del server è che anche se non ti aspetti problemi di concorrenza, sarà gestito automaticamente per te usando (Flask-) SQLAlchemy causando meno mal di testa. In generale, se ti aspetti di aggiungere più tabelle (file), è meno importante avere un server database centrale che mantenere più file in giro.

In qualsiasi modo, Flask-Cache sarà tuo amico, utilizzando un backend memcached o redis. È quindi possibile memorizzare/memoizzare la funzione che restituisce un DataFrame preparato da un file SQL o HDF5. È importante sottolineare che è anche possibile memorizzare nella cache modelli che potrebbero avere un ruolo nella visualizzazione di tabelle di grandi dimensioni.

Si potrebbe, naturalmente, anche generare una variabile globale, ad esempio, dove si crea l'app Flask e si importa solo dove è necessario. Non ho provato questo e quindi non lo consiglio. Potrebbe causare tutti i tipi di problemi di concorrenza.

+0

Grazie Midnighter. Questi sono ottimi commenti. Ho i dati di massa in un database SQL, ma sto cercando di spostarlo perché causa troppo mal di testa. Alcuni degli altri dati possono essere modificati contemporaneamente, quindi continuo a utilizzare Postgres. Le variabili globali non hanno funzionato quando ho provato Gunicorn. Sembra che ogni lavoratore (asincrono) di Gunicorn abbia il proprio spazio di indirizzamento, quindi gestirà anche la propria cache (che non è veramente utile). – orange

+0

@orange Finora ho usato Apache solo per la distribuzione e lì ho dovuto passare a un modello in cui utilizzo solo un processo ma molti thread perché altrimenti richieste dello stesso utente sono state gestite da diversi processi che hanno causato problemi con la sessione. Devo ancora arrivare a fondo, però. Quindi in quel caso un globale dovrebbe funzionare bene. Mi chiedo, però, che cosa ti causa problemi quando lavori con SQL? Usando 'read_sql' puoi anche scrivere query complete e semplicemente passarle. – Midnighter

+1

Ho fatto alcuni test preliminari e ho notato che' read_sql' è più lento del caricamento del file 'HDF5' dal disco. Ma il problema più grande è che ho bisogno di importare (csv -> sql tables) i bulk data che impiegano molto tempo ed è anche piuttosto poco pratico (devo decidere quali colonne usare/importare al momento dell'importazione. nel formato sorgente (o la conversione in 'HDF5') mi consente di considerare le colonne in seguito). – orange