He escrito una aplicación Scala (2.9.1-1) que necesita procesar varios millones de filas de una consulta de base de datos. Estoy convirtiendo el ResultSet
a un Stream
utilizando la técnica mostrada en la respuesta a una de mis previous questions:Consumo de memoria de un Scala Stream paralelo
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 => ... }
y esto ha funcionado muy bien.
Puesto que el cuerpo del cierre foreach
es muy intensivo de la CPU, y como un testimonio de la viabilidad de la programación funcional, si añado un .par
antes de la foreach
, los cierres de conseguir corrido en paralelo con ningún otro esfuerzo, excepto para hacer Asegúrese de que el cuerpo del cierre sea seguro para hilos (está escrito en un estilo funcional sin datos variables excepto la impresión en un registro seguro para subprocesos).
Sin embargo, me preocupa el consumo de memoria. ¿El .par
hace que todo el conjunto de resultados se cargue en la RAM, o la operación en paralelo carga solo tantas filas como hilos activos? He asignado 4G a la JVM (64 bits con -Xmx4g
) pero en el futuro lo ejecutaré en incluso más filas y me preocupará que eventualmente me salga la memoria.
¿Existe un mejor patrón para realizar este tipo de procesamiento paralelo de manera funcional? He estado mostrando esta aplicación a mis compañeros de trabajo como un ejemplo del valor de la programación funcional y las máquinas multi-core.
Sólo courious. ¿Qué DBMS estás usando y qué API de Scala DB para consultar? – santiagobasulto
Estoy accediendo a una base de datos de Microsoft SQL Server 2012 que se ejecuta en Windows Server 2008 R2 utilizando el controlador JDBC de Microsoft (http://msdn.microsoft.com/en-us/sqlserver/aa937724). – Ralph