Heim >Datenbank >Redis >Warum soll Redis Single-Threaded sein?

Warum soll Redis Single-Threaded sein?

王林
王林nach vorne
2021-01-11 09:31:571825Durchsuche

Warum soll Redis Single-Threaded sein?

Redis ist der Remote-Wörterbuchdienst. Es handelt sich um eine Open-Source-Schlüsselwertdatenbank vom Typ Protokoll, die in der Sprache ANSI C geschrieben ist, Netzwerke unterstützt, speicherbasiert und persistent sein kann und APIs in mehreren Sprachen bereitstellt.

(Lernvideo-Sharing: Redis-Video-Tutorial)

Dateiereignisprozessor

Redis hat einen Netzwerkereignisprozessor basierend auf dem Reactor-Modell entwickelt. Dieser Prozessor wird als Dateiereignisprozessor bezeichnet. Seine Struktur besteht aus 4 Teilen: mehreren Sockets, IO-Multiplexer, Dateiereignis-Dispatcher und Ereignisprozessor. Da der Verbrauch der Dateiereignis-Dispatcher-Warteschlange Single-Threaded ist, wird Redis als Single-Threaded-Modell bezeichnet.

Warum soll Redis Single-Threaded sein?

Nachrichtenverarbeitungsablauf

Der Dateiereignisprozessor verwendet E/A-Multiplexverfahren (Multiplexing), um mehrere Sockets gleichzeitig abzuhören und die Sockets entsprechend den aktuell von den Sockets ausgeführten Aufgaben zuzuordnen. Verschiedene Ereignishandler.

Wenn der überwachte Socket bereit ist, Vorgänge wie Verbindungsantwort (Akzeptieren), Lesen (Lesen), Schreiben (Schreiben), Schließen (Schließen) usw. auszuführen, wird das dem Vorgang entsprechende Dateiereignis generiert Zu diesem Zeitpunkt ruft der Datei-Ereignishandler den zuvor dem Socket zugeordneten Ereignishandler auf, um diese Ereignisse zu verarbeiten.

Obwohl mehrere Dateiereignisse gleichzeitig auftreten können, schiebt der E/A-Multiplexer immer alle ereignisgenerierenden Sockets in eine Warteschlange und durchläuft diese Warteschlange dann der Reihe nach (sequentiell), synchron, wobei er Sockets an den Dateiereignis-Dispatcher überträgt Socket zu einem Zeitpunkt: Nachdem das vom vorherigen Socket generierte Ereignis verarbeitet wurde (der Socket ist der dem Ereignis zugeordnete Ereignishandler). Der E/A-Multiplexer sendet weiterhin den nächsten Socket an den Dateiereignis-Dispatcher, bis der E/A-Multiplexer verarbeitet wird ausgeführt).

Implementierung des I/O-Multiplexing-Programms

Alle Funktionen des I/O-Multiplexing-Programms von Redis werden durch Packen der I/O-Multiplexing-Funktionsbibliotheken wie select, epoll, evport und kqueue implementiert, denen jede I/O-Multiplexing-Funktionsbibliothek entspricht eine separate Datei im Redis-Quellcode, z. B. ae_select.c, ae_epoll.c, ae_kqueue.c usw.

Da Redis für jede I/O-Multiplexing-Funktionsbibliothek dieselbe API implementiert, ist die zugrunde liegende Implementierung des I/O-Multiplexing-Programms austauschbar, wie in der folgenden Abbildung dargestellt.

Warum soll Redis Single-Threaded sein?

Für eine detaillierte Erklärung von Epoll können Sie auf klicken, um das Prinzip des effizienten Betriebs von Epoll anzuzeigen und gründlich zu verstehen.

Redis verwendet das #include-Makro, um die entsprechenden Regeln und Verfahren im Implementierungsquellcode von I zu definieren /O-Multiplexing-Programm Die E/A-Multiplexing-Funktionsbibliothek mit der besten Leistung im System wird zur Kompilierungszeit automatisch als zugrunde liegende Implementierung des E/A-Multiplexing-Programms von Redis ausgewählt:

