Redis
 sql >> Base de données >  >> NoSQL >> Redis

Cluster Laravel + predis + Redis - MOVED / pas de connexion à 127.0.0.1:6379

TL ;DR :

  • 'cluster' => true doit être vrai pour créer un client agrégé qui gère plusieurs nœuds.
  • 'options' => ['cluster' => 'redis'] doit être ajouté à la configuration en tant que frère de default (pas un enfant) afin de dire à Predis de gérer le clustering côté serveur fourni par Azure.
  • si vous utilisez auth avec un clustering côté serveur, 'options' => [ 'cluster' => 'redis', 'parameters' => ['password' => env('REDIS_PASSWORD', null)], ] sera nécessaire pour authentifier les nœuds de cluster nouvellement découverts.

Texte intégral

Dans la configuration Redis, vous pouvez configurer plusieurs connexions à plusieurs instances Redis. Le cluster L'option indique à Laravel comment gérer ces multiples connexions définies.

Si cluster est défini sur false , Laravel créera un \Predis\Client individuel instances pour chaque connexion. Chaque connexion est accessible individuellement et n'aura aucune relation avec une autre connexion.

Si cluster est défini sur true , Laravel créera un agrégat \Predis\Client instance en utilisant toutes les connexions définies. Sans autre configuration, c'est une sorte de "faux" cluster. Il utilise le partitionnement côté client pour distribuer l'espace de clés et peut nécessiter une surveillance et une maintenance externes pour garantir un bon équilibre de la charge des clés.

Le problème que vous rencontrez, cependant, est qu'Azure implémente (vraisemblablement) un véritable cluster Redis côté serveur, qui gère le partitionnement automatique de l'espace de clés. Dans ce cas, les nœuds se connaissent et se parlent, et peuvent monter et descendre. C'est là que MOVED et ASK d'où viennent les réponses.

Les Predis library peut gérer automatiquement ces réponses, mais uniquement lorsque vous lui indiquez qu'elle en a besoin. Dans ce cas, vous devez informer le Predis client dont il a besoin pour gérer le clustering, et cela est fait par Laravel via les options tableau sur le redis configuration.

Sur le redis configuration, les options key doit être un frère de vos connexions (c'est-à-dire default ), pas un enfant. De plus, les options doivent être spécifiées sous la forme key => value paires.

Ainsi, votre configuration devrait ressembler à :

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

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

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

Le cluster clé sous le redis config dira à Laravel de créer un agrégat Predis\Client instance qui peut gérer plusieurs nœuds, et le cluster clé sous les options array indiquera à cette instance qu'elle doit gérer le clustering côté serveur, et non le clustering côté client.

Authentification

Les paramètres de connexion d'origine (y compris l'authentification) ne sont pas partagés avec les connexions aux nouveaux nœuds découverts via -MOVED et -ASK réponses. Ainsi, toutes les erreurs que vous avez précédemment reçues de -MOVED les réponses seront désormais simplement converties en NOAUTH les erreurs. Cependant, le 'cluster' côté serveur la configuration permet un 'parameters' frère qui définit une liste de paramètres à utiliser avec les nœuds nouvellement découverts. C'est ici que vous pouvez mettre vos paramètres d'authentification à utiliser avec de nouveaux nœuds.

Je pense que cela ressemblera à :

'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)],
    ],
],

Juste avertissement, ce sont toutes les informations que je viens d'obtenir de la recherche et de la plongée dans le code. Bien que j'aie utilisé Redis avec Laravel, je n'ai pas (encore) utilisé le clustering côté serveur, donc cela peut toujours ne pas fonctionner.

Quelques informations utiles que j'ai trouvées en examinant ceci :

Problème Predis concernant la connexion à un cluster redis :
https://github.com/nrk/predis/issues/259#issuecomment-117339028

Il semble que vous n'ayez pas configuré Predis pour utiliser redis-cluster, mais que vous l'utilisiez avec l'ancienne logique de partitionnement côté client (qui est également le comportement par défaut). Vous devez configurer le client en définissant l'option cluster avec la valeur redis pour faire savoir au client qu'il doit jouer avec redis-cluster. Exemple rapide :

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

Cela permettra au client de gérer automatiquement les réponses -MOVED ou -ASK provenant des nœuds Redis.

Article MS traitant de la mise en cluster sur le cache Redis :
https://docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect- vers-mon-cache-lorsque-le-clustering-est-activé

Vous pouvez vous connecter à votre cache en utilisant les mêmes points de terminaison, ports et clés que vous utilisez lors de la connexion à un cache pour lequel la mise en cluster n'est pas activée. Redis gère le clustering sur le backend afin que vous n'ayez pas à le gérer depuis votre client.

Code Laravel pour créer Predis\Client instances :
https://github.com/laravel/framework/blob/v5.3.28/src/Illuminate/Redis/Database.php#L25-L66