Redis – Persistencia y Durabilidad

Redis proporciona dos mecanismos para permitir la persistencia de los datos en disco, y que no se pierdan tras un reinicio, un aspecto muy importante al tratarse de una base de datos que almacena todos sus datos en memoria, pudiendo utilizar cualquiera de ellos o ambos a la vez (una solución híbrida): Snapshotting (similar a un Backup Full) y AOF (similar a un Backup del Log de Transacciones).

Continuando con nuestra serie sobre Redis, tras haber hablado recientemente sobre cómo instalar y configurar Redis en Ubuntu, es el momento de tratar los mecanismos de persistencia y durabilidad en Redis, un aspecto muy importante, al tratarse de una base de datos que almacena todos sus datos en memoria.

Básicamente Redis ofrece dos mecanismos, que pueden usarse por separado, no utilizar ninguno (sin persistencia, completamente stateless), o combinar ambos en un modelo híbrido, y que detallamos a continuación.

NOTA: este Post se basa en pruebas realizadas con Redis 7.0.5 sobre Ubuntu, puede haber algunos detalles menores que difieran en otras versiones de Redis, por ejemplo, la forma de deshabilitar Snapshotting es diferente, en Redis 5 basta con comentar todas las líneas save mientras que en Redis 7 es necesario añadir una línea con save «», en ambos casos, descrito claramente en el fichero redis.conf

Snapshotting (fichero RDB – Redis Database)

Similar a un Backup Full (se genera un fichero RDB) que se realiza en un momento del tiempo, pudiendo configurarse de forma recurrente, cada hora, cada 24h, o como se desee, en la sección Snapshotting del fichero /etc/redis/redis.conf (se pueden utilizar una o varias directivas SAVE). Por ejemplo, las siguientes directivas realizarían un Snapshot cada 60 segundos, sólo si al menos 1000 claves han cambiado, y cada hora si al menos una clave ha cambiado. Cada Snapshot que se genera, sobrescribe el fichero RDB generado por el anterior.

save 3600 1
save 60 1000

El fichero RDB generado, se puede utilizar para restaurar en el mismo o diferente servidor de Redis, y por defecto se almacenará en /var/lib/redis con el nombre dump.rdb, o bien, como se especifique en las configuraciones dbfilename y dir de la sección Snapshotting del redis.conf.

Viene habilitado por defecto, de tal modo que Redis genera de forma automática un Snapshot siempre que se para el servicio de Redis de forma ordenada además de bajo ciertas condiciones (que podemos configurar y adaptar), sobrescribiendo el último fichero RDB. Y del mismo modo, cada vez que arranca Redis, recupera el último Snapshot y lo carga en memoria, de forma que no se pierda la información (si borrásemos el RDB, Redis arrancaría completamente vacío).

A continuación se muestra el comienzo de la sección de Snapshotting del fichero de configuración de Redis (redis.conf), donde se indica cuál es la configuración por defecto de Snapshotting, y también indica como deshabilitar Snapshotting con la opción save «» si no quisiéramos esta persistencia.

La creación del Snapshot (RDB) es una operación intensiva en acceso a disco y que puede ser prolongada en el tiempo para volúmenes grandes de datos, pudiendo afectar al rendimiento, por lo que debe de evitarse hacer un Snapshot en los momentos pico de carga de trabajo.

Suele utilizarse un proceso hijo (forked child process) para impactar menos en el proceso principal del servidor Redis.

Es posible utilizar el comando SAVE para generar un Snapshot de forma síncrona (esto no es habitual ni recomendable en Producción), o bien el comando BGSAVE para generar un Snapshot de forma asíncrona mediante un proceso hijo (opción recomendada), por ejemplo a través de un cron con la planificación que deseemos. También podemos utilizar el comando LASTSAVE para comprobar cuando se realizó el últimos Snapshot, teniendo en cuenta que este comando devuelve un Unix Timestamp.

