Pergunta

Eu tenho uma aplicação web que recebe mensagens através de uma interface HTTP, por exemplo:

http://server/application?source=123&destination=234&text=hello

Essa solicitação contém o ID do remetente, a IDENTIFICAÇÃO do destinatário e o texto da mensagem.

Esta mensagem deve ser processada como:

  • encontrar o objeto de Usuário correspondente para a origem e o destino do banco de dados
  • a criação de uma árvore de objetos:uma Mensagem que contém um campo para a mensagem de texto e dois objetos de Usuário de origem e de destino
  • a persistência desta árvore para um banco de dados.

A árvore será carregado por outros aplicativos que eu não posso tocar.

Eu uso a Oracle, como o backup do banco de dados e JPA com Toplink para a manipulação de banco de dados de tarefas.Se possível, eu gostaria de ficar com estes.

Sem muito otimização de que eu possa alcançar ~30 pedidos/s de taxa de transferência no meu ambiente.Que não é muito, eu ia exigir ~300 solicitações/s.Então eu medida onde o gargalo de desempenho é e descobriu que as chamadas para em.persist() toma a maior parte do tempo.Se eu simplesmente comentar essa linha, a taxa de transferência ir bem mais de 1000 pedidos/seg.

Eu tentei escrever um pequeno aplicativo de teste que usou simples chamadas JDBC para persistir 1 milhão de mensagens para o mesmo banco de dados.Eu usei o processamento em lote, ou seja, eu fiz 100 insere, em seguida, uma confirmação, e repetido até que todos os registros foi no banco de dados.Eu medi ~500 solicitações/s de taxa de transferência neste cenário, que atendesse as minhas necessidades.

É claro que eu precisa para otimizar inserir o desempenho aqui.No entanto, como mencionei anteriormente, eu gostaria de continuar a utilizar JPA e Toplink para isso, não JDBC puro.

Você sabe uma maneira de criar lotes de pastilhas com JPA e Toplink?Você pode recomendar qualquer outra técnica para melhorar o APP persistem desempenho?

INFORMAÇÕES ADICIONAIS:

"pedidos/s" significa aqui:número total de solicitações / tempo total desde o início do teste para o último registro escrito ao banco de dados.

Eu tentei fazer as chamadas para em.persist() assíncrona através da criação de uma fila na memória entre o servlet coisas e o persister.Ele ajudou o desempenho significativamente.No entanto, a fila fez crescer muito rápido e como o aplicativo receberá ~200 pedidos/segundo de forma contínua, não é uma solução aceitável para mim.

Neste dissociado abordagem reuni os pedidos de 100 milissegundos e chamado em.persist() em todos os itens recolhidos antes de cometer a transação.O EntityManagerFactory é armazenado em cache entre cada transação.

Foi útil?

Solução

Você deve dissociar do APC interface e utilizar o mínimo TopLink API.Você pode, provavelmente, chuck os objetos que você está persistindo em um UnitOfWork e consolidar a UnitOfWork em sua agenda (síncrono ou assíncrono).Nota-se que um dos custos de em.persist() é o implícito clone que acontece de todo o objeto de gráfico.TopLink vai funcionar melhor se você uow.registerObject() os dois objetos de usuário a si mesmo, guardar em si a identidade de testes que tem para fazer.Então você vai acabar com:

uow=sess.acquireUnitOfWork();
for (job in batch) {
 thingyCl=uow.registerObject(new Thingy());
 user1Cl=uow.registerObject(user1);
 user2Cl=uow.registerObject(user2);
 thingyCl.setUsers(user1Cl,user2Cl);
}
uow.commit();

Isso é muito antiga escola TopLink btw ;)

Observe que o lote vai ajudar muito, porque lote de escrever e, mais especialmente, em lotes, por escrito, com parâmetro de vinculação vai chutar que para este exemplo simples, provavelmente, terá um grande impacto em seu desempenho.

Outras coisas a observar:o sequenciamento de tamanho.Um monte de tempo gasto escrevendo objetos em TopLink é, na verdade, passei a ler o seqüenciamento de informações do banco de dados, especialmente com os pequenos padrões (eu provavelmente teria várias centenas ou mesmo mais como a minha sequência de tamanho).

Outras dicas

Qual é a sua medida de "pedidos/s"?Em outras palavras, o que acontece de 31 de pedido?O recurso está sendo bloqueado?Se ele é o front-end/servlet/parte web, você pode executar em.persist() em outro segmento e regressar imediatamente?

Além disso, você é a criação de transações de cada vez?Vocês estão criando EntityManagerFactory objetos com cada pedido?

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