2017-03-13 3 views
0

Redigo ist ein Golang-Client für die redis-Datenbank. Es verwendet die Struktur 10, um einen Pool von Verbindungen aufrechtzuerhalten. Diese Struktur enthält eine Mutex-Sperre für die parallele Anwendung und Verbindung der Anwendung.Redigo-Verbindungspool - Warum die Sperre beim Entfernen der veralteten Verbindung aufheben

type Pool struct { 
    // ... 
    IdleTimeout time.Duration 
    mu  sync.Mutex 
    // Stack of idleConn with most recently used at the front. 
    idle list.List 
} 

In seinen get Verfahren entfernt Verbindungspool abgestanden (Leerlaufzeit) Verbindungen erstens. Wenn eine veraltete Verbindung gefunden wird, wird sie vom Pool freigegeben, gibt die Sperre frei, schließt die Verbindung und versucht erneut, die Sperre zu aktivieren.

Warum entsperrt Pool und versucht, Sperre wieder zu erwerben, anstatt nur entsperren, bevor Funktion zurückkehrt? Ich schätze, dass das Schließen einer Verbindung ziemlich viel Zeit kosten kann, was andere Goroutine-Wartezeiten auf diesen Mutex verlangsamen wird.

Hier ist die ganze Pool get method

+0

Ich denke, Ihre Vermutung ist richtig. Das Schließen einer Verbindung kann einige Zeit in Anspruch nehmen. Es scheint unklug, die gesamte Nutzung des Pools für diese Zeit zu sperren. –

Antwort

0

Schließen einer Verbindung ziemlich viel Zeit kosten kann, die anderen goroutine auf dieser Mutex warten verlangsamen. Was @Cerise Limón gesagt hat - Es scheint unklug, die gesamte Nutzung des Pools für diese Zeit zu sperren.

Nach dem Entsperren des Mutex erhält einer der wartenden Gatorutinen den Mutex. Obwohl goroutine für get Methode immer noch veraltete Verbindungen entfernen muss, kann die Methode put Verbindung zum Pool herstellen und so schnell wie möglich weitere Arbeiten ausführen.

+0

"Eine Verbindung zu schließen kann eine Menge Zeit kosten" --- das braucht etwas Ausarbeitung. Unter der Haube ist es als 'err: = c.fd.Close()' implementiert. Unter welchen Umständen kann das langsam sein? – zerkms

+0

@zerkms Um ehrlich zu sein kann ich das zugrunde liegende 'netFD.Close' in net/fd_unix.go nicht verstehen. In der Theorie, wenn tcp normal endet, würde jede Seite (Client und Server) FIN senden und ACK von dem anderen empfangen. Während dieser Zeit konnten Netzwerklatenz und Paketverlust auftreten. – lorneli

Verwandte Themen