Pregunta

Tengo una aplicación web que recibe mensajes a través de una interfaz HTTP, por ejemplo:

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

Esta petición contiene el ID del remitente, el número de IDENTIFICACIÓN del destinatario y el texto del mensaje.

Este mensaje debe ser procesado como:

  • encontrar la coincidencia de objeto de Usuario para el origen y el destino de la base de datos
  • la creación de un árbol de objetos:un Mensaje que contiene un campo para el mensaje de texto y dos objetos de Usuario para el origen y el destino
  • la persistencia de este árbol a una base de datos.

El árbol será cargado por otras aplicaciones que ya no puedo tocar.

Yo uso de Oracle como el respaldo de la base de datos y JPA con Toplink para la base de datos las tareas de manipulación.Si es posible, yo me quedaría con estos.

Sin mucho optimización puedo lograr ~30 peticiones/s de rendimiento en mi entorno.Que no es mucho, yo necesitaría ~300 solicitudes/seg.Lo he medido, donde el cuello de botella de rendimiento es y se encontró que las llamadas a em.persist() toma la mayor parte del tiempo.Si yo simplemente comentar esa línea, el rendimiento de ir más de 1000 solicitudes/seg.

Traté de escribir una pequeña aplicación de prueba que usa simples llamadas JDBC a persistir de 1 millón de mensajes a la misma base de datos.He utilizado los lotes, lo que significa que me hizo 100 inserta a continuación, de la confirmación, y repite hasta que todos los registros se encontraba en la base de datos.He medido ~500 peticiones/s de rendimiento en este escenario, que habría de satisfacer mis necesidades.

Está claro que necesito para optimizar el rendimiento de la plaquita aquí.Sin embargo, como mencioné antes, me gustaría seguir usando JPA y Toplink por esto, no la pura JDBC.

¿Sabes una manera de crear lotes con inserciones de JPA y Toplink?Puede recomendar a cualquier otra técnica para la mejora de la JPA persisten rendimiento?

INFORMACIÓN ADICIONAL:

"peticiones/s" significa aquí:número total de solicitudes / tiempo total desde el comienzo de la prueba al último registro escrito de la base de datos.

Traté de hacer las llamadas a em.persist() asincrónica mediante la creación de una cola en memoria entre el servlet cosas y el almacenador.Ayudó a que el rendimiento en gran medida.Sin embargo, la cola hizo crecer muy rápido y como la aplicación recibirá ~200 peticiones por segundo de forma continua, no es una solución aceptable para mí.

En este enfoque disociado he recogido las peticiones de 100 ms, y se llama em.persist() en todos los elementos recopilados antes de llevar a cabo la transacción.El EntityManagerFactory se almacena en caché entre cada transacción.

¿Fue útil?

Solución

Usted debe separar de la JPA de la interfaz y el uso del desnudo TopLink de la API.Usted probablemente puede chuck los objetos que queremos persistir en un UnitOfWork y cometer el UnitOfWork en su horario (de sincronización o asíncrono).Tenga en cuenta que uno de los costos de em.persist() implícita es la clon que sucede de todo el objeto gráfico.TopLink funcionará bastante mejor si uow.registerObject() sus dos objetos de usuario a ti mismo, reservándose la identidad de las pruebas que ha de hacer.Así que usted va a terminar con:

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();

Esto es muy de la vieja escuela TopLink por cierto ;)

Tenga en cuenta que el lote va a ayudar mucho, porque lote de escritura y más especialmente de los lotes de la escritura con el parámetro de enlace se aplicará en los que, por este simple ejemplo probablemente tendrá un gran impacto en su rendimiento.

Otras cosas a tener en cuenta:su secuenciación tamaño.Mucho el tiempo dedicado a escribir objetos en TopLink es realmente dedicado a la lectura de la secuenciación de la información de la base de datos, especialmente con el pequeño defecto (probablemente tengo varios cientos, o incluso más, como mi secuencia de tamaño).

Otros consejos

¿Cuál es su medida de "peticiones/s"?En otras palabras, lo que ocurre para el 31 de solicitud?Qué recurso que está siendo bloqueado?Si es el front-end/servlet/web de la porción, puede ejecutar em.persist() en otro hilo y regresar de inmediato?

También, son la creación de transacciones cada vez?Son la creación de EntityManagerFactory objetos con cada solicitud?

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