sql >> Base de Datos >  >> NoSQL >> Redis

Laravel + predis + Redis cluster - MOVIDO / sin conexión a 127.0.0.1:6379

TL;DR:

  • 'cluster' => true debe ser verdadero para crear un cliente agregado que maneje múltiples nodos.
  • 'options' => ['cluster' => 'redis'] debe agregarse a la configuración como hermano de default (no un niño) para decirle a Predis que maneje la agrupación en clústeres del lado del servidor proporcionada por Azure.
  • si usa autenticación con agrupación en clúster del lado del servidor, 'options' => [ 'cluster' => 'redis', 'parameters' => ['password' => env('REDIS_PASSWORD', null)], ] será necesario para autenticar los nodos de clúster recién descubiertos.

Texto completo

En la configuración de redis, puede configurar varias conexiones a varias instancias de redis. El cluster La opción le dice a Laravel cómo manejar esas múltiples conexiones definidas.

Si cluster se establece en false , Laravel creará \Predis\Client individuales instancias para cada conexión. Se puede acceder a cada conexión individualmente y no tendrá ninguna relación con otra conexión.

Si cluster se establece en true , Laravel creará un \Predis\Client agregado instancia utilizando todas las conexiones definidas. Sin otra configuración, este es una especie de clúster "falso". Utiliza fragmentación del lado del cliente para distribuir el espacio de claves y puede requerir supervisión y mantenimiento externos para garantizar un equilibrio de carga de claves adecuado.

Sin embargo, el problema con el que se está encontrando es que Azure implementa (presumiblemente) un clúster de Redis del lado del servidor real, que maneja la fragmentación automática del espacio de claves. En este caso, los nodos se conocen y hablan entre sí, y pueden subir y bajar. Aquí es donde MOVED y ASK provienen las respuestas.

Los Predis biblioteca puede manejar automáticamente estas respuestas, pero solo cuando usted le dice que lo necesita. En este caso, debe informar al Predis cliente que necesita manejar la agrupación, y esto lo hace Laravel a través de las options matriz en redis configuración.

En redis configuración, las options la clave debe ser un hermano de sus conexiones (es decir, default ), no un niño. Además, las opciones deben especificarse como key => value parejas.

Entonces, su configuración debería verse así:

'redis' => [
    'cluster' => true,

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

    'options' => [
        'cluster' => 'redis',
    ],
],

El cluster tecla debajo de redis config le dirá a Laravel que cree un agregado Predis\Client instancia que puede manejar múltiples nodos, y el cluster clave debajo de las options array le dirá a esa instancia que necesita manejar la agrupación en clústeres del lado del servidor, no la agrupación en clústeres del lado del cliente.

Autorización

Los parámetros de conexión originales (incluida la autenticación) no se comparten con las conexiones a nuevos nodos descubiertos a través de -MOVED y -ASK respuestas Entonces, cualquier error que obtuviste previamente de -MOVED las respuestas ahora solo se convertirán a NOAUTH errores Sin embargo, el 'cluster' del lado del servidor la configuración permite un 'parameters' hermano que define una lista de parámetros para usar con los nodos recién descubiertos. Aquí es donde puede utilizar sus parámetros de autenticación con nuevos nodos.

Creo que esto se verá algo como:

'redis' => [
    'cluster' => true,

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

    'options' => [
        'cluster' => 'redis',
        'parameters' => ['password' => env('REDIS_PASSWORD', null)],
    ],
],

Advertencia justa, esta es toda la información que acabo de obtener de la investigación y el buceo de código. Si bien he usado Redis con Laravel, no he usado la agrupación en clústeres del lado del servidor (todavía), por lo que es posible que aún no funcione.

Algunas piezas de información útiles que encontré mientras investigaba esto:

Problema de Predis sobre la conexión a un clúster de redis:
https://github.com/nrk/predis/issues/259#issuecomment-117339028

Parece que no configuró Predis para usar redis-cluster, sino que lo está usando con la antigua lógica de fragmentación del lado del cliente (que también es el comportamiento predeterminado). Debe configurar el cliente configurando el clúster de opciones con el valor redis para que el cliente sepa que debe jugar junto con redis-cluster. Ejemplo rápido:

$client = new Predis\Client([$node1, $node2, ...], ['cluster' => 'redis']);

Al hacerlo, el cliente podrá manejar automáticamente las respuestas -MOVED o -ASK provenientes de los nodos de Redis.

Artículo de MS sobre la agrupación en clústeres en caché de redis:
https://docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect- a-mi-caché-cuando-la-agrupación-está-habilitada

Puede conectarse a su caché usando los mismos puntos finales, puertos y claves que usa cuando se conecta a un caché que no tiene la agrupación en clústeres habilitada. Redis administra el agrupamiento en el backend para que no tenga que administrarlo desde su cliente.

Código Laravel para crear Predis\Client instancias:
https://github.com/laravel/framework/blob/v5.3.28/src/Illuminate/Redis/Database.php#L25-L66