Este asunto de la memoria caché que usa el Servidor del Firebird parece que no está muy claro, así que trataré de explicarlo en este artículo.

¿Qué es la memoria caché?

Es una porción de la memoria RAM de esa computadora donde se encuentra el Servidor del Firebird.

¿Para qué sirve la memoria caché?

Para devolver muy rápidamente los resultados de los SELECT.

¿Qué se coloca en la memoria caché?

Las páginas que fueron leídas para devolver los resultados que necesita un SELECT.

¿Cómo se obtienen los resultados que necesita un SELECT?

Extrayendo de la Base de Datos toda la página (o páginas) donde se encuentra la fila deseada.

Por ejemplo, si el tamaño de la página es de 4.096 bytes y cada fila de la tabla CLIENTES ocupa 100 bytes entonces en cada página de la tabla CLIENTES se podrán colocar 4.096 / 100 = 40 filas.

En una página jamás se mezclan datos de varias tablas. Si una página se reservó para ser usada por la tabla CLIENTES entonces solamente filas de la tabla CLIENTES podrá contener esa página.

En nuestro ejemplo, cada página podrá contener 40 filas (o registros) de la tabla CLIENTES.

Si escribimos un SELECT como el siguiente:

Listado 1.

SELECT
   *
FROM
   CLIENTES
WHERE
   CLI_IDENTI = 12345

Nuestro SELECT nos devolverá una sola fila, la fila cuyo identificador es 12345, pero extrajo de la Base de Datos toda la página donde se encuentra esa fila, o sea que extrajo 40 filas aunque solamente 1 de esas filas nos muestre.

Pero ahora las 40 filas, la que nos mostró y las 39 restantes que no nos mostró, están en la memoria caché.

 ¿Por qué se usa la memoria caché?

Porque para cualquier programa de computadora es muchísimo más rápido leer algo que se encuentra en la memoria RAM que leer algo que se encuentra en el disco duro. Extraer de la memoria RAM es miles de veces más rápido que extraer del disco duro.

Si ahora ejecutamos este SELECT:

Listado 2.

SELECT
   *
FROM
   CLIENTES
WHERE
   CLI_IDENTI = 12346

Y la fila cuyo identificador es 12346 se encuentra en la misma página que la fila cuyo identificador es 12345 entonces la fila que tiene el identificador 12346 ya está en la memoria caché. Y como ya está en la memoria caché entonces el Servidor del Firebird extraerá de allí los datos de esa fila, no los obtendrá del disco duro. En consecuencia, devolverá esos datos muy rápidamente.

¿Cómo se diferencian Classic y SuperServer en el uso de la memoria caché?

En Classic cada conexión usa su propia memoria caché. En nuestro ejemplo, si Juan ejecutó el SELECT del Listado 1. y luego María ejecutó el SELECT del Listado 2. entonces María no se benefició del SELECT ejecutado por Juan, ya que la memoria caché de María es totalmente independiente de la memoria caché de Juan. Pero si Juan ejecutó el SELECT del Listado 1. y después Juan también ejecutó el SELECT del Listado 2. entonces sí Juan se benefició de ya tener en su memoria caché los datos que necesitaba.

En SuperServer la memoria caché es compartida entre todas las conexiones. En nuestro ejemplo, si Juan ejecutó el SELECT del Listado 1. y después María ejecutó el SELECT del Listado 2. entonces María obtuvo un gran beneficio: los datos que necesitaba ya se encontraban en la memoria caché y por eso los recibió muy rápidamente.

 ¿Cómo se establece el tamaño de la memoria caché?

El tamaño de la memoria caché se calcula con esta fórmula:

Tamaño_memoria_caché = Cantidad_de_páginas * Tamaño_de_cada_página

La Cantidad_de_páginas debe estar entre 0 y 131.072. El Tamaño_de_cada_página debe ser 4.096 bytes, 8.192 bytes, ó 16.384 bytes.

El Tamaño_memoria_caché por supuesto no debe ser mayor que la memoria RAM libre disponible en la computadora donde está instalado el Servidor del Firebird.

