Heim >Datenbank >Redis >Über die Leistungsanalyse von Redis unter hoher Parallelität

Über die Leistungsanalyse von Redis unter hoher Parallelität

王林
王林nach vorne
2021-03-08 09:31:521974Durchsuche

Über die Leistungsanalyse von Redis unter hoher Parallelität

Vorwort:

Ich habe kürzlich ein Projekt gestartet und war für die architektonische Gestaltung und Umsetzung des Projekts verantwortlich. Ursprünglich hat das Unternehmen viele APIs für Personen außerhalb des Unternehmens erstellt, aber wenn Außenstehende sie verwenden, wird die Schnittstellenverbindung an andere weitergegeben. Wo auch immer sich die Maschine befindet, auf der sich das Schnittstellenprogramm befindet für andere. Das geistige Eigentum ist vorhanden und es gibt keine Plattform, um es zu verwalten. Daher weiß ich genau, dass der Wert dieser Schnittstellen schwer zu ermitteln ist (welche Schnittstelle mehr von anderen verwendet wird und welche Schnittstelle weniger von anderen verwendet wird).

Nur aus Gründen der „Überwachung“ haben wir Redis als mittlere Ebene eingeführt und einen Schlüssel durch Benutzerinformationen und Adresse gehasht dieses (Schlüssel-Adresse)-Paar in Redis. Als nächstes folgt Nginx. Der Prozess von Nginx in unserem Projekt sieht ungefähr so ​​aus:

1 Nachdem sich der Benutzer registriert hat, erhält er seinen Schlüssel und greift darauf über eine URL zu, die den Schlüssel enthält, der sich völlig von der ursprünglichen URL unterscheidet. 2. Nginx erfasst den Spezialschlüssel des Benutzers. Anschließend ruft das Programm die Zieladresse basierend auf diesem Schlüssel von Redis ab. Anschließend greift Nginx im Namen des Benutzers auf die tatsächliche Adresse zu und kehrt dann zurück.

(Die Vorteile dieses Prozesses sind vielfältig)

(1) Das Programm kann in den Zugriff des Benutzers außerhalb des Upstream-Servers eingreifen. Der Eingriffsprozess kann sehr kompliziert sein ) Rufen Sie die Benutzerinformationen ab und speichern Sie sie über ein Timer-Programm in Oracle, um sie dann weiter zu analysieren und zu visualisieren. Das Problem besteht weiterhin Die Testphase ist ein Windows-Server und ein Centos6.5-Server. Während der Testphase gab es in den ersten ein oder zwei Tagen nach der Bereitstellung keine Probleme fehlgeschlagen. . Beim Betrachten des Prozesszugriffs wird die folgende Situation angezeigt. (Unter Windows Server)

Es gibt viele FiN_WAIT_2 TCP-Links.

(Lernvideo-Sharing:

Redis-Video-Tutorial

)

Über die Leistungsanalyse von Redis unter hoher ParallelitätAnalyse

1. Redis verwendet einen einzelnen Thread zur Verarbeitung von Verbindungen, was bedeutet, dass die im zweiten Schritt unten erwähnte Situation auf jeden Fall auftreten wird.

2. Dies wird offensichtlich durch viele nicht freigegebene Ressourcen zwischen Nginx und Redis verursacht und erklärt: Bei HTTP-Anwendungen liegt ein Problem vor, z Das Timeout von KEEPALIVE wechselt in den FIN_WAIT2-Status als aktiv geschlossener SERVER. Es gibt jedoch ein Problem mit dem TCP/IP-Protokollstapel. Der FIN_WAIT2-Status hat kein Timeout (im Gegensatz zum TIME_WAIT-Status). nicht schließen. Dieser FIN_WAIT_2-Status bleibt bestehen, bis das System neu gestartet wird, und immer mehr FIN_WAIT_2-Status führen zum Absturz des Kernels.

Okay, ich habe im College nicht gut gelernt. Hier sind die Statusänderungen der HTTP-Verbindung.

Client-Statusmigration ->CLOSEDb .

Serverstatusmigration

CLOSED->LISTEN->SYN empfangen->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

Bösartiger Client mit dauerhaften Verbindungen