La forma de recuperar un Snapshot de Redis, depende de si tenemos habilitado o no AOF.

  • En un servidor Redis sin AOF, consiste en parar el servicios de Redis, copiar el RDB que deseamos recuperar en la carpeta y con el nombre que se especifica en el fichero de configuración de Redis (redis.conf), y arrancar Redis. Fácil y sencillo.
  • En un servidor Redis con AOF, consiste en parar el servicios de Redis, copiar el RDB que deseamos recuperar en la carpeta y con el nombre que se especifica en el fichero de configuración de Redis (redis.conf), deshabilitar AOF (poner la opción appendonly a no en el redis.conf), arrancar Redis, ejecutar el comando BGREWRITEAOF para crear un nuevo fichero AOF, y volver a habilitar AOF en el redis.con (poner la opción appendonly a yes).

Append-Only File (AOF)

Similar a un Backup de Transacciones. Permite registrar en disco (fichero AOF) cada nueva operación de escritura, según llegan, lo que permite que se puedan volver a ejecutar (re-play) durante el arranque del servidor Redis, para así garantizar no perder datos, ya que en caso de una parada no ordenada de Redis, no se generaría un último Snapshot (RDB) actualizado y se perderían los datos desde el último RDB que fué realizado con éxito hasta el momento de la caída.

Cuando el fichero AOF es muy grande, el servidor Redis lo compacta de forma automática en segundo plano, manteniendo únicamente la mínima información más actual necesaria para poder recuperar los datos.

AOF se habilita y configura en la sección «Appen Only Mode» del fichero /etc/redis/redis.conf.

  • La opción appendonly especifica si está habilitado AOF (por defecto no está habilitado y esta opción está establecida al valor no).
  • La opción appenddirname, cuyo valor por defecto es «appendonlydir», especifica el subdirectorio donde se almacenará el fichero AOF (y resto de ficheros relacionados), por debajo del directorio de Snapshotting (que por defecto es /var/lib/redis).
  • La opción appendfilename, cuyo valor por defecto es «appendonly.aof», especifica el nombre del fichero AOF, así como marca la nomenclatura del resto de ficheros relacionados (incrementales y manifiestos).

Una de las principales opciones a configurar es appendfsync, para la cual podemos elegier entre los siguientes tres valores.

  • appendfsync always. Es la opción más segura, ya que siempre que se escribe en el fichero AOF se fuerza su actualización en disco (flush to disk), garantizando que no se pierden datos con un comportamiento totalmente síncrono, pero que genera una mayor latencia.
  • appendfsync everysec (opción por defecto). La actualización del fichero AOF en disco (flush to disk) se realiza de forma asíncrona en segundo plano cada segundo, lo que ofrece un mejor rendimiento (menor latencia) y el riesgo de pérdida de información sería en el peor caso de un segundo.
  • appendfsync no (no recomendable). En este caso, Redis no forzará la actualización del fichero AOF en disco (flush to disk), lo que implica que en caso de una parada no ordenada (ej: un crash) se puedan perder los datos de los últimos segundos. Habitualmente Linux fuerza (flush to disk) cada 30 seg, pero esto puede depender de la configuración concreta del servidor.

El fichero AOF es un fichero de texto que almacena los diferentes comandos ejecutados en protocolo RESP (Redis Serialization Protocol), lo que le hace fácilmente entendible. En caso de necesidad incluso podriamos editarlo y eliminar algún comando peligroso que pudiera haberse ejecutado, como FLUSH o FLUSHALL.

Despedida y Cierre

Hasta aquí llega este Post, en el que hemos visto los dos mecanismos que proporcionan persistencia y durabilidad en Redis, el Snapshotting (RDB – Redis Database) que es similar a un backup full que viene habilitado por defecto y que se ejecuta automáticamente en base a ciertos criterios además de al parar el servicio de Redis de forma ordenada (y se hace un restore automático al arrancar Redis), y el AOF que es similar a un backup del registro de transacciones, y que no viene habilitado por defecto. Ambos mecanismos pueden convivir sin ningún problema, o incluso no tener ninguno habilitado (sin persistencia, cada reinicio arrancaría Redis en vacío).

Para más información: Redis persistence

Poco más por hoy. Como siempre, confío que la lectura resulte de interés.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

diecisiete − tres =