¿Cómo se elige el tamaño de cada página?

Al crear la Base de Datos se puede elegir el tamaño de sus páginas, que como ya vimos debe ser uno de los siguientes: 4.096, 8.192, 16.384

Si no se eligió uno de ellos entonces el Servidor del Firebird usará 4.096

Se puede cambiar el tamaño de cada página haciendo un ciclo backup/restore. Al hacer el restore tenemos la opción de elegir el tamaño que tendrá cada página de la Base de Datos restaurada.

¿Cómo se elige la cantidad de páginas?

Primero, debemos recordar que esa cantidad debe estar entre 50 y 131.072

Segundo, no debemos sobrepasar la memoria RAM disponible.

Ejemplo: la computadora donde se instaló el Servidor del Firebird tiene 32 Gb de memoria RAM. Dejaremos 16 Gb para ser usados por el Sistema Operativo y los demás programas. Por lo tanto, para nuestra memoria caché reservaremos los restantes 16 Gb.

Nuestra Base de Datos tiene páginas de 4.096 bytes

Memoria RAM disponible = 16 Gb = 16 * 1.024 * 1.024 * 1.024 = 17.179.869.184 bytes

Tamaño de cada página = 4.096 bytes

Cantidad de páginas = 4.194.304

No podemos usar 4.194.304 páginas, la cantidad máxima que podemos usar es 131.072, el Firebird no nos permite usar más.

Y como cada página ocupa 4.096 bytes entonces nuestra memoria caché puede ocupar como máximo 131.072 * 4.096 = 536.870.912 bytes = 0,5 Gb

Si la arquitectura es SuperServer y el tamaño de cada página es de 4.096 bytes entonces el caché no puede ser mayor que 0,5 Gb. O sea, que tener disponibles 16 Gb de RAM es un gran desperdicio.

Podemos aumentar el tamaño del caché usado por SuperServer si aumentamos el tamaño de cada página. El tamaño de página máximo que podemos usar es 16.384 bytes, entonces: 131.072 * 16.384 = 2.147.483.648 bytes = 2 Gb

En otras palabras, si la arquitectura es SuperServer la cantidad máxima de memoria RAM del Servidor que podemos usar es de 2 Gb. Ni un byte más.

Entonces, si tenemos la posibilidad de usar más de 2 Gb de memoria RAM (como en este ejemplo) lo que debemos hacer es cambiar la arquitectura a Classic.

En Classic la memoria caché es por conexión. O sea que en nuestros cálculos debemos considerar la cantidad de conexiones concurrentes que podemos tener como máximo. No la cantidad normal de conexiones ni la cantidad mínima de conexiones, sino la cantidad máxima de conexiones que podríamos tener.

Por ejemplo, tenemos 70 usuarios pero algunos se conectan más de una vez al mismo tiempo, hemos determinado que nunca hay más de 90 conexiones concurrentes pero por un motivo de seguridad supondremos que son 100.

El tamaño de  cada página de nuestra Base de Datos es de 4.096 bytes.

Entonces:

16 Gb / 100 / 4.096 = 16 * 1.024 * 1.024 * 1.024 / 100 / 4.096 = 41.943 páginas

41.943 páginas * 4.096 bytes = 171.798.691 bytes

O sea, que podremos tener hasta 100 conexiones concurrentes, cada una de ellas usando 171.798.691 bytes de la memoria RAM del Servidor como su propia memoria caché.

Y como 171.798.691 bytes de memoria para cada conexión es muchísimo, entonces todos los SELECT de todos los usuarios serán rapidísimos.

¿Dónde se especifica la cantidad de páginas que debe usar el Servidor del Firebird?

En el archivo FIREBIRD.CONF, que encontrarás en la misma carpeta donde instalaste al Firebird. En ese archivo existe una entrada llamada DefaultDbCachePages. Debes borrar el símbolo de numeral que se encuentra a la izquierda (el símbolo de numeral indica que todo lo que se encuentra a su derecha es un comentario) y escribir la cantidad de páginas que quieres tener.

CACHE-1

Captura 1. Si haces clic en la imagen la verás más grande