Es gibt einige Clients Es gibt ein Problem beim Umgang mit dauerhaften Verbindungen (Akakeepalives). Wenn die Verbindung inaktiv wird und der Server die Verbindung schließt (basierend auf der KeepAliveTimeout-Direktive), ist der Client so programmiert, dass er FIN und ACK nicht an den Server zurücksendet. Dies bedeutet, dass die Verbindung im Status FIN_WAIT_2 bleibt, bis eines der folgenden Ereignisse eintritt:

Der Client öffnet eine neue Verbindung zu derselben oder einer anderen Site, wodurch die vorherige Verbindung auf diesem Socket vollständig geschlossen wird.

Der Benutzer beendet das Client-Programm, was bei einigen (vielleicht den meisten?) Clients dazu führt, dass das Betriebssystem die Verbindung vollständig schließt.

FIN_WAIT_2-Timeout, auf den Servern mit der Einstellung FIN_WAIT_2-Status-Timeout.

Wenn Sie Glück haben, bedeutet dies, dass der defekte Client die Verbindung vollständig schließt und die Ressourcen Ihres Servers freigibt.

Es gibt jedoch einige Fälle, in denen der Socket nie vollständig geschlossen wird, z. B. wenn ein Einwahl-Client die Verbindung zum ISP trennt, bevor das Client-Programm geschlossen wird.

Darüber hinaus können einige Clients mehrere Tage lang im Leerlauf sein, ohne neue Verbindungen herzustellen, und so den Socket mehrere Tage lang gültig halten, auch wenn er nicht mehr verwendet wird. Dies ist ein Fehler in der TCP-Implementierung des Browsers oder Betriebssystems.

Die Gründe sind:

1. Lange Verbindung und wenn die Verbindung immer im IDLE-Zustand ist und SERVERCLOSE verursacht, sendet der CLIENT-Programmierfehler keine FIN- und ACK-Pakete an den SERVER

2. 2 Funktion linger_close(( ) hinzugefügt, die im vorherigen Beitrag eingeführt wurde, diese Funktion könnte dieses Problem verursacht haben (ich weiß nicht warum)

 Lösung:

1. Fügen Sie einen Timeout-Mechanismus zum Status FIN_WAIT_2 hinzu. Diese Funktion ist nicht im Protokoll enthalten, wurde aber in einigen Betriebssystemen implementiert

z. B.: LINUX, SOLARIS, FREEBSD, HP-UNIX, IRIX usw.

2. Nicht mit linger_close() kompilieren

3. Verwenden Sie stattdessen SO_LINGER, was in einigen Systemen gut gehandhabt werden kann

4. Erhöhen Sie den Speicher-MBUF, der zum Speichern des Netzwerkverbindungsstatus verwendet wird, um einen Kernel-Absturz zu verhindern

5. DEAKTIVIEREN SIE KEEPALIVE

Angesichts dieser Situation haben wir mehrere Diskussionen geführt und einige Schlussfolgerungen sind:

1 Stellen Sie den Verbindungspool von Nginx und Redis ein und stellen Sie die Keepalive-Zeit auf 10 Sekunden bzw. 5 Sekunden ein, aber das Ergebnis ist Immer noch das Gleiche

2. Kein Keepalive, also kein Verbindungspool, also close() bei jeder Verwendung. Sie können sehen, dass es weniger Verbindungen gibt, aber die Nichtverwendung des Verbindungspools bedeutet, dass er geöffnet werden muss und 100.000 Mal in 10 Sekunden geschlossen, ist der Overhead zu hoch

3. Redis-Cluster: Das Hinzufügen eines Redis-Clusters zum ursprünglichen Clustersystem kann das Problem lösen, aber 100.000 Mal in 10 Sekunden ist möglicherweise nicht viel , aber es wurde nicht gefunden Frage

4. Legen Sie das Leerlaufzeitlimit von Redis fest, das Ergebnis ist das gleiche.

Lösung:

Tatsächlich handelt es sich nicht um eine Lösung, da der Speichermechanismus von Redis aufgegeben wird, sondern die Speichertechnologie von Nginx selbst verwendet wird. Der größte Teil der Online-Optimierung von Redis ist nicht anwendbar, und dieses Problem muss analysiert und gelöst werden.

Verwandte Empfehlungen: Redis-Datenbank-Tutorial

Das obige ist der detaillierte Inhalt vonÜber die Leistungsanalyse von Redis unter hoher Parallelität. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen