2008-09-09 21 views
8

Tengo una aplicación que es una mezcla de Java y C++ en Solaris. Los aspectos Java del código ejecutan la interfaz de usuario web y establecen el estado en los dispositivos con los que estamos hablando, y el código C++ hace el crujido en tiempo real de los datos que regresan de los dispositivos. La memoria compartida se utiliza para pasar el estado del dispositivo y la información de contexto desde el código de Java hasta el código de C++. El código de Java usa una base de datos PostgreSQL para persistir en su estado.Alta disponibilidad y plataforma escalable para Java/C++ en Solaris

Nos encontramos con algunos cuellos de botella de rendimiento bastante severos, y en este momento la única forma en que podemos escalar es aumentar la memoria y el recuento de CPU. Estamos atrapados en la única caja física debido al diseño de memoria compartida.


El gran éxito aquí está siendo tomado por el código C++. La interfaz web es bastante poco utilizada para configurar los dispositivos; lo que realmente nos cuesta es manejar los volúmenes de datos que entregan los dispositivos una vez configurados.

Cada dato que obtenemos del dispositivo tiene un identificador que apunta al contexto del dispositivo, y tenemos que buscarlo. En este momento hay una serie de objetos de memoria compartida mantenidos por el código Java/UI y referidos por el código C++, y ese es el cuello de botella. Debido a esa arquitectura, no podemos mover el manejo de datos C++ a otra máquina. Necesitamos ser capaces de escalar para que varios subconjuntos de dispositivos puedan ser manejados por máquinas diferentes, pero luego perdemos la capacidad de hacer esa búsqueda de contexto, y ese es el problema que estoy tratando de resolver: cómo descargar el real- tiempo de procesamiento de datos a otras cajas al mismo tiempo que se puede referir al contexto del dispositivo.

Debo señalar que no tenemos control sobre el protocolo utilizado por los propios dispositivos, y no hay posibilidad de que la situación cambie.


sabemos que necesitamos a alejarse de este ser capaz de escalar a cabo mediante la adición de más máquinas a la agrupación, y yo estoy en las primeras etapas de la elaboración de exactamente cómo vamos a hacer esto.

En este momento estoy viendo a Terracotta como una forma de ampliar el código de Java, pero no he llegado a la conclusión de cómo escalar el C++ para que coincida.

Además de aumentar el rendimiento, también debemos tener en cuenta la alta disponibilidad. La aplicación debe estar disponible casi todo el tiempo, no completamente al 100%, lo que no es rentable, pero tenemos que hacer un trabajo razonable para sobrevivir a una interrupción de la máquina.

Si tuvieras que realizar la tarea que me han encomendado, ¿qué harías?

EDIT: Basado en los datos proporcionados por @john channing, estoy viendo tanto GigaSpaces como Gemstone. Oracle Coherence e IBM ObjectGrid parecen ser solo de Java.

Respuesta

5

Lo primero que haría es construir un modelo del sistema para mapear el flujo de datos y tratar de comprender con precisión dónde se encuentra el cuello de botella. Si puede modelar su sistema como pipeline, entonces debería poder utilizar la teoría de restricciones (la mayoría de la literatura trata sobre la optimización de procesos de negocios pero se aplica igualmente al software) para mejorar continuamente el rendimiento y eliminar el cuello de botella.

A continuación, recopilaré algunos datos empíricos difíciles que caracterizan con precisión el rendimiento de su sistema. Es algo así como un cliché que no se puede administrar lo que no se puede medir, pero he visto a muchas personas intentar optimizar un sistema de software basado en corazonadas y fallar miserablemente.

Luego usaría Pareto Principle (80/20 rule) para elegir la pequeña cantidad de cosas que producirán las mayores ganancias y centrarme solo en ellas.

Para escalar horizontalmente una aplicación Java, he usado ampliamente Oracle Coherence. Aunque algunos lo descartan como un distributed hashtable muy costoso, la funcionalidad es mucho más rica que eso y, por ejemplo, puede acceder directamente a los datos en el caché desde C++ code.

Otras alternativas para escalar horizontalmente su código Java serían Giga Spaces, IBM Object Grid o Gemstone Gemfire.

Si su código C++ es sin estado y se usa exclusivamente para el cálculo numérico, puede consultar la distribución del proceso utilizando ICE Grid, que tiene enlaces para todos los idiomas que está utilizando.

+0

Aquí hay algunos enlaces excelentes, John. Gracias. Tengo algo de lectura que hacer. – Andrew

1

Tiene que escalar hacia los lados y hacia afuera. Tal vez algo como un message queue podría ser el back-end entre el frontend y el crujido.

1

Andrew, (además de modelar como una tubería, etc.), medir cosas es importante. ¿Has ejecutado un generador de perfiles sobre el código y obtuviste las métricas de dónde pasó la mayor parte del tiempo?

Para el código de la base de datos, ¿con qué frecuencia cambia? ¿Estás buscando almacenamiento en caché en este momento? Supongo que ha mirado índices, etc. sobre los datos para acelerar el Db.

¿Qué niveles de tráfico tiene en la parte delantera? ¿Estás almacenando en caché las páginas web? (No es demasiado difícil decir que use una API de tipo JMS para comunicarse entre componentes. Luego puede poner el componente de Página Web en una máquina (o más) y luego poner el código de integración (C++) en otra, y para muchos JMS los productos suelen ser api nativos de C++, es decir, me viene a la mente ActiveMQ), pero realmente ayuda saber cuánto tiempo está disponible en Web (JSP?), C++, operaciones de base de datos.

¿La base de datos está almacenando datos comerciales, o también se usa para pasar datos entre Java y C++? ¿Dice que está utilizando la memoria compartida no JNI? ¿Qué nivel de multi-threading existe actualmente en la APLICACIÓN? ¿Podría describir el código como de naturaleza síncrona o asíncrona?

Existe una relación física entre el código de Solaris y los dispositivos que se deben mantener (es decir, todos los dispositivos se registran con el código de C++, o se puede especificar). es decir. si pusiera un equilibrador de carga web en la interfaz, y acaba de colocar 2 máquinas hoy, ¿cuál es la relación entre los dispositivos administrados por una caja inicializada por adelantado o por adelantado?

¿Cuáles son los requisitos de HA? es decir. solo informacion del estado? ¿Puede el HA hacerse solo en el nivel web al agrupar los datos de la sesión?

¿Está funcionando el DB en otra máquina?

¿Qué tan grande es la base de datos? ¿Ha optimizado sus consultas, es decir. intentado usar combinaciones explícitas internas/externas a veces ayuda versus subconsultas anidadas (algo). (otra vez mira las estadísticas sql).

Cuestiones relacionadas