Instalación y gestión de sesiones con Redis

¿Que es Redis?

Redis es un sistema de cache y servidor de estructuras de datos que admite diferentes tipos de valores. A diferencia de otros almacenes de valores-clave, en Redis el valor no está limitado a una cadena simple, sino que puede contener estructuras de datos complejas.

Tipos de estructuras que podemos encontrar en Redis:

  • Cuerdas binarias seguras.
  • Listas: colecciones de elementos de cadena ordenados de acuerdo con el orden de inserción. Básicamente son listas vinculadas.
  • Conjuntos: colecciones de elementos de cadena únicos y sin clasificar.
  • Conjuntos ordenados, similares a Conjuntos, pero donde cada elemento de cadena está asociado a un valor de número flotante, llamado puntaje . Los elementos siempre se toman ordenados por su puntuación, por lo que a diferencia de Sets, es posible recuperar un rango de elementos.
  • Hashes, que son mapas compuestos de campos asociados con valores. Tanto el campo como el valor son cadenas. Esto es muy similar a los hashes de Ruby o Python.
  • Arrays de bits (o simplemente mapas de bits): es posible, usando comandos especiales, manejar valores de Cadena como una matriz de bits: puede establecer y borrar bits individuales, contar todos los bits configurados en 1, encontrar el primer conjunto o un bit no configurado. Etcétera.
  • HyperLogLogs: esta es una estructura de datos probabilísticos que se usa para estimar la cardinalidad de un conjunto. No tengas miedo, es más simple de lo que parece … Ver más adelante en la sección HyperLogLog de este tutorial.

Instalación de Redis

El responsable de almacenar y recuperar los datos guardados en las sesiones: de manera predeterminada, puede usar archivos PHP para esto. Se puede utilizar un controlador de sesión externo para crear entornos PHP escalables detrás de un equilibrador de carga, donde todos los nodos de aplicaciones se conectarán a un servidor central para compartir información de la sesión.

Requisitos previos

Redis se puede instalar directamente en el servidor junto con los demás servicios o en un servidor intependiente el cual estará ubicado en el mismo centro de datos con redes privadas habilitados para conectar el servidor redis con el servidor web.

Necesitamos por lo tanto:

  • Un servidor web con PHP para poder ejecutar LAMP.
  • Un servidor para ejecutar Redis.
  • Acceso SSH a ambos servidores.

Pasos para la instalación:

  1. Actualizamos la cache del administrador:
    $ sudo apt-get update
  2. Instalación de Redis en servidor dedicado:
    $ sudo apt-get install redis-server
  3. Instalación de Redis en el servidor web:
    $ sudo apt-get install php5-redis
  4. Comprobamos la instalación:
    $ redis-cli ping

Configuración de Redis

Por defecto Redis solo permite conexiones desde localhost al puerto 6379. Si utilizamos un servidor para Redis, necesitaremos cambiar la configuración para permitir las conexiones de otros servidores.

Configuración de Redis en servidor dedicado

Para ello en primer lugar comprobamos la información de red privada, en concreto la dirección IP de la red privada del servidor Redis:

Podemos consultar esta información ejecutando:
$ sudo ifconfig

Donde podemos encontrar la dirección IP en el valor innet_addr asignado a la interfaz eth1. Un ejemplo sería:

eth1      
Link encap:Ethernet  HWaddr 32:f6:26:a8:0f:7a
inet addr:10.155.15.155  Bcast:10.255.17.255  Mask:255.255.255.0
inet6 addr: fe80::30f6:26ff:fea8:f7a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:29427281 errors:0 dropped:0 overruns:0 frame:0
TX packets:21976386 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2977408632 (2.7 GiB)  TX bytes:49188842934 (45.8 GiB)
Interrupt:30

Una vez obtenida la dirección IP privada, procederemos a configurarla en el fichero de configuración de redis:
$ vim /etc/redis/redis.conf

Y añadiremos la IP a la línea «bind localhost», un ejemplo de como quedaría sería:
bind localhost 10.155.15.155

Podríamos encontrar 127.0.0.1 en lugar de localhost, es correcto, no deberíamos modificarlo.

A continuación reiniciamos el servicio de Redis para aplicar los cambios:
$ service redis-server restart

Configuración de Redis en servidor Web

Después de instalar el paquete php5-redis deberémos añadir en el fichero de configuración de php, el php.ini, la siguiente directiva:
sudo vim /etc/php5/apache2/php.ini

Buscaremos la línea session.save_handler, la cual tendrá un valor predeterminado de files y deberíamos cambiarlo a redis, debería quedar de la siguiente forma:
session.save_handler = redis

También buscaremos la línea session.save_path, la descomentaremos y ajustaremos los valores, siempre siguiendo el siguiente formato:
tcp://IPADDRESS:PORT?auth=REDISPASSWORD

En nuestro ejemplo debería quedar así:
session.save_path = "tcp:// 10.155.15.155:6379 ?auth=frase_compleja_aqui "

Configurar contraseña para Redis

Es recomendable establecer una clave de seguridad para acceder a los datos del servidor Redis. Para ellos volveremos a editar el fichero de configuración de Redis:
$ vim /etc/redis/redis.conf

Buscaremos la línea requirepass, la descomentaremos y añadiremos nuestra clave segura, por ejemplo:
requirepass frase_compleja_aqui

Volvemos a reiniciar el servicio para aplicar los cambios:
$ service redis-server restart

Por último reiniciamos el servicio web para aplicar los cambios:
$ service apache2 restart

Comprobar la conexión y autenticación de Redis

Para comprobar los cambios, en primer lugar probaremos la conexión desde el propio servidor Redis:
$ redis-cli -h 10.155.15.155

Lo que nos debería mostrar:
10.155.15.155:6379>

Dado que hemos definido una clave segura, si intentamos acceder a los datos nos debería devolver un error de autenticación:
10.155.15.155:6379> keys *

Lo que nos devolvería:
Output
(error) NOAUTH Authentication required.

Para conectarse con la clave segura, solamente debemos ejecutar previamente el comando AUTH:
10.155.15.155:6379> AUTH frase_compleja_aqui
y a continuación ya podemos consultar las llaves:
10.155.15.155:6379> keys *

Ahora ya nos debería devolver la lista de llaves, como por ejemplo:
1) "PHPREDIS_SESSION: j9dtltde7st3sqb5al6a5d3j83"

Probar el manejo de sesiones en Redis

Para asegurarse de que las sesiones se manejar correctamente desde Redis, podemos ejecutar un script de pruebas, como por ejemplo:

 session_start ();
 $count = isset($_SESSION['count'])? $_SESSION['count']: 1;
 echo $ count;
 $_SESSION['count'] = ++$count;

Este script aplica un contador de sesiones, el cual debería incrementarse en cada recarga de página. Recuerda añadirlo dentro de las etiquetas php.

Accedermos al fichero a través del navegador:
http://dominio.com/test_Redis.php

Conclusiones

Redis es un potente y rápido servicio de almacenamiento de valor-llave, además de un excelente controlador de sesiones PHP para entornos distribuidos.

Fuentes:

  • https://redis.io/topics/data-types-intro
  • https://www.cloudways.com/blog/setup-redis-as-session-handler-php/
  • https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04