2010-05-30 14 views
30

Tengo grandes cantidades de datos (unos pocos terabytes) y acumulando ... Están contenidos en muchos archivos de texto plano delimitados por tabuladores (cada uno de aproximadamente 30 MB). La mayor parte de la tarea implica leer los datos y agregar (sumando/promediando + transformaciones adicionales) sobre las observaciones/filas basadas en una serie de declaraciones de predicados, y luego guardar la salida como archivos de texto, HDF5 o SQLite, etc. Normalmente uso R para tales tareas, pero me temo que esto puede ser un poco grande. Algunas soluciones candidatas son agran cantidad de datos en muchos archivos de texto: ¿cómo procesarlos?

  1. escribir toda la cosa en C (o Fortran)
  2. importar los archivos (tablas) en una base de datos relacional directa e a continuación, saque trozos en R o Python (algunos de las transformaciones no son susceptibles de soluciones SQL puros)
  3. escribir toda la cosa en Python

Te (3) sea una mala idea? Sé que puede ajustar las rutinas C en Python, pero en este caso, dado que no hay nada computacionalmente prohibitivo (por ejemplo, rutinas de optimización que requieren muchos cálculos iterativos), creo que la E/S puede ser un cuello de botella tan importante como el cálculo. ¿Tiene alguna recomendación sobre consideraciones o sugerencias adicionales? Gracias

Editar Gracias por su respuesta. Parece haber opiniones contradictorias sobre Hadoop, pero en cualquier caso no tengo acceso a un clúster (aunque puedo usar varias máquinas sin red) ...

+1

Gran pregunta, este parece ser el mismo problema que estoy teniendo con los datos de secuencia biológica. – Stedy

Respuesta

13

(3) no es necesariamente una mala idea - Python hace que sea más fácil procesar el archivo "CSV" (ya pesar de que la C representa la pestaña Coma, ya que un separador es igual de fácil de manejar) y, por supuesto, obtiene casi tanto ancho de banda en operaciones de E/S como en cualquier otro idioma. En cuanto a otras recomendaciones, numpy, además del cálculo rápido (que puede que no necesite de acuerdo con sus declaraciones) proporciona matrices multidimensionales muy prácticas y flexibles, que pueden ser bastante útiles para sus tareas; y el módulo de biblioteca estándar multiprocessing le permite explotar múltiples núcleos para cualquier tarea que sea fácil de paralelizar (importante ya que casi todas las máquinas en estos días tienen múltiples núcleos ;-).

+0

Creo que intentaré Python, NumPy y multiprocesamiento ... Muchas gracias. – hatmatrix

+0

De acuerdo. La supuesta penalidad de rendimiento de Python no tiene mucha apariencia en el mundo real. –

6

Eche un vistazo a Disco. Es un motor MapReduce ligero distribuido, escrito en aproximadamente 2000 líneas de Erlang, pero diseñado específicamente para el desarrollo de Python. Admite no solo trabajar en sus datos, sino también almacenar una replicación de manera confiable. Acaban de lanzar la versión 0.3, que incluye una capa de indexación y base de datos.

+0

Gracias - Tendré que estar pendiente de Disco. Sin embargo, no pude encontrar mucha documentación en la capa de la base de datos, y tal vez el framework MapReduce no sea apropiado para mi hardware en este momento ... – hatmatrix

+0

Discodb es una base de datos de gente pobre. Básicamente es solo una tabla hash distribuida que se encuentra encima de ddfs. No sé mucho sobre esto yo mismo, ya que es muy nuevo. –

2

En caso de que tenga un grupo de máquinas, puede paralelizar su aplicación utilizando Hadoop Mapreduce. Aunque Hadoop está escrito en Java, también puede ejecutar Python. Puede consultar el siguiente enlace para ver los indicadores al paralelizar el código: PythonWordCount

+0

Gracias ~ no tengo un clúster de máquinas en red para esto ... – hatmatrix

1

Sí. ¡Tienes razón! La E/S costaría la mayor parte de su tiempo de procesamiento. No sugiero que use sistemas distribuidos, como hadoop, para esta tarea.

Su tarea se puede hacer en una estación de trabajo modesta. No soy un experto en Python, creo que tiene soporte para programación asincrónica. En F #/.Net, la plataforma tiene soporte para eso. Una vez estaba haciendo un trabajo de procesamiento de imágenes, cargar imágenes de 20K en el disco y transformarlas en vectores de características solo cuesta varios minutos en paralelo.

