Wie läuft die Verarbeitung von Redis-Anfragen ab?
Übersicht#
Das erste, was Sie tun müssen, ist, den Prozessor zu registrieren.
Öffnen Sie den Loop-Listening-Port. Jedes Mal, wenn eine Verbindung überwacht wird, wird eine Goroutine erstellt Schleife, um die Anforderungsdaten zu empfangen, und passen Sie dann den entsprechenden Prozessor in der Prozessor-Routing-Tabelle entsprechend der angeforderten Adresse an und übergeben Sie die Anforderung dann zur Verarbeitung an den Prozessor.
-
Der Code lautet wie folgt:
func (srv *Server) Serve(l net.Listener) error { ... baseCtx := context.Background() ctx := context.WithValue(baseCtx, ServerContextKey, srv) for { // 接收 listener 过来的网络连接 rw, err := l.Accept() ... tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // 创建协程处理连接 go c.serve(connCtx) } }
Nach dem Login kopieren Bei Redis ist dies etwas anders, da es Single-Threaded ist und kein Multithreading zum Verarbeiten von Verbindungen verwenden kann. Daher entscheidet sich Redis für die Verwendung eines Ereignistreibers basierend auf dem Reactor-Modus, um die gleichzeitige Verarbeitung von Ereignissen zu implementieren.
Zum Beispiel: „Akzeptieren“ entspricht dem Ereignishandler „acceptTCPHandler“, „Lesen und Schreiben“ entspricht dem Ereignishandler „readQueryFromClient“ usw., und dann wird das Ereignis dem Ereignisprozessor zur Verarbeitung durch den Ereignisschleifenversand zugewiesen.
Der obige Reaktormodus wird also über Epoll implementiert. Für Epoll gibt es hauptsächlich drei Methoden:
//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大 int epoll_create(int size); /* * 可以理解为,增删改 fd 需要监听的事件 * epfd 是 epoll_create() 创建的句柄。 * op 表示 增删改 * epoll_event 表示需要监听的事件,Redis 只用到了可读,可写,错误,挂断 四个状态 */ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); /* * 可以理解为查询符合条件的事件 * epfd 是 epoll_create() 创建的句柄。 * epoll_event 用来存放从内核得到事件的集合 * maxevents 获取的最大事件数 * timeout 等待超时时间 */ int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
Wir können also einen einfachen Server basierend auf diesen drei Methoden implementieren:
// 创建监听 int listenfd = ::socket(); // 绑定ip和端口 int r = ::bind(); // 创建 epoll 实例 int epollfd = epoll_create(xxx); // 添加epoll要监听的事件类型 int r = epoll_ctl(..., listenfd, ...); struct epoll_event* alive_events = static_cast<epoll_event*>(calloc(kMaxEvents, sizeof(epoll_event))); while (true) { // 等待事件 int num = epoll_wait(epollfd, alive_events, kMaxEvents, kEpollWaitTime); // 遍历事件,并进行事件处理 for (int i = 0; i < num; ++i) { int fd = alive_events[i].data.fd; // 获取事件 int events = alive_events[i].events; // 进行事件的分发 if ( (events & EPOLLERR) || (events & EPOLLHUP) ) { ... } else if (events & EPOLLRDHUP) { ... } ... } }
Aufrufprozess #
Also basierend auf dem oben Gesagten Einführung, Sie können wissen, dass eine Ereignisschleife für Redis nichts weiter als ein paar Schritte ist:
Ereignisüberwachungs- und Rückruffunktionen registrieren;
Schleife, die darauf wartet, Ereignisse abzurufen und zu verarbeiten; Rückruffunktion zum Verarbeiten der Datenlogik;
- Registrieren Sie fd bei epoll und stellen Sie die Rückruffunktion ein. Wenn eine neue Verbindung besteht, wird die Rückruffunktion ausgeführt aufgerufen werden;
- Starten Sie eine Endlosschleife, um epoll_wait aufzurufen, um zu warten und mit der Verarbeitung des Ereignisses fortzufahren takeTcpHandler wird vollständig aufgerufen. readQueryFromClient analysiert die Client-Daten und findet die entsprechende cmd-Funktion zur Ausführung an den Client. Ausgabepuffer, anstatt sofort zurückzukehren.
Dann wird die Funktion beforeSleep jedes Mal aufgerufen, um die Daten im Puffer zurück an den Client zu schreiben eigentlich der Code Die Schritte wurden sehr klar geschrieben und es gibt viele Artikel im Internet darüber, daher werde ich nicht auf Details eingehen.
- Befehlsausführungsprozess und Write-Back-Client#
Befehlsausführung#
Lassen Sie uns nun über etwas sprechen, das in vielen Artikeln im Internet nicht erwähnt wurde. Schauen wir uns an, wie Redis den Befehl ausführt, ihn dann im Cache speichert und schreibt die Daten aus dem Cache zurück zum Client-Prozess. - Wir haben im vorherigen Abschnitt auch erwähnt, dass bei einem Netzwerkereignis die Funktion readQueryFromClient aufgerufen wird, in der der Befehl tatsächlich ausgeführt wird. Wir werden dieser Methode folgen und nach unten schauen:
- readQueryFromClient ruft die Funktion „processInputBufferAndReplicate“ auf, um den angeforderten Befehl zu verarbeiten Der Befehl wird auf andere Knoten kopiert. Die Funktion „processInputBuffer“ verarbeitet den angeforderten Befehl in einer Schleife, ruft die Funktion „processInlineBuffer“ gemäß dem angeforderten Protokoll auf und ruft dann „processCommand“ auf, um den Befehl nach dem Objekt „redisObject“ auszuführen
processCommand geht bei der Ausführung des Befehls zur Tabelle
server.commands
, um die entsprechende Ausführungsfunktion basierend auf dem Befehl zu finden, und ruft dann nach einer Reihe von Überprüfungen die entsprechende Funktion auf, um den Befehl auszuführen Befehl und ruft addReply auf, um die zurückgegebenen Daten in den Client-Ausgabepufferbereich zu schreiben der Befehlsname. Um beispielsweise den get-Befehl auszuführen, wird die getCommand-Funktion aufgerufen: void getCommand(client *c) { getGenericCommand(c); } int getGenericCommand(client *c) { robj *o; // 查找数据 if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL) return C_OK; ... } robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) { //到db中查找数据 robj *o = lookupKeyRead(c->db, key); // 写入到缓存中 if (!o) addReply(c,reply); return o; }
Nach dem Login kopierenSuchen Sie die Daten in der getCommand-Funktion und rufen Sie dann addReply auf, um die zurückgegebenen Daten in den Client-Ausgabepuffer zu schreiben.
Daten zurück an den Client schreiben#
Nachdem der Befehl in den Puffer geschrieben wurde, müssen die Daten aus dem Puffer entnommen und an den Client zurückgegeben werden. Der Prozess des Zurückschreibens von Daten an den Client wird tatsächlich in der Ereignisschleife des Servers abgeschlossen.
Zunächst ruft Redis die Funktion aeSetBeforeSleepProc in der Hauptfunktion auf, um die Funktion beforeSleep des Writeback-Pakets in der eventLoop zu registrieren.
Anschließend ermittelt Redis, ob beforesleep vorhanden ist, wenn es die Funktion aeMain aufruft Wenn die Ereignisschleife festgelegt ist, wird sie aufgerufen. Die Funktion „beforesleep“ ruft die Funktion „handleClientsWithPendingWrites“ auf, die writeToClient aufruft, um die Daten aus dem Puffer zurück zu schreiben.
Das obige ist der detaillierte Inhalt vonWie läuft die Verarbeitung von Redis-Anfragen ab?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Der Redis -Cluster -Modus bietet Redis -Instanzen durch Sharding, die Skalierbarkeit und Verfügbarkeit verbessert. Die Bauschritte sind wie folgt: Erstellen Sie ungerade Redis -Instanzen mit verschiedenen Ports; Erstellen Sie 3 Sentinel -Instanzen, Monitor -Redis -Instanzen und Failover; Konfigurieren von Sentinel -Konfigurationsdateien, Informationen zur Überwachung von Redis -Instanzinformationen und Failover -Einstellungen hinzufügen. Konfigurieren von Redis -Instanzkonfigurationsdateien, aktivieren Sie den Cluster -Modus und geben Sie den Cluster -Informationsdateipfad an. Erstellen Sie die Datei nodes.conf, die Informationen zu jeder Redis -Instanz enthält. Starten Sie den Cluster, führen Sie den Befehl erstellen aus, um einen Cluster zu erstellen und die Anzahl der Replikate anzugeben. Melden Sie sich im Cluster an, um den Befehl cluster info auszuführen, um den Clusterstatus zu überprüfen. machen

So löschen Sie Redis -Daten: Verwenden Sie den Befehl Flushall, um alle Schlüsselwerte zu löschen. Verwenden Sie den Befehl flushdb, um den Schlüsselwert der aktuell ausgewählten Datenbank zu löschen. Verwenden Sie SELECT, um Datenbanken zu wechseln, und löschen Sie dann FlushDB, um mehrere Datenbanken zu löschen. Verwenden Sie den Befehl del, um einen bestimmten Schlüssel zu löschen. Verwenden Sie das Redis-Cli-Tool, um die Daten zu löschen.

Um eine Warteschlange aus Redis zu lesen, müssen Sie den Warteschlangenname erhalten, die Elemente mit dem Befehl LPOP lesen und die leere Warteschlange verarbeiten. Die spezifischen Schritte sind wie folgt: Holen Sie sich den Warteschlangenname: Nennen Sie ihn mit dem Präfix von "Warteschlange:" wie "Warteschlangen: My-Queue". Verwenden Sie den Befehl LPOP: Wischen Sie das Element aus dem Kopf der Warteschlange aus und geben Sie seinen Wert zurück, z. B. die LPOP-Warteschlange: my-queue. Verarbeitung leerer Warteschlangen: Wenn die Warteschlange leer ist, gibt LPOP NIL zurück, und Sie können überprüfen, ob die Warteschlange existiert, bevor Sie das Element lesen.

Die Verwendung der REDIS -Anweisung erfordert die folgenden Schritte: Öffnen Sie den Redis -Client. Geben Sie den Befehl ein (Verbschlüsselwert). Bietet die erforderlichen Parameter (variiert von der Anweisung bis zur Anweisung). Drücken Sie die Eingabetaste, um den Befehl auszuführen. Redis gibt eine Antwort zurück, die das Ergebnis der Operation anzeigt (normalerweise in Ordnung oder -err).

Um die Operationen zu sperren, muss die Sperre durch den Befehl setNX erfasst werden und dann den Befehl Ablauf verwenden, um die Ablaufzeit festzulegen. Die spezifischen Schritte sind: (1) Verwenden Sie den Befehl setNX, um zu versuchen, ein Schlüsselwertpaar festzulegen; (2) Verwenden Sie den Befehl Ablauf, um die Ablaufzeit für die Sperre festzulegen. (3) Verwenden Sie den Befehl Del, um die Sperre zu löschen, wenn die Sperre nicht mehr benötigt wird.

Der beste Weg, um Redis -Quellcode zu verstehen, besteht darin, Schritt für Schritt zu gehen: Machen Sie sich mit den Grundlagen von Redis vertraut. Wählen Sie ein bestimmtes Modul oder eine bestimmte Funktion als Ausgangspunkt. Beginnen Sie mit dem Einstiegspunkt des Moduls oder der Funktion und sehen Sie sich die Codezeile nach Zeile an. Zeigen Sie den Code über die Funktionsaufrufkette an. Kennen Sie die von Redis verwendeten Datenstrukturen. Identifizieren Sie den von Redis verwendeten Algorithmus.

Zu den Ursachen für Datenverluste gehören Speicherausfälle, Stromausfälle, menschliche Fehler und Hardwarefehler. Die Lösungen sind: 1. Speichern Sie Daten auf Festplatten mit RDB oder AOF Persistenz; 2. Kopieren Sie auf mehrere Server, um eine hohe Verfügbarkeit zu erhalten. 3. Ha mit Redis Sentinel oder Redis Cluster; 4. Erstellen Sie Schnappschüsse, um Daten zu sichern. 5. Implementieren Sie Best Practices wie Persistenz, Replikation, Schnappschüsse, Überwachung und Sicherheitsmaßnahmen.

Verwenden Sie das Redis-Befehlszeilen-Tool (REDIS-CLI), um Redis in folgenden Schritten zu verwalten und zu betreiben: Stellen Sie die Adresse und den Port an, um die Adresse und den Port zu stellen. Senden Sie Befehle mit dem Befehlsnamen und den Parametern an den Server. Verwenden Sie den Befehl Hilfe, um Hilfeinformationen für einen bestimmten Befehl anzuzeigen. Verwenden Sie den Befehl zum Beenden, um das Befehlszeilenwerkzeug zu beenden.
