Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Laravel + predis + cluster Redis - MOVIDO / sem conexão para 127.0.0.1:6379

TL;DR:

  • 'cluster' => true deve ser true para criar um cliente agregado que lide com vários nós.
  • 'options' => ['cluster' => 'redis'] precisa ser adicionado à configuração como um irmão de default (não um filho) para informar ao Predis para lidar com o cluster do lado do servidor fornecido pelo Azure.
  • se estiver usando autenticação com cluster do lado do servidor, 'options' => [ 'cluster' => 'redis', 'parameters' => ['password' => env('REDIS_PASSWORD', null)], ] será necessário para autenticar nós de cluster recém-descobertos.

Texto completo


Na configuração do redis, você pode configurar várias conexões para várias instâncias do redis. O cluster opção diz ao Laravel como lidar com essas múltiplas conexões definidas.

Se cluster está definido como false , o Laravel criará \Predis\Client individual instâncias para cada conexão. Cada conexão pode ser acessada individualmente e não terá qualquer relação com outra conexão.

Se cluster está definido como true , o Laravel criará um agregado \Predis\Client instância usando todas as conexões definidas. Sem outra configuração, este é um tipo de cluster "falso". Ele usa fragmentação do lado do cliente para distribuir o keyspace e pode exigir monitoramento e manutenção externos para garantir um equilíbrio de carga de chave adequado.

O problema que você está enfrentando, no entanto, é que o Azure implementa (presumivelmente) um cluster Redis do lado do servidor real, que lida com a fragmentação automática do keyspace. Nesse caso, os nós se conhecem e conversam entre si, podendo subir e descer. É aqui que MOVED e ASK as respostas vêm.

O Predis library pode lidar automaticamente com essas respostas, mas apenas quando você diz que precisa. Neste caso, você precisa informar ao Predis cliente que ele precisa para lidar com clustering, e isso é feito pelo Laravel através das options array no redis configuração.

No redis configuração, as options key deve ser um irmão de suas conexões (ou seja, default ), não uma criança. Além disso, as opções devem ser especificadas como key => value pares.

Assim, sua configuração deve ficar assim:
'redis' => [
    'cluster' => true,

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

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

O cluster chave sob o redis config dirá ao Laravel para criar um agregado Predis\Client instância que pode manipular vários nós e o cluster chave sob as options array dirá a essa instância que ela precisa lidar com clustering do lado do servidor, não do cluster do lado do cliente.

Autenticação


Os parâmetros de conexão originais (incluindo autenticação) não são compartilhados com conexões para novos nós descobertos via -MOVED e -ASK respostas. Portanto, todos os erros que você recebeu anteriormente de -MOVED as respostas agora serão apenas convertidas para NOAUTH erros. No entanto, o 'cluster' do lado do servidor configuração permite um 'parameters' irmão que define uma lista de parâmetros a serem usados ​​com nós recém-descobertos. É aqui que você pode colocar seus parâmetros de autenticação para usar com novos nós.

Acredito que será 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)],
    ],
],

Aviso justo, esta é toda a informação que acabei de obter de pesquisa e mergulho de código. Embora eu tenha usado o Redis com o Laravel, não usei o clustering do lado do servidor (ainda), então isso ainda pode não funcionar.

Algumas informações úteis que encontrei ao pesquisar isso:

Problema do Predis discutindo a conexão com um redis-cluster:
https://github.com/nrk/predis/issues/259#issuecomment-117339028

Parece que você não configurou o Predis para usar o redis-cluster, mas em vez disso você o está usando com a lógica de fragmentação do lado do cliente simples (que também é o comportamento padrão). Você deve configurar o cliente configurando a opção cluster com o valor redis para que o cliente saiba que deve jogar junto com redis-cluster. Exemplo rápido:

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

Isso possibilitará que o cliente manipule automaticamente as respostas -MOVED ou -ASK provenientes de nós Redis.

Artigo MS discutindo clustering no cache redis:
https://docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect- to-my-cache-when-clustering-is-habilitado

Você pode se conectar ao cache usando os mesmos endpoints, portas e chaves que usa ao se conectar a um cache que não tem clustering habilitado. O Redis gerencia o cluster no back-end para que você não precise gerenciá-lo do seu cliente.

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