Pergunta

Eu tenho um aplicativo que é uma mistura de Java e C++ no Solaris.Os aspectos Java do código executam a UI da web e estabelecem o estado nos dispositivos com os quais estamos conversando, e o código C++ processa em tempo real os dados que retornam dos dispositivos.A memória compartilhada é usada para passar informações de contexto e estado do dispositivo do código Java para o código C++.O código Java usa um banco de dados PostgreSQL para persistir seu estado.

Estamos enfrentando alguns gargalos de desempenho bastante graves e, no momento, a única maneira de escalar é aumentar a memória e a contagem de CPU.Estamos presos em uma caixa física devido ao design da memória compartilhada.


O grande sucesso aqui está sendo causado pelo código C++.A interface da web é levemente usada para configurar os dispositivos;O que realmente estamos enfrentando é lidar com os volumes de dados que os dispositivos entregam depois de configurados.

Cada dado que recebemos do dispositivo contém um identificador que aponta para o contexto do dispositivo, e precisamos pesquisar isso.No momento, há uma série de objetos de memória compartilhada que são mantidos pelo código Java/UI e referenciados pelo código C++, e esse é o gargalo.Por causa dessa arquitetura, não podemos mover o tratamento de dados C++ para outra máquina.Precisamos ser capazes de expandir para que vários subconjuntos de dispositivos possam ser manipulados por máquinas diferentes, mas então perdemos a capacidade de fazer essa pesquisa de contexto, e esse é o problema que estou tentando resolver:como descarregar o processamento de dados em tempo real para outras caixas e ainda poder consultar o contexto do dispositivo.

Devo observar que não temos controle sobre o protocolo usado pelos próprios dispositivos e não há possibilidade de que a situação mude.


Sabemos que precisamos nos afastar disso para podermos expandir adicionando mais máquinas ao cluster, e estou nos estágios iniciais para definir exatamente como faremos isso.

No momento, estou olhando para o Terracotta como uma forma de dimensionar o código Java, mas ainda não descobri como dimensionar o C++ para corresponder.

Além de dimensionar o desempenho, precisamos considerar também a alta disponibilidade.O aplicativo precisa estar disponível praticamente o tempo todo - não absolutamente 100%, o que não é econômico, mas precisamos fazer um trabalho razoável para sobreviver a uma interrupção da máquina.

Se você tivesse que realizar a tarefa que me foi dada, o que você faria?

EDITAR:Com base nos dados fornecidos por @john channing, estou analisando GigaSpaces e Gemstone.Oracle Coherence e IBM ObjectGrid parecem ser apenas Java.

Foi útil?

Solução

A primeira coisa que eu faria é construir um modelo do sistema para mapear o fluxo de dados e tentar entender precisamente onde está o gargalo.Se você puder modelar seu sistema como um gasoduto, então você deverá ser capaz de usar a teoria das restrições (a maior parte da literatura é sobre otimização de processos de negócios, mas se aplica igualmente ao software) para melhorar continuamente o desempenho e eliminar o gargalo.

A seguir, eu coletaria alguns dados empíricos concretos que caracterizam com precisão o desempenho do seu sistema.É um clichê dizer que você não pode gerenciar o que não pode medir, mas tenho visto muitas pessoas tentarem otimizar um sistema de software com base em palpites e falharem miseravelmente.

Então eu usaria o Princípio de Pareto (regra 80/20) escolher o pequeno número de coisas que produzirão os maiores ganhos e focar apenas nelas.

Para dimensionar um aplicativo Java horizontalmente, usei Coerência Oráculo extensivamente.Embora alguns o considerem muito caro tabela hash distribuída, a funcionalidade é muito mais rica do que isso e você pode, por exemplo, acessar diretamente os dados no cache de Código C++ .

Outras alternativas para dimensionar horizontalmente seu código Java seriam Giga Espaços, Grade de objetos IBM ou Pedra Preciosa Pedra Preciosa.

Se o seu código C++ não tiver estado e for usado exclusivamente para processamento de números, você poderá distribuir o processo usando Grade de GELO que possui ligações para todos os idiomas que você está usando.

Outras dicas

Você precisa dimensionar lateralmente e diminuir.Talvez algo como um fila de mensagens poderia ser o backend entre o frontend e a análise.

Andrew, (além de modelar como pipeline, etc.), medir as coisas é importante.Você executou um criador de perfil no código e obteve métricas de onde a maior parte do tempo é gasta?

Para o código do banco de dados, com que frequência ele muda?Você está olhando para o cache no momento?Presumo que você tenha analisado índices, etc. sobre os dados para acelerar o banco de dados.

Que níveis de tráfego você tem no front-end?Você está armazenando páginas da web em cache?(Não é muito difícil dizer que use uma API do tipo JMS para comunicação entre componentes.Você pode então colocar o componente da página da Web em uma máquina (ou mais) e, em seguida, colocar o código de integração (c++) em outra, e para muitos produtos JMS geralmente existem APIs C++ nativas, ou seja.ActiveMQ vem à mente), mas realmente ajuda saber quanto tempo é dedicado à Web (JSP?), C++, operações de banco de dados.

O banco de dados está armazenando dados de negócios ou também está sendo usado para transmitir dados entre Java e C++?Você diz que está usando memória compartilhada e não JNI?Qual nível de multithreading existe atualmente no APP?Você descreveria o código como sendo de natureza síncrona ou assíncrona?

Existe uma relação física entre o código Solaris e os dispositivos que devem ser mantidos (ou seja,todos os dispositivos são registrados com o código c++ ou isso pode ser especificado).ou seja.se você colocasse um balanceador de carga web no frontend, e apenas colocasse 2 máquinas hoje, a relação de quais dispositivos são gerenciados por uma caixa inicializada antecipadamente ou antecipadamente?

Quais são os requisitos de HA?ou seja.apenas informações do estado?A HA pode ser feita apenas na camada da web, agrupando os dados da sessão?

O banco de dados está rodando em outra máquina?

Qual é o tamanho do banco de dados?Você otimizou suas consultas, ou seja.tentei usar junções internas/externas explícitas às vezes ajuda em comparação com subconsultas aninhadas (às vezes).(novamente veja as estatísticas sql).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top