WMB: Uso eficiente y escalable de variables compartidas (SHARED ROW)


Normalmente en ESQL las variables compartidas (SHARED) son usadas para almacenar datos extraídos de una base de datos, los cuales se recorren con sentencias SELECT, que, mientras más aumenten los datos en memoria, son más lentas. Aquí se muestra una forma eficiente de estructurar la caché que escala bien y es más rápido que un acceso a base de datos incluso cuando se excede de 10.000 registros.

Nuestro ejemplo se basa en un flujo que recibe mensajes que contienen un código de aeropuerto (por ejemplo LHR) y accede a una tabla de base de datos de la correspondiente ciudad (Londres). Acceder a la base de datos por cada mensaje es costoso, por lo que una solucion es cargar toda la tabla en una variable compartida ESQL (SHARED ROW) en el primer acceso, y después buscar en ella. Este artículo describe la estructura de caché más comúnmente usada, llamada standard cache, y luego, introduce una efeciente y escalable variante llamada ESQL Cache, porque explota la forma de ESQL de acceder a sus variables.

  1. Standard Cache.
  2. Rendimiento usando Standard Cache.
  3. ESQL Cache.
  4. Rendimiento usando ESQL Cache.
  5. Usando múltiples claves (ESQL Cache).
  6. ESQL Cache vs Global Cache.

  • Standard Cache:

La forma más común de implementación de una caché con variables compartidas de ESQL consiste en una SHARED ROW que contiene los resultados de un SELECT de una tabla de base de datos cacheada. Si asumimos que tenemos una tabla llamada AIRPORTS que contiene las columnas CODE y CITY. Este código carga la caché:

El contenido de la variable CACHE sería:

Esta función implementa la caché:

NOTA: Por legibilidad la función se muestra sin un bloque ATOMIC, lo cual únicamente funciona cuando hay un único hilo para el flujo. Hay otros métodos para buscar en la cache como bucles WHILE o FOR, pero son más lentos que SELECT.
  • Rendimiento usando Standard Cache:

El problema de esta estructura de caché es que no es escalable. Una traza de usuario muestra que el SELECT escanea la tabla secuencialmente hasta que encuentra el registro que satisface la cláusula WHERE. Así como la tabla crece, la búsqueda se vuelve más lenta. Eventualmente, conviene más tirar la caché e ir a la base de datos a buscar cada vez.

Las mediciones usando IBM Integration Server V9 en Windows 7 64-bit, con una base de datos local DB2 V10.1 muestran el efecto de crecimiento de la caché:

Las mediciones usando IBM Integration Server V9 en Windows 7 64-bit, con una base de datos local DB2 V10.1 muestran el efecto de crecimiento de la caché

NOTA: La prueba consiste en poner 10.000 mensajes para acceder aleatoriamente a los primeros 1000, 2000, 3000 (y así) registros en la caché, así se simula diferentes tamaños de caché. El tamaño total de la caché es de 9185 registros. El gráfico muestra el tiempo transcurrido, en milisegundos, para procesar un mensaje. La respuesta de la base de datos (0,8 milisegundos) es constante (etiqueta NO_CACHE).

En este configuración, la caché es más rapida que la base de datos hasta llegar a los 3.000 registros. Para cachés más grandes, es más lento que el acceso a base de datos.

  • ESQL Cache:

La ESQL Cache almacena cada clave y valor (en nuestro ejemplo, código del aeropuerto y nombre de la ciudad) como un par nombre/valor:

No hay ningún array. PAra devolver el nombre de la ciudad de un código de aeropuerto dado, la función de búsqueda en caché simplemente se refiere a la variable apropiada:

Y aquí la función que implementa la nueva estructura en caché:

Para organizar la caché en la nueva estructura, la función navega por cada registro devuelto por el SELECT de la base de datos. En este ejemplo, cada registro contiene el código del aeropuerto (como JFK) y la ciudad (Nueva York). Este par es usado para añadir la variable a la caché, donde el nombre de la variable es el código y el valor es la ciudad (CACHE.JFK=’New York’).

NOTA: Por legibilidad la función se muestra sin un bloque ATOMIC, lo cual únicamente funciona cuando hay un único hilo para el flujo. Hay otros métodos para buscar en la cache como bucles WHILE o FOR, pero son más lentos que SELECT.

Aquí hay una sentencia para poblar un registro de caché:

Las sentencias SET y CREATE son equivalentes si y solo si hay una única instancia de la clave (CODE, en este ejemplo). Cuando usamos SET cuando hay múltiples ocurrencias de la clave, únicamente habrá una instancia en la caché (la última).

  • Rendimiento usando ESQL Cache:

Como la búsqueda accede directamente a la variable, es mucho más rápido y escalable. El gráfico a continuación compara el tiempo de respuesta de ESQL Cache con la Standar Cache. En la siguiente figura se muestra en milisegundos por mensaje para tamaños de caché de 9000 registros:

En la siguiente figura se muestra en milisegundos por mensaje para tamaños de caché de 9000 registros

La ESQL Cache tiene una media transcurrida de 0,21 milisegundos por mensaje, lo cual es significativamente más rápido que acceder a la base de datos sea cual sea el tamaño de la caché. Es incluso más rápida que la Standard Cache para cualquier tamaño de caché:

ESQL Cache vs Standard Cache en milisegundos por numero de registros

El gráfico muestra que realmente el tiempo aumenta conforme se incrementa el tamaño de la caché, pero es despreciable. Este aumento es apreciable en el siguiente gráfico:

Aumento del tiempo de ESQL Cache conforme crece el tamño de la caché

La respuesta crece desde aproximadamente 0,2 milisegundos por mensaje para una caché de 1.000 entradas, hasta 0,23 miliegundos para una caché de 9.000 entradas, lo cual es un 15%. ¿Cuándo la ESQL Cache empieza a ser más lenta que el acceso a caché? Aunque no se ha experimentado aqui, una progresión linear basada en estos test, indican que la ESQL Cache seguiría siendo más rápida que un acceso a base de datos hasta al menos 80.000 entradas.

  • Usando múltiples claves:

La ESQL Cache puede soportar fácilmente múltiples claves, para satisfacer el equivalente del SELECT … WHERE KEY1=value1 AND KEY2=value2. Aquí está la estructura:

Y para retornar un valor:

  • ESQL Cache vs Global Cache:

Message Broker V8 introdujo la Global Cache. Esta usa la pila de la JVM del grupo de ejecución para almacenar datos, y provee APIs de Java para hacer put y get sobre la caché. Es fácil implementarla, y tiene un rendimiento consistente a lo largo de los rangos del tamaño de la caché. Una ventaja de la Global Cache sobre las variables compartidas (shared) de ESQL es que la cache puede compartirse entre diferentes flujos, integration servers, grupos de ejecución, y busas de integración o message brokers (intermediarios), mientras que el ámbito de las variables compartidas ESQL son sólo para el flujo.

La siguiente figura compara la Global Cache con la ESQL Cache:

La siguiente figura compara la Global Cache con la ESQL Cache

La ESQL Cache, con 0,21 milisegundos por mensaje, es más rapida que la Global Cache (con una media de 0,43 milisegundos por mensaje) para todos los tamaños de caché probados. Sin embargo, para mayores tamños, la Global Cache será más rápida.

La misma proyección linear indica que la ESQL Cache empezará a ser más lenta que la Global Cache cuando el tamaño de la caché alcance los 40.000 registros.

Fuente: http://www.ibm.com/developerworks/websphere/library/techarticles/1405_dunn/1405_dunn.html