Predis: Erreur lors de la lecture de la ligne du serveur

Créé le 16 juin 2011  ·  21Commentaires  ·  Source: predis/predis

Utilisation de redis pour la branche php 5.2. J'obtiens une erreur aléatoire "Erreur lors de la lecture de la ligne du serveur". La commande que j'ai utilisée est lpush une chaîne sérialisée.

J'utilise predis sur un script de démon php, ce qui signifie qu'il est actif tout le temps. J'ai déjà défini le délai d'attente de redis.conf sur 0.

Commentaire le plus utile

Si vous utilisez Predis dans un script de type démon, vous devez définir read_write_timeout sur -1 si vous souhaitez désactiver complètement le délai d'attente (cette valeur fonctionne avec les versions plus anciennes et plus récentes de Predis). N'oubliez pas non plus que vous devez désactiver le délai d'expiration par défaut de Redis en définissant timeout = 0 dans redis.conf, sinon Redis

Tous les 21 commentaires

Avez-vous déjà suivi les étapes décrites ici pour déboguer votre problème avant d'ouvrir un nouveau problème avec le même titre ? Voir aussi ce fil de

Merci nrk. Je vais essayer de définir socket_timeout et read_write_timeout et rapporter mes découvertes ici plus tard.

Si vous utilisez Predis dans un script de type démon, vous devez définir read_write_timeout sur -1 si vous souhaitez désactiver complètement le délai d'attente (cette valeur fonctionne avec les versions plus anciennes et plus récentes de Predis). N'oubliez pas non plus que vous devez désactiver le délai d'expiration par défaut de Redis en définissant timeout = 0 dans redis.conf, sinon Redis

nrk, essayé comme mentionné et cela fonctionne maintenant parfaitement. Merci!

Cependant, il y a encore beaucoup de délais de connexion de temps en temps. J'ai déjà défini timeout = 0 et read_write_timeout à -1. Y a-t-il quelque chose que nous puissions faire pour déboguer cela lorsqu'il se produit ?

timeout n'est pas un paramètre de connexion reconnu par Predis, vous devez utiliser connection_timeout place. La valeur par défaut de connection_timeout est de 5 secondes, vous pouvez essayer d'augmenter sa valeur mais je ne pense pas que ce soit une solution à votre problème. Vous devriez essayer de voir ce qui se passe sur votre serveur lorsque ces délais d'attente se produisent, cela dépend vraiment de votre application, je ne peux donc pas vous aider. Les raisons possibles de ces délais d'attente pourraient être :

  1. problèmes de connectivité réseau si votre serveur Redis n'est pas sur l'hôte local
  2. êtes-vous sûr de ne pas utiliser des appels coûteux à la commande KEYS quelque part dans vos scripts ? Selon le nombre de clés stockées sur Redis, KEYS peut finir par bloquer le serveur qui, en attendant, ne pourra pas traiter d'autres requêtes ou connexions entrantes.

Je vais laisser ce problème ouvert pour le moment, mais je suis sûr que ce n'est certainement pas quelque chose lié à Predis.

nrk. Comme conseillé, j'ai augmenté connection_timeout à 30. Je surveillerai cela.

  1. Oui, nous utilisons plusieurs nœuds redis qui ne sont pas des hôtes locaux mais ils sont sur un réseau privé (donc au moins devrait-il être plus stable ?)
  2. Ne pas utiliser de CLÉS. Cependant, nous prenons des instantanés tous les 900. D'après le journal, il semble que le système met 8 secondes pour enregistrer en HD. Cela ne devrait-il pas être la cause du délai d'expiration de la connexion, n'est-ce pas ?
  3. Des conseils sur la façon de surveiller le serveur lorsque le délai d'attente se produit ? Le délai d'attente est assez aléatoire. J'ai vérifié le journal Redis, et la plupart du temps, il s'agit simplement de prendre des instantanés de messages.

Autre mise à jour, j'ai mesuré la connexion, et il semble qu'effectivement l'exception se soit produite après 5s. J'ai essayé de modifier le connection_timeout via :

new Predis_Client($param, array('read_write_timeout' => -1, 'connection_timeout' => 30));

Est-ce exact? Il ne semble pas prendre effet les 30s connection_timeout et toujours lever une exception.

Ce sont des paramètres de connexion et non des options client, donc read_write_timeout et connection_timeout doivent être spécifiés comme paramètres dans $param .

  1. À moins qu'il ne s'agisse d'un réseau privé sur Amazon EC2 (latence élevée et divers problèmes de temps en temps), cela ne devrait pas.
  2. L'instantané ne devrait pas bloquer le serveur pour autant que je sache
  3. Vous pouvez vérifier les délais d'expiration par rapport aux journaux de capture d'écran. A part ça, cela dépend vraiment de l'architecture de votre application et de votre infrastructure, désolé mais je ne peux pas vous aider là-dessus.

