Pregunta

Tengo una aplicación que es una combinación 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++ procesa en tiempo real los datos que regresan de los dispositivos.La memoria compartida se utiliza para pasar información de contexto y estado del dispositivo desde el código Java al código C++.El código Java utiliza una base de datos PostgreSQL para conservar su estado.

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


El gran éxito aquí lo está recibiendo el código C++.La interfaz web se utiliza bastante ligeramente para configurar los dispositivos;Donde realmente estamos luchando es en 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 debemos buscarlo.En este momento hay una serie de objetos de memoria compartida que son mantenidos por el código Java/UI y a los que hace referencia el código C++, y ese es el cuello de botella.Debido a esa arquitectura no podemos mover el manejo de datos de C++ a otra máquina.Necesitamos poder escalar para que diferentes máquinas puedan manejar varios subconjuntos de dispositivos, pero luego perdemos la capacidad de realizar esa búsqueda de contexto, y ese es el problema que estoy tratando de resolver:cómo descargar el procesamiento de datos en tiempo real a otras cajas y al mismo tiempo poder consultar el contexto del dispositivo.

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


Sabemos que necesitamos alejarnos de esto para poder escalar agregando más máquinas al clúster, y estoy en las primeras etapas para determinar exactamente cómo lo haremos.

En este momento estoy considerando Terracotta como una forma de ampliar el código Java, pero no he llegado tan lejos como para descubrir cómo ampliar el código C++ para que coincida.

Además de escalar para mejorar el rendimiento, también debemos considerar la alta disponibilidad.La aplicación debe estar disponible prácticamente todo el tiempo, no al 100%, lo cual no es rentable, pero debemos hacer un trabajo razonable para sobrevivir a una interrupción de la máquina.

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

EDITAR:Según los datos proporcionados por @john channing, estoy analizando tanto GigaSpaces como Gemstone.Oracle Coherence e IBM ObjectGrid parecen ser solo para Java.

¿Fue útil?

Solución

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

A continuación, recopilaría algunos datos empíricos concretos que caractericen con precisión el rendimiento de su sistema.Es una especie de cliché que no se puede gestionar lo que no se puede medir, pero he visto a muchas personas intentar optimizar un sistema de software basándose en corazonadas y fracasar estrepitosamente.

Entonces usaría el Principio de Pareto (regla 80/20) elegir la pequeña cantidad de cosas que producirán las mayores ganancias y centrarse solo en ellas.

Para escalar una aplicación Java horizontalmente, he usado Coherencia del Oráculo extensamente.Aunque algunos lo tachan de muy caro tabla hash distribuida, la funcionalidad es mucho más rica que eso y puede, por ejemplo, acceder directamente a los datos en el caché desde código C ++ .

Otras alternativas para escalar horizontalmente su código Java serían Gigaespacios, Cuadrícula de objetos de IBM o Fuego de gema de piedras preciosas.

Si su código C++ no tiene estado y se usa exclusivamente para procesar números, podría considerar distribuir el proceso usando Rejilla de hielo que tiene enlaces para todos los idiomas que está utilizando.

Otros consejos

Necesitas escalar hacia los lados y hacia afuera.Tal vez algo como un cola de mensajes podría ser el backend entre el frontend y el crujido.

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

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

¿Qué niveles de tráfico tiene en el frente?¿Está almacenando en caché páginas web?(No es demasiado difícil decir que utilice una API de tipo JMS para comunicarse entre componentes.Luego puede colocar el componente de la página web en una máquina (o más) y luego colocar el código de integración (c++) en otra, y para muchos productos JMS generalmente hay API nativas de C++, es decir.Me viene a la mente ActiveMQ), pero realmente ayuda saber cuánto tiempo se dedica a operaciones web (¿JSP?), C++ y bases de datos.

¿La base de datos almacena datos comerciales o también se utiliza para pasar datos entre Java y C++?¿Dice que está utilizando memoria compartida, no JNI?¿Qué nivel de subprocesos múltiples existe actualmente en la aplicación?¿Describirías el código como de naturaleza sincrónica o asíncrona?

¿Existe una relación física entre el código Solaris y los dispositivos que deben mantenerse (es decir,¿Todos los dispositivos se registran con el código C++, o se puede especificar eso)?es decir.Si tuviera que colocar un equilibrador de carga web en la interfaz y simplemente colocar 2 máquinas hoy, ¿la relación de qué dispositivos son administrados por una caja inicializada por adelantado o por adelantado?

¿Cuáles son los requisitos de HA?es decir.¿Solo indica información?¿Se puede realizar HA solo en el nivel web agrupando los datos de la sesión?

¿La base de datos se está ejecutando en otra máquina?

¿Qué tamaño tiene la base de datos?¿Ha optimizado sus consultas, es decir?Intenté usar uniones internas/externas explícitas a veces ayuda en comparación con las subconsultas anidadas (a veces).(nuevamente mire las estadísticas de SQL).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top