/* Include the best multiplexing layer supported by this system.
 * The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
    #ifdef HAVE_EPOLL
    #include "ae_epoll.c"
    #else
        #ifdef HAVE_KQUEUE
        #include "ae_kqueue.c"
        #else
        #include "ae_select.c"
        #endif
    #endif
#endif

Typen von Dateiereignissen

I/O Multiple Der Straßenmultiplexer kann das ae.h/AE_READABLE-Ereignis und das ae.h/AE_WRITABLE-Ereignis mehrerer Sockets überwachen. Die Entsprechung zwischen diesen beiden Arten von Ereignissen und Socket-Operationen ist wie folgt:

Wenn der Socket lesbar wird (der Der Client führt einen Schreibvorgang für den Socket aus oder führt einen Schließvorgang aus. Wenn ein neuer akzeptabler Socket angezeigt wird (der Client führt einen Verbindungsvorgang für den Listening-Socket des Servers aus), generiert die Socket-Schnittstelle das Ereignis AE_READABLE.

Wenn der Socket beschreibbar wird (der Client führt einen Lesevorgang für den Socket aus), generiert der Socket das AE_WRITABLE-Ereignis. Der E/A-Multiplexer ermöglicht es dem Server, gleichzeitig auf das AE_READABLE-Ereignis und das AE_WRITABLE-Ereignis des Sockets zu hören. Wenn ein Socket beide Ereignisse gleichzeitig generiert, priorisiert der Dateiereignis-Dispatcher das AE_READABLE-Ereignis und wartet, bis das Das AE_READABLE-Ereignis wird verarbeitet. Anschließend wird das AE_WRITABLE-Ereignis verarbeitet. Das heißt, wenn ein Socket sowohl lesbar als auch beschreibbar ist, liest der Server zuerst vom Socket und schreibt dann in den Socket.

Dateiereignisprozessor

Redis hat mehrere Prozessoren für Dateiereignisse geschrieben, die zur Implementierung verschiedener Netzwerkkommunikationsanforderungen verwendet werden:

Um auf verschiedene mit dem Server verbundene Clients zu reagieren, Der Server ordnet den Verbindungsantworthandler dem Listening-Socket zu.

Um die Befehlsanforderung vom Client zu empfangen, muss der Server den Befehlsanforderungshandler mit dem Client-Socket verknüpfen.

Um das Ausführungsergebnis des Befehls an den Client zurückzugeben, muss der Server den Befehlsantwortprozessor dem Client-Socket zuordnen.

Verbindungsantwortprozessor

Die Funktion „acceptTcpHandler“ in networking.c ist der Verbindungsantwortprozessor von Redis. Dieser Prozessor wird verwendet, um auf die Verbindung des Clients mit dem Listening-Socket des Servers zu reagieren Verpackung.

Wenn der Redis-Server initialisiert wird, ordnet das Programm diesen Verbindungsantwortprozessor dem AE_READABLE-Ereignis des Server-Listening-Sockets zu. Wenn ein Client die Funktion sys/socket.h/connect verwendet, um eine Verbindung zum Server-Listening-Socket herzustellen, wird der Socket dies tun Generieren Sie das AE_READABLE-Ereignis, lösen Sie die Ausführung des Verbindungsantwortprozessors aus und führen Sie die entsprechende Socket-Antwortoperation aus, wie in der Abbildung gezeigt.

Warum soll Redis Single-Threaded sein?

Befehlsanforderungsprozessor

Die readQueryFromClient-Funktion in networking.c ist der Befehlsanforderungsprozessor von Redis. Dieser Prozessor ist für das Lesen des vom Client gesendeten Befehlsanforderungsinhalts verantwortlich. Die spezifische Implementierung ist unistd.h /read-Funktionswrapper.

Wenn ein Client über den Verbindungsantwortprozessor erfolgreich eine Verbindung zum Server herstellt, ordnet der Server das AE_READABLE-Ereignis des Client-Sockets dem Befehlsanforderungsprozessor zu. Wenn der Client eine Befehlsanforderung an den Server sendet, sendet der Socket das AE_READABLE-Ereignis generiert werden, wodurch der Befehlsanforderungsprozessor den entsprechenden Socket-Lesevorgang ausführt und durchführt, wie in der Abbildung gezeigt.

Warum soll Redis Single-Threaded sein?

Während des gesamten Prozesses der Verbindung des Clients mit dem Server ordnet der Server immer Befehlsanforderungsprozessoren für das AE_READABLE-Ereignis des Client-Sockets zu.

Befehlsantwortprozessor

Die sendReplyToClient-Funktion in networking.c ist der Befehlsantwortprozessor von Redis. Dieser Prozessor ist dafür verantwortlich, die vom Server erhaltene Befehlsantwort über den Socket an den Client zurückzugeben unistd.h /write-Funktionswrapper.

Wenn der Server eine Befehlsantwort hat, die an den Client gesendet werden muss, ordnet der Server das AE_WRITABLE-Ereignis des Client-Sockets dem Befehlsantwortprozessor zu, wenn der Client bereit ist, die vom Server zurückgesendete Befehlsantwort zu empfangen Das Ereignis AE_WRITABLE löst die Ausführung des Befehlsantwortprozessors aus und führt den entsprechenden Socket-Schreibvorgang aus, wie in der Abbildung dargestellt.

Warum soll Redis Single-Threaded sein?

Nachdem die Befehlsantwort gesendet wurde, trennt der Server den Befehlsantworthandler vom AE_WRITABLE-Ereignis des Client-Sockets.

Ein vollständiges Beispiel für ein Client-Server-Verbindungsereignis

Angenommen, der Redis-Server läuft, dann sollte sich das AE_READABLE-Ereignis des Abhör-Sockets dieses Servers im Abhörstatus befinden, und der diesem Ereignis entsprechende Prozessor ist der Verbindungsantwortprozessor .

Wenn ein Redis-Client zu diesem Zeitpunkt eine Verbindung zum Redis-Server initiiert, generiert der Listening-Socket ein AE_READABLE-Ereignis, das die Ausführung des Verbindungsantwortprozessors auslöst: Der Prozessor antwortet auf die Verbindungsanforderung des Clients und erstellt dann einen Client-Socket Wörter sowie den Clientstatus und verknüpft das AE_READABLE-Ereignis des Client-Sockets mit dem Befehlsanforderungshandler, sodass der Client Befehlsanforderungen an den Hauptserver senden kann.

Danach sendet der Client eine Befehlsanforderung an den Redis-Server. Anschließend generiert der Client-Socket ein AE_READABLE-Ereignis, das die Ausführung des Befehlsanforderungsprozessors auslöst. Der Prozessor liest den Befehlsinhalt des Clients und übergibt ihn dann an das entsprechende Programm Ausführung.

Durch das Ausführen von Befehlen werden entsprechende Befehlsantworten generiert. Um diese Befehlsantworten an den Client zurückzusenden, ordnet der Server das AE_WRITABLE-Ereignis des Client-Sockets dem Befehlsantwortprozessor zu: Wenn der Client versucht, die Befehlsantwort zu lesen Der Client-Socket generiert ein AE_WRITABLE-Ereignis und löst die Ausführung des Befehlsantwortprozessors aus. Wenn der Befehlsantwortprozessor alle Befehlsantworten in den Socket schreibt, gibt der Server das AE_WRITABLE-Ereignis und die Befehlsantwort des Client-Sockets frei.

Warum soll Redis Single-Threaded sein?

Verwandte Empfehlungen: Redis-Datenbank-Tutorial

Das obige ist der detaillierte Inhalt vonWarum soll Redis Single-Threaded sein?. 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