Honnêtement, Predis ne fait rien d'extraordinaire avec les ressources de socket lors de la connexion à un hôte car c'est quelque chose qui est délégué presque entièrement aux internes de PHP, il peut donc s'agir d'un bogue dans PHP (peu probable, mais toujours possible) ou d'une configuration/d'exécution problème sur vos serveurs, ou Redis effectuant des opérations lourdes qui finissent par bloquer le serveur pendant un certain temps.

nrk, merci encore pour votre réponse. J'ai trouvé le problème, et c'est juste le serveur à court de problème ip_conntrack. Une fois le conntrack corrigé, le délai d'expiration de la connexion disparaît également.

Ravi de savoir que vous avez enfin trouvé le véritable problème derrière ces délais d'attente. J'ajouterai probablement cela quelque part dans la FAQ pour donner aux utilisateurs une liste initiale de vérifications pour résoudre les problèmes de délai d'attente.

obtenait la même erreur, résolue en définissant read_write_timeout sur 0.
Je l'ai fait dans predis, pouvons-nous faire la même chose en utilisant le client predis ?
comme indiqué ici http://code.google.com/p/dires/source/browse/trunk/predis/examples/PubSubContext.php?r=4
Je crée un client predis en utilisant : $redis = new Predis\Client("tcp://".$turboConfig->getActivitiesRedisHost()); comment dois-je passer read_write_timeout dans mon implémentation.

@amitchhajer le client accepte les mêmes paramètres de connexion avec des tableaux nommés ou des chaînes d'URI, donc si vous utilisez une chaîne d'URI, vous pouvez simplement l'ajouter comme s'il s'agissait d'une chaîne de requête : tcp://127.0.0.1:6379?read_write_timeout=0 .

@nrk merci pour l'info,

Que se passe-t-il si nous devons modifier read_write_timeout au moment de l'exécution ? Existe-t-il un setter pour les paramètres de délai d'attente (à l'exception du constructeur) ?

Les paramètres de connexion

$connection = $client->getConnection();
$stream = $connection->getResource();
stream_set_timeout($stream, 2);

Veuillez noter que faire $connection->getResource() déclenche effectivement l'opération connect() sur Redis, vous risquez donc de perdre les avantages des connexions paresseuses selon la façon dont vous allez utiliser cette fonctionnalité.

Veuillez noter que le paramètre connection_timeout a été renommé en timeout dans la nouvelle version de Predis.

J'utilise assez largement les « touches h ». Cela peut-il conduire à des verrous ?

Si vous utilisez Predis dans un script de type démon, vous devez définir read_write_timeout sur -1 si vous souhaitez désactiver complètement le délai d'attente (cette valeur fonctionne avec les versions plus anciennes et plus récentes de Predis). N'oubliez pas non plus que vous devez désactiver le délai d'expiration par défaut de Redis en définissant timeout = 0 dans redis.conf, sinon Redis

Un inconvénient ou une précaution associés à la définition de timeout=0 sur redis.conf ?

Ce que je soupçonne, c'est que les connexions ne seront jamais interrompues
L'utilisation de Redis restera élevée

nrk, merci encore pour votre réponse. J'ai trouvé le problème, et c'est juste le serveur à court de problème ip_conntrack. Une fois le conntrack corrigé, le délai d'expiration de la connexion disparaît également.

Comment réparer ce contrat.. où chercher ?

Un inconvénient ou une précaution associés à la définition de timeout=0 sur redis.conf ?

@aditya-rewari-cb en fait timeout = 0 dans redis.conf est la valeur par défaut depuis Redis 2.4 (publié il y a quelques années), donc je dirais qu'il n'y a pas d'inconvénients.

Si vous utilisez Predis dans un script de type démon, vous devez définir read_write_timeout sur -1 si vous souhaitez désactiver complètement le délai d'attente (cette valeur fonctionne avec les versions plus anciennes et plus récentes de Predis). N'oubliez pas non plus que vous devez désactiver le délai d'expiration par défaut de Redis en définissant timeout = 0 dans redis.conf, sinon Redis

@nrk J'utilise Redis avec des processus démons (travailleurs du superviseur laravel), ainsi que , avec une mise en cache régulière
Attention à l'utilisation de 'read_write_timeout' => -1 ?
Je voulais confirmer toute possibilité de casse ou de bug.. dans mon utilisation régulière de la mise en cache de Redis, en raison de ce changement !

Merci !

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

koda0611 picture koda0611  ·  4Commentaires

tillkruss picture tillkruss  ·  13Commentaires

luoxun picture luoxun  ·  7Commentaires

tillkruss picture tillkruss  ·  7Commentaires

jackyxie picture jackyxie  ·  7Commentaires