Predis: Fehler beim Lesen der Zeile vom Server

Erstellt am 16. Juni 2011  ·  21Kommentare  ·  Quelle: predis/predis

Verwenden von redis für den PHP 5.2-Zweig. Ich erhalte den zufälligen Fehler "Fehler beim Lesen der Zeile vom Server". Der Befehl, den ich verwendet habe, ist lpush eine serialisierte Zeichenfolge.

Ich verwende Predis für ein PHP-Daemon-Skript, was bedeutet, dass es die ganze Zeit aktiv ist. Den Timeout für die redis.conf habe ich bereits auf 0 gesetzt.

Hilfreichster Kommentar

Wenn Sie Predis in einem daemonähnlichen Skript verwenden, sollten Sie read_write_timeout auf -1 wenn Sie das Timeout vollständig deaktivieren möchten (dieser Wert funktioniert mit älteren und neueren Versionen von Predis). Denken Sie auch daran, dass Sie das Standard-Timeout von Redis deaktivieren müssen, indem Sie timeout = 0 in der redis.conf festlegen, oder Redis wird die Verbindung von inaktiven Clients nach 300 Sekunden Inaktivität

Alle 21 Kommentare

Haben Sie die hier beschriebenen Schritte zum Debuggen Ihres Problems bereits ausgeführt, bevor Sie ein neues Problem mit demselben Titel öffnen? Siehe auch diesen Thread auf der Redis-Liste, es könnte auch etwas sein, das nichts mit clientseitigen Problemen zu tun hat.

Danke nr. Ich werde versuchen, socket_timeout und read_write_timeout zu setzen und meine Ergebnisse später hier berichten.

Wenn Sie Predis in einem daemonähnlichen Skript verwenden, sollten Sie read_write_timeout auf -1 wenn Sie das Timeout vollständig deaktivieren möchten (dieser Wert funktioniert mit älteren und neueren Versionen von Predis). Denken Sie auch daran, dass Sie das Standard-Timeout von Redis deaktivieren müssen, indem Sie timeout = 0 in der redis.conf festlegen, oder Redis wird die Verbindung von inaktiven Clients nach 300 Sekunden Inaktivität

nrk, habe es wie erwähnt versucht und es funktioniert jetzt perfekt. Danke schön!

Es gibt jedoch immer noch viele Verbindungs-Timeouts ab und zu. Ich habe bereits timeout = 0 und read_write_timeout auf -1 gesetzt. Gibt es etwas, was wir tun können, um dies zu debuggen, wenn es auftritt?

timeout ist kein von Predis erkannter Verbindungsparameter, Sie sollten stattdessen connection_timeout verwenden. Der Standardwert für connection_timeout ist 5 Sekunden. Sie könnten versuchen, den Wert zu erhöhen, aber ich glaube nicht, dass dies eine Lösung für Ihr Problem ist. Sie sollten versuchen, zu sehen, was auf Ihrem Server passiert, wenn diese Zeitüberschreitungen auftreten. Es hängt wirklich von Ihrer Anwendung ab, daher kann ich Ihnen nicht weiterhelfen. Die möglichen Gründe für diese Zeitüberschreitungen können sein:

  1. Probleme mit der Netzwerkverbindung, wenn sich Ihr Redis-Server nicht auf dem localhost befindet
  2. Sind Sie sicher, dass Sie nicht irgendwo in Ihren Skripten teure Aufrufe des Befehls KEYS ? Abhängig von der Anzahl der Schlüsselspeicher auf Redis kann KEYS den Server blockieren, der in der Zwischenzeit keine anderen Anfragen oder eingehenden Verbindungen verarbeiten kann.

Ich lasse dieses Problem vorerst offen, aber ich bin mir ziemlich sicher, dass es definitiv nichts mit Predis zu tun hat.

nr. Wie empfohlen, habe ich connection_timeout auf 30 erhöht. Werde dies überwachen.

  1. Ja, wir verwenden mehrere Redis-Knoten, die nicht localhost sind, sich aber in einem privaten Netzwerk befinden (sollten also zumindest stabiler sein?)
  2. SCHLÜSSEL nicht verwenden. Wir machen jedoch alle 900s Snapshots. Aus dem Protokoll geht hervor, dass das System 8 Sekunden braucht, um auf HD zu speichern. Sollte nicht die Ursache für das Verbindungs-Timeout sein, oder?
  3. Irgendwelche Ratschläge, wie man den Server überwacht, wenn die Zeitüberschreitung auftritt? Das Timeout ist ziemlich zufällig. Ich habe das Redis-Log überprüft, und meistens sind es nur Snapshots von Nachrichten.

Bei einem weiteren Update habe ich die Verbindung gemessen und es scheint, dass die Ausnahme tatsächlich nach 5s aufgetreten ist. Ich habe versucht, das connection_timeout über Folgendes zu ändern:

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

Ist das korrekt? Es scheint die 30s connection_timeout nicht zu übernehmen und immer noch eine Ausnahme auszulösen.

Sie sind Verbindungsparameter und keine Client-Optionen, daher müssen read_write_timeout und connection_timeout als Parameter in $param .

  1. Sofern es sich nicht um ein privates Netzwerk auf Amazon EC2 handelt (hohe Latenz und verschiedene Probleme von Zeit zu Zeit), sollte dies nicht der Fall sein.
  2. Snapshotting sollte den Server meines Wissens nicht blockieren
  3. Sie können die Zeitangaben der Zeitüberschreitungen anhand der Snapshot-Protokolle überprüfen. Abgesehen davon hängt es wirklich von der Architektur Ihrer Anwendung und Ihrer Infrastruktur ab, aber dazu kann ich Ihnen leider keine Unterstützung geben.

