Éste es un artículo de Rahul Biswas, miembro del grupo Java Performance Engineering de Sun. Se trata de una de mis “traducciones”, para ver si me voy reenterando de los temitas java. El artículo orginal en inglés lo podéis encontrar aquí.
La Java Persistence API, presentada en la especificación (JSR 220) de Enterprise JavaBeans (EJB) 3.0, simplifica el desarrollo de las aplicaciones empresariales en Java que usan persitencia de datos. Este articulito explica como tunear la implementación que hay en GlassFish de la Java Persistence API llamada Toplink Essentials.
El ejemplo que incluye este artículo está basado en el ejemplo customer-cmp que viene con GlassFish. Este artículo cubre el tunning de rendimientopara una implementación de la JPA usada en diferentes modos: in-container y out-of container. Además también se usa el framework Faban para demostrar los diferentes parámetros de tunning del rendimiento.
Antes de comentar estos parámetros, vamos a examinar los modos in-container y out-of container y el framework Faban.
Dos modos de ejecutar una implementación de la Java Persistence
Puedes usar implementaciones de la JPA que sean compatibles con la JSR-220 en cualquiera de estos dos modos: in-container y out-of container. Esta es una marcada diferencia con las primeras implementaciones de JPA, como por ejemplo la persistencia gestionada por el contenedor de las EJB2.1. Con este tipo de gestión de persistencia sólo se podía ejecutar dentro de una contenedor de aplicaciones.
El modo In-container significa que la JPA se usa dentro de un contenedor de EJBs. Los entity managers, los objetos que gestionan las entidades de persistencia, normalmente se crean por el contenedor de EJBs. Los Entity managers suelen ser gestores JTA, lo que quiere decir que funcionan bajo transacciones controladas por la Java Transaction Architecture (JTA). Sin embargo, la JPA debe soportar tanto a los entity managers JTA como a los entity managers resource-local, esto es, gestores en transacciones no gestionadas por JTA.
En el modo out-of-container la JPA es standalone o se ejecuta en un contenedor web. La aplicación es responsable de crear sus propios entity managers. Las transacciones suelen ser locales. Si la implementación funciona sola, no necesita soportar JTA.
The Faban Driver Framework
Faban es un driver framework de código abierto que permite a los desarrolladores crear, ejecutar y simular procesos de benchmarking. Para más información consultar la página del proyecto Faban.
Tunear la Aplicación de muestra
La aplicación de ejemplo customer-cmp interactua con una base de datos relacional para guardar y mostrar información sobre las suscripciones de los clientes a publicaciones. La base de datos guarda información como el nombre y la dirección del cliente, así como el tipo de periódico al que el cliente está suscrito — esto es, una revista, un boletín o un diario. Los usuarios pueden enviar peticiones a la aplicación para mostrar información relacionada con sus suscripciones.
Este tutorial se enfoca en una de las operaciones soportadas por la aplicación: encontrar a un usuario por su ID.
Cambiar el tamaño de la Cache y el número de pools de conexiones
Vamos a examinar el impacto que tienen los parámetros de tunning específicos sobre el rendimiento combinado de estas operaciones. Específicamente, vamos a examinar el impacto que tiene cambiar el tamaño de la cache en Toplink Essentials y resetear el número de conexiones en la connection pool en GlassFish para las llamadas a la base de datos.
Toplink Essentials tiene un tamaño de cache por defecto de 1000 por entidad. Para demostrar el efecto del cambio en el tamaño de la cache, veamos el ratio de transacciones usando el valor por defecto. Y después cambiaremos el tamaño a 5000 y compararemos los resultados.
Para establecer el tamaño de la cache, necesitas modificar el fichero persistence.xml de tu proyecto y establece la propiedad toplink.cache.size.default como sigue:
<property name="toplink.cache.size.default" value="5000"/>
En este ejemplo, hay 20.000 clientes en la base de datos.
La configuración de la cache sirve para los dos modos comentados antes (in-container y out-of-container). La connection pool, sin embargo, se gestiona diferente según se use un modo u otro. Para dentro del contenedor, la connection pool se configura en el servidor, en Glassfish en este caso, y se controla por la configuración de una fuente de datos o data-source. En este modo, puedes configurar las conexiones con la consola de administración de GlassFish.
Dentro del contenedor, establece el número de conexiones del pool del contenedor con el número de threads para procesar peticiones a una instancia de GlassFish (en este caso, 40). Éste es el máximo número de conexiones que necesita Toplink Essentials para las llamadas a la base de datos.
Para el uso fuera del contenedor, la configuración del pool de conexiones se hace en el fichero persistence.xml. La implementación Toplink Essentials tiene una configuración por defecto de la connection pool de ocho conexiones tanto para lecturas como escrituras. Ejecutaremos la aplicación en el modo out-of-container para ocho usuarios, de modo que estableceremos las conexiones de la connection pool a ocho.
Resultados
Si ejecutamos Toplink dentro del contenedor obtenemos los siguientes resultados:
| Tamaño cache | Transacciones/segundo | ||
| 1000 (por defecto) | 1911.493 | ||
| 5000 | 3727.253 | ||
Ejecutando Toplink fuera del contenedor tenemos lo siguiente:
| Tamaño cache/ Connection Pool |
Transacciones/segundo | ||
| 1000/por defecto* | 1456.153 | ||
| 5000/8 | 6510.0 | ||
* Los valores por defecto son:
toplink.jdbc.read-connections.min = 2
toplink.jdbc.read-connections.max = 2
toplink.jdbc.write-connections.max = 10
toplink.jdbc.write-connections.min = 5
Nótese que cuando se usan los valores por defecto, el pool se inicializa con la configuración por defecto mínima y puede escalar al máximo especificado por la configuración máxima por defecto. Poniendo un valor de 8 al pool, siempre habrá ocho conexiones en el pool.
Las configuraciones del sistema para los tests son:
Sun Fire V880, Solaris 10, 4 CPUs para el Sistema bajo test(SUT).
Sun Fire V880, Solaris 10, 12 CPUs para el sistema driver (véase Faban framework).
Nótese que el driver y el SUT son el mismo sistema para el test out-of-container. El sistema Driver y el SUT tienen una conexión ethernet punto-a-punto, lo que quiere decir que no hay tráfico de red externo.
Resumen
Para obtener el mejor rendimiento de tu JPA, es importante entender los parámetros de tunning incluídos en la implementación de la JPA.
La configuración de la cache es un importante parámetro de tunning de Toplink. Ajustar la connection pool de GlassFish también es importante para obtener el mejor rendimiento de cualquier implementación de JPA dentro de GlassFish.
Si usas una JPA fuera del contenedor EJB, la cache y la connection pool también juegan un papel importante en el rendimiento, aunque en este caso configuramos el pool en el fichero persistence.xml.
Hay otros parámetros que pueden impactar en el rendimiento de una JPA. Uno es el statement cache. Éste se tiene que especificar explícitamente para algunas bases de datos como una Oracle. Este parámetro se activa por defecto la base de datos Java DB que viene con GlassFish.
Además, la configuración de tu Java Virtual Machine (JVM) puede jugar un rol importante en el ajuste de la persistencia. Para tener información detallada del ajuste de la JVM, mira el Java Tuning White Paper. Para la ejecución de la aplicación de este tip, las opciones de la JVM las pondremos así:
-server -XX:+AggressiveHeap -Xmx2500m -Xms2500m -Xss128k
-XX:+DisableExplicitGC
Para más información
Para más información sobre Java Persistence, ver The Java Persistence API - A Simpler Programming Model for Entity Persistence y el Java Persistence API FAQ.
Para más información sobre Toplink Essentials, ver TopLink Essentials - The Java Persistence API Implementation at GlassFish.
Ejecutar el código de ejemplo
Para instalar y ejecutar el código que acompaña esta propinilla:
GLASSFISH_HOME. Debe apuntar dónde hayas instalado GlassFish.ANT_HOME. Debe apuntar dónde tengas instalado el Ant (incluido en el paquete de GlassFish).JAVA_HOME. Apunta dónde tengas el JDK 5.0.Añadir $JAVA_HOME/bin, $ANT_HOME/bin, y $GLASSFISH_HOME/bin a tu variable de entorno PATH.
<sample_install_dir>/ttmay2007jpaper, donde <sample_install_dir> es el direcotorio donde hayas puesto el paquete. El directorio ttmay2007jpaper contiene el código fuente además de otros ficheros para el ejemplo.javaee.server.passwordfile sea correcta. $GLASSFISH_HOME/bin/asadmin start-domain domain1 ant start-db: ant create-db ant setup ant generate-data ant configure-glassfish ant run_inc_default ant run_inc_optimized ant run_ooc_default ant run_ooc_optimized${runid} es el id de cada ejecución que muestra la consola durante la ejecución. Para ver los resultados, hay que ver el fichero summary.xml en ese directorio. Una vez termina la ejecución, puedes desahacer la configuración de tunning. Cambia al directorio samples/javaee5/enterprise/customer-cmp-ear/setup e introduce el siguiente comando: ant unconfigure_glassfish.[…] Fuente: Blog del Galifate. […]