Python, PyTables, Java-atando todos juntos
import tables python (4)
Esta es una pregunta épica, y hay muchas consideraciones. Como no mencionó ningún rendimiento específico ni limitaciones arquitectónicas, intentaré ofrecer las mejores sugerencias.
El plan inicial de usar PyTables como una capa intermedia entre sus otros elementos y los archivos de datos parece sólido. Sin embargo, una de las restricciones de diseño que no se mencionó es una de las más críticas de todo el procesamiento de datos: cuál de estas tareas de procesamiento de datos se puede realizar en un estilo de procesamiento por lotes y qué tareas de procesamiento de datos son más una transmisión en vivo.
Esta diferencia entre "sabemos exactamente nuestra entrada y salida y solo podemos hacer el procesamiento" (lote) y "sabemos nuestra entrada y lo que debe estar disponible para otra cosa que preguntar" (en vivo) hace toda la diferencia a una pregunta arquitectónica . Mirando su diagrama, hay varias relaciones que implican los diferentes estilos de procesamiento.
Además, en su diagrama tiene componentes de diferentes tipos, todos con los mismos símbolos. Hace que sea un poco difícil analizar el rendimiento y la eficiencia esperados.
Otra contraintensidad que es importante es su infraestructura de TI. ¿Tienes almacenamiento de red de alta velocidad disponible? Si lo hace, los archivos intermedios se convierten en una forma brillante, simple y rápida de compartir datos entre los elementos de su infraestructura para todas las necesidades de procesamiento por lotes. Usted mencionó la ejecución de su aplicación de uso de PyTables en el mismo servidor que ejecuta la simulación de Java. Sin embargo, eso significa que el servidor experimentará una carga tanto para escribir como para leer los datos. (Es decir, el entorno de simulación podría verse afectado por las necesidades de software no relacionado cuando consultan los datos).
Para responder a sus preguntas directamente:
- PyTables parece un buen partido.
- Python y Java se pueden comunicar de muchas maneras, pero considere un método de comunicación independiente del lenguaje para que estos componentes puedan cambiarse más adelante si es necesario. Esto es tan simple como encontrar bibliotecas que admitan Java y Python y probarlas. La API que elija implementar con cualquier biblioteca debería ser la misma de todos modos. (XML-RPC estaría bien para la creación de prototipos, ya que está en la biblioteca estándar, los Protocol Buffers de Google o Thrift de Facebook son buenas opciones de producción. Pero no subestime lo grande y simple que es simplemente "escribir cosas en archivos intermedios" si los datos están Predecible y por lotes.
Para ayudar con el proceso de diseño más y satisfacer sus necesidades:
Es fácil mirar una pequeña pieza del rompecabezas, hacer algunas suposiciones razonables y saltar a la evaluación de la solución. Pero es incluso mejor considerar el problema de manera integral con una comprensión clara de sus limitaciones. Puedo sugerir este proceso:
- Crea dos diagramas de tu arquitectura actual, física y lógica.
- En el diagrama físico, cree cuadros para cada servidor físico y diagrame las conexiones físicas entre cada uno.
- Asegúrese de etiquetar los recursos disponibles para cada servidor y el tipo y los recursos disponibles para cada conexión.
- Incluya hardware físico que no esté involucrado en su configuración actual si pudiera ser útil. (Si tiene una SAN disponible, pero no la está utilizando, inclúyala en caso de que la solución lo desee).
- En el diagrama lógico, cree cuadros para cada aplicación que se ejecute en su arquitectura actual.
- Incluir bibliotecas relevantes como cuadros dentro de los cuadros de aplicación. (Esto es importante porque su diagrama de solución futura tiene actualmente PyTables como un cuadro, pero es solo una biblioteca y no puede hacer nada por sí mismo).
- Dibuje en recursos de disco (como los archivos HDF5 y CSV) como cilindros.
- Conecte las aplicaciones con flechas a otras aplicaciones y recursos según sea necesario. Dibuja siempre la flecha del "actor" al "objetivo". Así que si una aplicación escribe y un archivo HDF5, la flecha va de la aplicación al archivo. Si una aplicación lee un archivo CSV, la flecha va de la aplicación al archivo.
- Cada flecha debe estar etiquetada con el mecanismo de comunicación. Las flechas sin etiqueta muestran una relación, pero no muestran qué relación y, por lo tanto, no le ayudarán a tomar decisiones ni a comunicar restricciones.
- En el diagrama físico, cree cuadros para cada servidor físico y diagrame las conexiones físicas entre cada uno.
Una vez que haya terminado con estos diagramas, haga algunas copias de ellos, y luego, justo encima de ellos, comience a hacer garabatos de flujo de datos. Con una copia del diagrama para cada aplicación de "punto final" que necesita sus datos originales, comience en la simulación y finalice en el punto final con una flecha que fluye bastante sólida. Cada vez que su flecha de datos fluya a través de una flecha de comunicación / protocolo, tome nota de cómo cambian los datos (si corresponde).
En este punto, si usted y su equipo están de acuerdo con lo que hay en el papel, entonces han explicado su arquitectura actual de una manera que debería ser fácilmente comunicable a cualquier persona. (No solo ayudantes aquí en stackoverflow, sino también a jefes y gerentes de proyectos y otros portadores).
Para comenzar a planificar su solución, mire los diagramas de flujo de datos y avance desde el punto final hasta el punto inicial y cree una lista anidada que contenga todas las aplicaciones y el formato intermedio de regreso al inicio. Luego, enumere los requisitos para cada aplicación. Asegúrese de incluir:
- ¿Qué formatos de datos o métodos puede utilizar esta aplicación para comunicarse?
- ¿Qué datos realmente quiere? (¿Es esto siempre lo mismo o cambia por capricho dependiendo de otros requisitos?)
- ¿Con qué frecuencia lo necesita?
- Aproximadamente cuántos recursos necesita la aplicación.
- ¿Qué hace la aplicación ahora que no lo hace tan bien?
- ¿Qué puede hacer esta aplicación ahora que ayudaría, pero no lo está haciendo?
Si hace un buen trabajo con esta lista, puede ver cómo esto ayudará a definir qué protocolos y soluciones elige. Observa las situaciones en las que los datos cruzan una línea de comunicación y compara la lista de requisitos para ambos lados de la comunicación.
Ya ha descrito una situación particular en la que tiene un poco de código de procesamiento posterior Java que está haciendo "uniones" en tablas de datos en archivos CSV, eso es un "hágalo ahora pero no lo hace bien". Entonces miras al otro lado de esa comunicación para ver si el otro lado puede hacer eso bien. En este punto, el otro lado es el archivo CSV y antes de eso, la simulación, entonces no, no hay nada que pueda hacer eso mejor en la arquitectura actual.
Así que ha propuesto una nueva aplicación de Python que utiliza la biblioteca de PyTables para mejorar ese proceso. ¡Suena bien hasta ahora! Pero en tu próximo diagrama, agregaste un montón de otras cosas que hablan sobre "PyTables". Ahora hemos superado la comprensión del grupo aquí en StackOverflow, porque no conocemos los requisitos de esas otras aplicaciones. Pero si realiza la lista de requisitos como se mencionó anteriormente, sabrá exactamente qué considerar. Tal vez su aplicación Python que usa PyTables para proporcionar consultas en los archivos HDF5 puede admitir todas estas aplicaciones. Tal vez solo sea compatible con uno o dos de ellos. Tal vez proporcionará consultas en vivo al post-procesador, pero periódicamente escribirá archivos intermedios para las otras aplicaciones. No podemos decirlo, pero con la planificación, usted puede.
Algunas pautas finales:
- ¡Mantén las cosas simples! El enemigo aquí es la complejidad. Cuanto más compleja sea su solución, más difícil será la solución de implementar y más probable será que falle. Usa las operaciones con menos números, usa las operaciones menos complejas. En ocasiones, solo una aplicación para manejar las consultas de todas las demás partes de su arquitectura es la más sencilla. A veces es mejor una aplicación para manejar consultas "en vivo" y una aplicación por separado para manejar "solicitudes por lotes".
- ¡Mantén las cosas simples! ¡Tiene mucha importancia! No escriba nada que ya se pueda hacer por usted. (Esta es la razón por la cual los archivos intermedios pueden ser tan grandes, el sistema operativo maneja todas las partes difíciles). Además, usted menciona que una base de datos relacional es una sobrecarga excesiva, pero considera que una base de datos relacional también viene con una consulta muy expresiva y bien conocida. El lenguaje, el protocolo de comunicación de red que lo acompaña, ¡ y no tiene que desarrollar nada para usarlo! Cualquiera que sea la solución que surja debe ser mejor que usar la solución estándar que funcionará, por cierto, muy bien, o no es la mejor solución.
- Consulte la documentación de su capa física con frecuencia para comprender el uso de recursos de sus consideraciones. Un enlace de red lento o poner demasiado en un servidor puede descartar buenas soluciones.
- Guarde esos documentos. Decida lo que decida, la documentación que generó en el proceso es valiosa. Wiki-ellos o archívalos para que puedas sacarlos nuevamente cuando el tema aparezca.
Y la respuesta a la pregunta directa, "¿Cómo lograr que Python y Java jueguen bien juntos?" es simplemente "usar un método de comunicación de lenguaje agnóstico". La verdad del asunto es que Python y Java no son importantes para describir el conjunto de problemas. Lo importante es la información que fluye a través de él. Cualquier cosa que pueda compartir datos de manera fácil y efectiva va a estar bien.
Pregunta en pocas palabras
¿Cuál es la mejor manera de hacer que Python y Java jueguen bien entre ellos?
Explicación más detallada
Tengo una situación algo complicada. Haré mi mejor esfuerzo para explicar tanto en imágenes como en palabras. Aquí está la arquitectura actual del sistema:
Arquitectura actual del sistema http://i50.tinypic.com/2s6lutk.png
Tenemos una simulación de modelado basada en agentes escrita en Java. Tiene opciones de escribir localmente en archivos CSV o de forma remota a través de una conexión a un servidor Java a un archivo HDF5 . Cada ejecución de simulación escupe más de un gigabyte de datos, y ejecutamos la simulación docenas de veces. Necesitamos poder agregar en varias ejecuciones del mismo escenario (con diferentes semillas aleatorias) para ver algunas tendencias (por ejemplo, mín, máx, mediana, media). Como puedes imaginar, tratar de moverte por todos estos archivos CSV es una pesadilla; Hay varios archivos producidos por ejecución, y como he dicho, algunos de ellos son enormes. Esa es la razón por la que hemos estado intentando avanzar hacia una solución HDF5, donde todos los datos para un estudio se almacenan en un solo lugar, en lugar de dispersos en docenas de archivos de texto sin formato. Además, dado que es un formato de archivo binario, debería poder obtener un ahorro significativo de espacio en comparación con CSVS sin comprimir.
Como muestra el diagrama, el procesamiento posterior actual que hacemos de los datos de salida sin procesar de la simulación también tiene lugar en Java y se lee en los archivos CSV producidos por la salida local. Este módulo de postprocesamiento usa JFreeChart para crear algunos cuadros y gráficos relacionados con la simulación.
El problema
Como mencioné anteriormente, los CSV son realmente insostenibles y no están escalando bien a medida que generamos más y más datos a partir de la simulación. Además, el código de posprocesamiento está haciendo más de lo que debería, esencialmente realizando el trabajo de una base de datos relacional de un hombre muy, muy pobre (haciendo uniones a través de ''tablas'' (archivos csv) basadas en claves externas (las ID de agentes únicas También es difícil en este sistema visualizar los datos de otras maneras (por ejemplo, Prefuse, Processing, JMonkeyEngine obteniendo un subconjunto de los datos en bruto para jugar en MatLab o SPSS).
¿Solución?
Mi grupo decidió que realmente necesitamos una forma de filtrar y consultar los datos que tenemos, así como realizar combinaciones de tablas cruzadas. Dado que esto es una situación de lectura una vez de escritura única, realmente no necesitamos la sobrecarga de una base de datos relacional real; en lugar de eso, solo necesitamos alguna forma de poner un mejor extremo en los archivos HDF5. Encontré algunos artículos sobre esto, como uno que describe cómo usar XQuery como el lenguaje de consulta en archivos HDF5 , pero el artículo describe tener que escribir un compilador para convertir de XQuery / XPath a las llamadas HDF5 nativas, mucho más allá de nuestras necesidades. Introduzca PyTables . Parece que hace exactamente lo que necesitamos (proporciona dos formas diferentes de consultar datos, ya sea mediante la comprensión de la lista de Python o mediante búsquedas en el núcleo (nivel C)) .
La arquitectura propuesta que imagino es la siguiente: Arquitectura visualizada http://i46.tinypic.com/9aseg3.png
Lo que no estoy realmente seguro de cómo hacer es vincular el código de Python que se escribirá para la consulta, con el código de Java que sirve los archivos HDF5 y el código de Java que realiza el procesamiento posterior de los datos. Obviamente, querré reescribir gran parte del código de post-procesamiento que implícitamente está haciendo consultas y, en cambio, dejar que las excelentes PyTables lo hagan de manera mucho más elegante.
Opciones de Java / Python
Una simple búsqueda en Google muestra algunas opciones para la comunicación entre Java y Python , pero soy tan nuevo en el tema que estoy buscando algunos conocimientos y críticas reales de la arquitectura propuesta. Parece que el proceso de Python debería ejecutarse en la misma máquina que Datahose para que los archivos .h5 grandes no se transfieran a través de la red, sino que las vistas filtradas, mucho más pequeñas, se transmitirían a los clientes. Pyro parece ser una opción interesante. ¿Alguien tiene experiencia con eso?
No estoy seguro si esto es una buena etiqueta. No pude encajar todos mis comentarios en un comentario normal, y la publicación no tiene actividad durante 8 meses.
¿Sólo quería ver cómo te iba? Tengo una situación muy similar en la que trabajo, solo la simulación está escrita en C y el formato de almacenamiento son archivos binarios. Cada vez que un jefe quiere un resumen diferente, tenemos que hacer / modificar el código manuscrito para hacer resúmenes. Nuestros archivos binarios tienen un tamaño de aproximadamente 10 GB y hay uno de estos para cada año de simulación, por lo que, como pueden imaginar, las cosas se ponen peludas cuando queremos ejecutarlas con diferentes semillas y demás.
Acabo de descubrir pyTables y tuve una idea similar a la tuya. Esperaba cambiar nuestro formato de almacenamiento a hdf5 y luego ejecutar nuestros informes / consultas de resumen utilizando pytables. Parte de esto implica unir tablas de cada año. ¿Tuviste mucha suerte al hacer este tipo de "combinaciones" usando pytables?
No hagas esto más complejo de lo que necesita ser.
Su proceso Java puede, simplemente, generar un subproceso separado para ejecutar sus consultas de PyTables. Deje que el sistema operativo haga lo que OS hace mejor.
Su aplicación Java puede simplemente bifurcar un proceso que tiene los parámetros necesarios como opciones de línea de comandos. Luego, su Java puede pasar a la siguiente cosa mientras Python se ejecuta en segundo plano.
Esto tiene enormes ventajas en términos de rendimiento concurrente. El "backend" de Python se ejecuta simultáneamente con la "interfaz" de su simulación de Java.
Puede probar Jython , un intérprete de Python para la JVM que puede import
clases de Java.
Página de inicio del proyecto Jython
Desafortunadamente, eso es todo lo que sé sobre el tema.