en general, cargue y procese sus datos en paralelo y guarde el resultado en la memoria (si es pequeña), en la base de datos (si es grande).

+0

Gracias - Eso espero. Todo lo que tengo a mi disposición son unas pocas estaciones de trabajo modestas (y alguna vez) – hatmatrix

4

Con terabytes, querrá paralelizar sus lecturas en muchos discos; así que podría ir directamente a Hadoop.

Utilice Pig o Hive para consultar los datos; ambos tienen un amplio soporte para transformaciones definidas por el usuario, por lo que debería poder implementar lo que necesita hacer usando un código personalizado.

+0

No sabía nada sobre Pig o Hive - lo tendré en cuenta ... – hatmatrix

13

Ok, entonces para ser diferente, ¿por qué no?

  • Parece que sabes R por lo que puede llegar a código de trabajo rápidamente
  • 30 MB por archivo no es grande en la estación de trabajo estándar con unos cuantos GB de RAM
  • la variante read.csv() de read.table() puede ser muy eficiente si especifica los tipos de columnas mediante el argumento colClasses: en lugar de guestimating tipos de conversión, estos serán manejados de manera eficiente
  • el cuello de botella que aquí es de e/S del disco y que es el mismo para todos los idiomas
  • R tiene multicore para configurar el procesamiento paralelo en máquinas con núcleo múltiple (similar al multiprocesamiento de Python, al parecer)
  • Si desea emplear la estructura "embarazosamente paralela" del problema, R tiene varios paquetes que son adecuados para datos- problemas paralelos: Ej. snow y foreach pueden implementarse en una sola máquina o en un conjunto de máquinas en red.
+0

Creo que podría hacerse con R, pero una parte de mí siente que no es la herramienta correcta? Sin embargo, con todas las consideraciones adicionales que ha incluido, ciertamente podría funcionar ... Recientemente comencé a usar data.frame (escanear (nombre de archivo, qué = lista (...))) para tratar de acelerar el entrada, pero especificar las clases colC puede ser otra buena idea. Gracias ~ – hatmatrix

+2

@Stephen No olvides revisar este hilo http://stackoverflow.com/questions/1727772/quickly-reading-very-large-tables-as-dataframes-in-r – Marek

+0

¡Gracias! He sido un usuario de R desde hace mucho tiempo, pero esto es muy útil – hatmatrix

2

Cuando dice "acumulando", entonces la solución (2) parece más adecuada para el problema.
Después de la carga inicial en la base de datos, solo actualiza la base de datos con archivos nuevos (¿diarios, semanales? Depende de la frecuencia con que los necesite).

En los casos (1) y (3) necesita procesar archivos cada vez (lo que se dijo anteriormente como la mayor cantidad de tiempo/recursos), a menos que encuentre una forma de almacenar los resultados y actualizarlos con archivos nuevos.

Puede usar R para procesar archivos de csv a, por ejemplo, la base de datos SQLite.

+0

Ah sí, entiendo lo que quiere decir ... pero una vez que procese cada archivo de texto, almacenaré los resultados más probablemente en un archivo SQLite y trabajo con estos resultados para el posterior análisis. La agregación que hago es una especie de promediación del tiempo (esto es datos longitudinales), así que no tendré que volver a importar archivos anteriores al analizar el actual (razón por la cual MapReduce tendría sentido, supongo ...). – hatmatrix

4

He tenido buena suerte al usar R con Hadoop en Amazon's Elastic Map Reduce. Con EMR pagas solo por el tiempo de la computadora que usas y AMZN se encarga de girar y girar las instancias. Exactamente cómo estructurar el trabajo en EMR realmente depende de cómo está estructurado su flujo de trabajo de análisis. Por ejemplo, ¿todos los registros necesarios para un trabajo están completamente dentro de cada csv o necesita bits de cada csv para completar un análisis?

He aquí algunos recursos que pueden resultar útiles:

El problema que mencioné en mi publicación de blog es más uno de estar vinculado a la CPU, no a IO. Sus problemas son más IO, pero los consejos para cargar bibliotecas y archivos caché pueden ser útiles.

Si bien es tentador tratar de meterlo dentro o fuera de una base de datos relacional, recomiendo considerar cuidadosamente si realmente necesita todos los gastos generales de un RDB. Si no lo hace, puede crear un cuello de botella y un desafío de desarrollo sin una recompensa real.

+0

Muchas gracias - ¡Supongo que queda una pregunta sobre si vale la pena sobrecargar la transferencia de datos a su infraestructura! – hatmatrix

Cuestiones relacionadas