Noob, te presento a redis

redis

Actualmente estamos acostumbrados a hacer peticiones y a querer resultados lo más pronto posible. Con el auge de Internet y de los smartphones, las aplicaciones  cada vez tienen que dar servicio a un mayor número de usuarios y las antiguas arquitecturas Cliente-Servidor o las Bases de Datos Relacionales no son suficientes para soportar cientos de millones de usuarios, por lo que ha sido necesario  re-inventarse. Ya en una entrada anterior os hablamos sobre una base de datos no-relacional como es MongoDB.

En esta entrada hablaremos de redis de forma teórico-práctica, aunque más bien teórica. En futuras entradas veremos cómo utilizarlo junto con node.js y MongoDB. ¿Qué vamos a ver entonces?

  • ¿Qué es redis?
  • Tipos de estructura de datos que soporta
  • Instalación
  • Algunos parámetros de configuración
  • Comandos y operaciones básicas
  • Transacciones

¿Qué es redis?

Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain stringshasheslistssets and sorted sets.

La mejor definición que se me ocurre de redis es que se trata de “un servidor de caché de memoria que conoce la estructura de los datos que alberga” o dicho de otra forma, “una caché de datos con estructura”. Su nombre es un acrónimo de Servidor de DIccionario REmoto, puedes encontrar el código fuente del proyecto en su respositorio de Github.

Es una solución de código abierto de almacenamiento de datos NoSQL basado en una estructura de Llave-Valor (key-value).

Redis es sumamente veloz, debido a su sencilla estructura ausente de lógica relacional, pero sobretodo porque la base de datos está cargada en memoria. Pero si todo está en memoria, ¿qué ocurre si se apaga el ordenador? No pasa nada, redis posee 2 estrategias de persistencia para mantener los datos seguros. Si pensamos manejar grandes volúmenes de datos que podrían sobrepasar nuestra capacidad de memoria, debemos pensar en utilizar una base de datos basada en disco para los datos que no vayan a ser manipulados con tanta frecuencia y utilizar redis para aquellos de alto nivel de uso (como datos de sesión, tokens, cuentas, etcétera). En futuros ejemplos veremos cómo utilizar redis en node.js junto a MongoDB.

Además de actuar como servidor de estructuras de datos, redis aporta otras funcionalidades muy interesantes:
  • Es capaz de manejar altísimos niveles de concurrencia, por defecto esta establecido en 10000 pero puede ser fácilmente cambiado en la configuración. En este caso, la cantidad real de clientes que puede atender simultáneamente viene dada por la cantidad de descriptores de archivo que pueda manejar el sistema
  • Expiración de claves basada en tiempo
  • Sistema de Publicación y Subscripción a colas de mensajes
  • Operaciones Atómicas y Transacciones
  • Persistencia periódica de la memoria a disco, para recuperación ante caídas
  • Replicación Maestro-Esclavo, para en el futuro implementar un Cluster
  • Protocolo abierto, y uso desde decenas de lenguajes de programación

Tipos de estructura de datos que soporta

Actualmente redis soporta cinco tipos de estructuras de datos:
  1. Cadenas de caracteres (Strings)
  2. Listas (Lists)
  3. Conjuntos (Sets)
  4. Conjuntos Ordenados (Sorted Sets)
  5. Tablas Hash (Hashes)
Aunque puede parecer una lista muy corta, sólo con estos cinco tipos de estructuras se pueden modelar infinitud de procesos y aplicaciones complejas, hasta el punto que muchos de los usuarios de redis han terminado por sustituir completamente las bases de datos relacionales. Vamos a verlos con un paco más de detalle.

Cadenas de caracteres

Simplemente una llave posee un valor común y corriente tipo string:

 Listas

Este tipo de dato permite almacenar varias cadenas de caracteres ordenadas por orden de inserción en una llave, muy parecido al concepto de pilas y colas:

 Juegos o sets

Permite asignar a una llave una serie de cadenas de caracteres que no posee ningún orden. Una característica importante de los sets es que no permite miembros duplicados. Al tratar de insertar un valor duplicado en un juego, este último solo tendrá una copia del mismo. Su representación es como la de una lista.

Juegos ordenados o sorted sets

Un juego ordenado, al igual que un juego convencional, es una serie de cadenas de caracteres no duplicados que tienen asociado una puntuación. Cada miembro posee una puntuación y de esta manera se determina el orden del juego del menor a mayor.

 Hashes

Suelen utilizarse para definir objetos o mapas. Un hash permite asignar a una llave una serie de atributos y valores, tal como lo haría un objeto común.

 Instalación