CUIDADO: La cantidad de páginas es por Base de Datos. Eso significa que si puedes tener 2 bases de datos abiertas debes dividir la cantidad calculada por 2. Si puedes tener 3 bases de datos abiertas debes dividir la cantidad calculada por 3, y así sucesivamente.

En el archivo FIREBIRD.CONF se especifica la cantidad de páginas que usarán todas las bases de datos, o sea que es el valor por defecto, el que se usará si no se elige otra cantidad. Si queremos especificar para una Base de Datos en particular entonces usamos al programa GFIX.EXE para eso. Su opción -buffers nos permite determinar la cantidad de páginas que usará esa Base de Datos.

CACHE-2

Captura 2. Si haces clic en la imagen la verás más grande

En la Captura 2. le estamos diciendo que use 1.200 páginas para la Base de Datos BLOG_DB.FDB

CACHE-3

Captura 3. Si haces clic en la imagen la verás más grande

Y en la Captura 3. podemos ver la cantidad de páginas (Page buffers) usadas y el tamaño (Page size) de cada página. Entonces, 1.200 * 4.096 = 4.915.200 bytes

Si la arquitectura es Classic entonces esos 4.915.200 bytes serán para cada conexión y si la arquitectura es SuperServer entonces esos 4.915.200 bytes serán para todas las conexiones.

¿Cómo se coloca a una tabla en la memoria caché?

En la memoria caché se colocan las páginas que necesitó un SELECT. No se colocan datos allí cuando se ejecuta un INSERT, un UPDATE, o un DELETE. Solamente cuando se ejecuta un SELECT. Para colocar a toda una tabla en la memoria caché podemos hacerlo mediante SELECT * FROM MiTabla o mediante SELECT COUNT(*) FROM MiTabla. Esta última opción es preferible porque es mucho más rápida que la primera. ¿El motivo? Pone a cada página de MiTabla en la memoria caché pero no devuelve el contenido de esas páginas al Cliente.

Resumiendo:

  • La memoria caché es una porción de la memoria RAM de la computadora donde se instaló al Servidor del Firebird
  • Se usa la memoria caché para devolver muy rápidamente los resultados de los SELECT
  • Si los datos que debe devolver un SELECT se encuentran en la memoria caché obtenerlos de allí será mucho más rápido que obtenerlos del disco duro
  • En la memoria caché no se colocan filas ni tablas, se colocan páginas
  • Cuando se ejecuta un SELECT el Servidor del Firebird no extrae de la Base de Datos las filas que necesita ese SELECT sino las páginas donde se encuentran esas filas
  • En Classic la memoria caché de cada conexión es independiente de la memoria caché de las otras conexiones. En SuperServer la memoria caché es compartida entre todas las conexiones.
  • Si el tamaño de la Base de Datos es menor que 2 Gb entonces es recomendable que la arquitectura sea SuperServer. Si el tamaño de la Base de Datos es mayor que 2 Gb entonces es recomendable que la arquitectura sea Classic.
  • En el archivo FIREBIRD.CONF se puede especificar la cantidad de páginas que usará cada Base de Datos. Para una Base de Datos en particular se puede cambiar la cantidad de páginas usando el programa GFIX.EXE con la opción -buffers
  • El tamaño de cada página de la Base de Datos se determina cuando es creada, puede ser cambiado más adelante mediante un ciclo backup/restore
  • Los comandos INSERT, UPDATE, y DELETE no colocan datos en la memoria caché. Solamente el comando SELECT lo hace
  • Para poner a toda una tabla en la memoria caché se puede escribir: SELECT COUNT(*) FROM MiTabla. Ese comando colocará a cada página de MiTabla en la memoria caché.

Artículos relacionados:

Entendiendo las páginas de la Base de Datos

Eligiendo el tamaño adecuado de las páginas de la Base de Datos

SuperServer: optimizando el tamaño del caché

Classic: optimizando el tamaño del caché

Optimizando SuperServer: poniendo toda la Base de Datos en la memoria caché

El índice del blog Firebird21

El foro del blog Firebird21

 

Anuncios