Ho scritto un'applicazione Scala (2.9.1-1) che deve elaborare diversi milioni di righe da una query di database. Io sono la conversione del ResultSet
ad un Stream
con la tecnica mostrata nella risposta ad una mia previous questions:Consumo di memoria di un flusso Scala parallelo
class Record(...)
val resultSet = statement.executeQuery(...)
new Iterator[Record] {
def hasNext = resultSet.next()
def next = new Record(resultSet.getString(1), resultSet.getInt(2), ...)
}.toStream.foreach { record => ... }
e questo ha funzionato molto bene.
Poiché il corpo della chiusura foreach
è molto CPU, e come testamento alla praticità di programmazione funzionale, se si aggiunge una .par
prima della foreach
, le chiusure ottenere condotte in parallelo con nessun altro sforzo, se non per fare sicuro che il corpo della chiusura sia thread-safe (è scritto in uno stile funzionale senza dati mutabili tranne che per la stampa su un log thread-safe).
Tuttavia, sono preoccupato per il consumo di memoria. È il .par
che causa l'intero set di risultati da caricare nella RAM, oppure l'operazione parallela carica solo il maggior numero di righe dei thread attivi? Ho assegnato 4G alla JVM (64-bit con -Xmx4g
) ma in futuro lo farò su più file e temo che alla fine avrò una memoria esaurita.
Esiste uno schema migliore per eseguire questo tipo di elaborazione parallela in modo funzionale? Ho mostrato questa applicazione ai miei colleghi come esempio del valore della programmazione funzionale e delle macchine multi-core.
solo curiosi. Che DBMS stai usando e quale API Scala DB interrogarla? – santiagobasulto
Accedo a un database Microsoft SQL Server 2012 in esecuzione su Windows Server 2008 R2 utilizzando il driver JDBC di Microsoft (http://msdn.microsoft.com/en-us/sqlserver/aa937724). – Ralph