No existe ningún problema para instarlo en Mac OS X o cualquier versión de Unix. Sin embargo, no hay una versión oficial para Windows, aunque podemos encontrar una versión no oficial que utilizar en desarrollo.

Lo primero que debemos hacer es descargar la última versión (actualmente es la 2.8.7) de su página oficial. Una vez descargada, descomprimirmos, instalamos y probamos que todo funcione.

Una vez instalado, en Mac OS X podemos abrir un servidor de prueba y un cliente.

Algunos parámetros de configuración

El archivo de configuración de redis es bastante intuitivo y fácil de configurar. En *nix se encuentra en el fichero 6379.conf y en Mac OS X en redis.conf

Vamos a ver algunas cosas que podemos hacer.

Frecuencia de salvado en persistencia. La configuración por defecto establece 3 casos, pero puedes agregar los que consideres necesarios. En el ejemplo: guardar en persistencia cada 60 segundos si al menos 1000 llaves han sido cambiadas, cada 5 minutos si al menos 10 llaves han cambiado o cada 15 minutos si al menos una llave cambió. Debemos tener presente que redis mantiene la base de datos en memoria y es importante que tener respaldada su información en disco.

Replicación. Establecer servidores redis de replicación de datos es sumamente sencillo, tan solo debes establecer quién es la base datos maestra. Si el servidor maestro posee clave lo debemos especificar. Una vez establecido este parámetro, la base de datos esclava se sincronizará automaticamente con la maestra.

Seguridad. Evidentemente es posible asignarle una clave de acceso a la base de datos. Adicionalmente, debido a que el comando nativo CONFIG permite cambiar la configuración de la instancia mientras funciona, podemos renombrar este comando para que cualquiera que trata de modificarlo con malas intenciones se le vea dificultada su tarea. O inclusive podemos deshabilitar el comando asignándole una cadena vacía “”.

 Bitacora de persistencia. Redis posee una segunda estrategia de persistencia que consiste en guardar en un archivo, la bitácora o lista de todos los comandos y/o acciones que han sido ejecutadas, con el fin de que si la base de datos falla, al levantarse nuevamente la información puede ser reconstruida siguiendo dicha bitácora.

Comandos y operaciones básicas

Esta es la parte más práctica y con la que estaremos continuamente jugando. Sólo voy a explicar los comando más básicos o útiles, pero podemos ver en la web oficial una lista de todos los comandos.

Cadenas de caracteres

 Contadores

Si el valón almacenado es numérico, es posible incrementarlo.

Expiradores

Podemos colocar un tiempo de vencimiento de la llave para que sea eliminada después del tiempo especificado. Con el comando TTL podemos ver el tiempo de vida que le queda a la llave (Time To Live). Si la llave es seteada nuevamente, el tiempo de expiración será eliminado. Si se asigna un nuevo valor de expiración, el contador comenzará desde el tiempo indicado.

Juegos

Usando los juegos o sets podemos agregar distintos valores a una llave. Los valores se guardan sin ningún orden en particular.

Juegos ordenados

Los juegos ordenados siguen el principio de mantener el orden de sus elementos según una puntuación que hemos asignado. El orden es de menos a mayor, sin importar el orden en el que fueron introducidos. ZRANK nos permite determinar la posición que tiene cierto valor dentro de un juego ordenado según la puntuación que tiene. ZRANGE recibe como parámetros la llave, la posición de inicio del rango a buscar y la cantidad de elementos a tomar, en nuestro caso utilizamos que empiece en la posición 0 y al indicar que seleccione -1 elementos, tomará todos los elementos del juego.

 Listas

Usar listas es muy parecido a usar pilas y colas en programación. Podemos insertar y eliminar elementos tanto en forma de cola (por la derecha) (RPUSH y RPOP) como en forma de pila (o por la izquierda) (LPUSH y LPOP).

Hashes

Los hashes son de gran utilidad para definir objetos, dónde el identificador único sería la llave principal del hash (usuario:1), la definición de atributos serian las llaves dentro del hash (nombre, apellido, …) y los valores respectivos a los atributos serían los valores de cada llave del hash (Jonathan, Wiesel, …). Inclusive podemos añadir y borrar atributos dinámicamente según sea necesario, a diferencia de la estructura común de una tabla de base de datos que las columnas se encuentran predefinidas.

 

Transacciones

Utilizamos los comandos MULTI y EXEC. MULTI para indicar que iniciamos una secuencia de acciones y EXEX para que las ejecute. Además encontramos el comando DISCARD si nos hemos equivocado en algo durante la transacción.

 

Hasta aquí llega toda la teoría y los comandos básicos. Puedes ver cómo utilizar redis en próximas entradas.

 


2 Comments

So, what do you think ?