Ehrlich gesagt macht Predis nichts Besonderes mit den Socket-Ressourcen, wenn es eine Verbindung zu einem Host herstellt, da dies fast vollständig an die Interna von PHP delegiert wird. Es kann also entweder ein Fehler in PHP sein (unwahrscheinlich, aber immer noch eine Möglichkeit) oder eine Konfiguration / Laufzeit Problem auf Ihren Servern oder Redis führt einige schwere Operationen durch, die den Server für eine Weile blockieren.

nk, danke nochmal für deine Antwort. Ich habe das Problem gefunden, und es ist nur der Server, der kein ip_conntrack-Problem mehr hat. Sobald die Verbindung behoben ist, verschwindet auch die Verbindungszeitüberschreitung.

Schön zu wissen, dass Sie endlich das eigentliche Problem hinter diesen Timeouts gefunden haben. Ich werde dies wahrscheinlich irgendwo in den FAQ hinzufügen, um Benutzern eine erste Liste von Überprüfungen zur Fehlerbehebung bei Zeitüberschreitungen zu geben.

erhielt den gleichen Fehler, der mit der Einstellung von read_write_timeout auf 0 behoben wurde.
Ich habe das in Predis gemacht, können wir dasselbe mit dem Predis-Client machen?
wie hier gezeigt http://code.google.com/p/dires/source/browse/trunk/predis/examples/PubSubContext.php?r=4
Ich mache einen Predis-Client mit: $redis = new Predis\Client("tcp://".$turboConfig->getActivitiesRedisHost()); Wie soll ich read_write_timeout in meiner Implementierung übergeben.

@amitchhajer Der Client akzeptiert dieselben Verbindungsparameter mit beiden benannten Arrays oder URI-Strings. Wenn Sie also einen URI-String verwenden, können Sie ihn einfach wie einen Abfrage-String hinzufügen: tcp://127.0.0.1:6379?read_write_timeout=0 .

@nrk danke für die Info, funktioniert jetzt ganz gut.

Was ist, wenn wir read_write_timeout zur Laufzeit ändern müssen? Existiert ein Setter für Timeout-Parameter (außer Konstruktor)?

@bondeg- Verbindungsparameter sind absichtlich unveränderlich, was bedeutet, dass Sie sie nach dem Initialisieren der Verbindung nicht mehr ändern können. Sie können diese Einschränkung jedoch umgehen, indem Sie die zugrunde liegende Stream-Ressource aus dem vom Client verwendeten Verbindungsobjekt abrufen und die Stream-Optionen entsprechend ändern. Hier ist ein kleiner Ausschnitt, vorausgesetzt, Sie verwenden den Client nicht im Cluster- oder Replikationsmodus:

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

Bitte beachten Sie, dass die Ausführung von $connection->getResource() effektiv die Operation connect() für Redis auslöst, sodass Sie möglicherweise die Vorteile von Lazy Connections verlieren, je nachdem, wie Sie diese Funktion verwenden.

Bitte beachten Sie, dass der Parameter connection_timeout timeout in der neuen Version von Predis in

Ich verwende ' h- Tasten' ziemlich häufig. Kann das zu Sperren führen?

Wenn Sie Predis in einem daemonähnlichen Skript verwenden, sollten Sie read_write_timeout auf -1 wenn Sie das Timeout vollständig deaktivieren möchten (dieser Wert funktioniert mit älteren und neueren Versionen von Predis). Denken Sie auch daran, dass Sie das Standard-Timeout von Redis deaktivieren müssen, indem Sie timeout = 0 in der redis.conf festlegen, oder Redis wird die Verbindung von inaktiven Clients nach 300 Sekunden Inaktivität

Irgendwelche Nachteile oder Vorsichtsmaßnahmen im Zusammenhang mit der Einstellung von timeout=0 in redis.conf?

Was ich vermute ist ..da Verbindungen nie abbrechen
Redis-Auslastung bleibt hoch

nk, danke nochmal für deine Antwort. Ich habe das Problem gefunden, und es ist nur der Server, der kein ip_conntrack-Problem mehr hat. Sobald die Verbindung behoben ist, verschwindet auch die Verbindungszeitüberschreitung.

Wie kann man diesen Vertrag reparieren? Wo muss man suchen?

Irgendwelche Nachteile oder Vorsichtsmaßnahmen im Zusammenhang mit der Einstellung von timeout=0 in redis.conf?

@aditya-rewari-cb eigentlich timeout = 0 in der redis.conf ist die Standardeinstellung seit Redis 2.4 (veröffentlicht vor ein paar Jahren), also würde ich sagen, dass es keine Nachteile gibt.

Wenn Sie Predis in einem daemonähnlichen Skript verwenden, sollten Sie read_write_timeout auf -1 wenn Sie das Timeout vollständig deaktivieren möchten (dieser Wert funktioniert mit älteren und neueren Versionen von Predis). Denken Sie auch daran, dass Sie das Standard-Timeout von Redis deaktivieren müssen, indem Sie timeout = 0 in der redis.conf festlegen, oder Redis wird die Verbindung von inaktiven Clients nach 300 Sekunden Inaktivität

@nrk Ich verwende Redis mit Daemon-Prozessen (Laravel-Supervisor-Worker) sowie mit regelmäßigem Caching
Irgendeine Vorsicht bei der Verwendung von 'read_write_timeout' => -1?
Ich wollte mich auf mögliche Fehler oder Fehler bei meiner regelmäßigen Caching-Nutzung von Redis aufgrund dieser Änderung vergewissern!

Danke !

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

tillkruss picture tillkruss  ·  13Kommentare

Horki picture Horki  ·  6Kommentare

mnvx picture mnvx  ·  9Kommentare

jimbonator picture jimbonator  ·  6Kommentare

jackyxie picture jackyxie  ·  7Kommentare