Heim  >  Artikel  >  Datenbank  >  Ist Redis Single-Threaded oder Multi-Threaded?

Ist Redis Single-Threaded oder Multi-Threaded?

青灯夜游
青灯夜游Original
2020-12-18 15:08:2621064Durchsuche

Vor Redis 4.0 lief es in einem einzelnen Thread; nach Redis 4.0 begann es, Multithreading zu unterstützen. Die Gründe, warum Single-Threading vor Redis 4.0 verwendet wurde: 1. Der Single-Threaded-Modus ist praktisch für Entwicklung und Debugging. 2. Redis verwendet intern Epoll-basiertes Multiplexing. 3. Der Hauptleistungsengpass von Redis ist die Speicher- oder Netzwerkbandbreite.

Ist Redis Single-Threaded oder Multi-Threaded?

(Lernvideo-Sharing: Redis-Video-Tutorial)

Verschiedene Versionen von Redis sind unterschiedlich. Vor Redis 4.0 wurde Redis in einem einzelnen Thread ausgeführt, aber ein einzelner Thread bedeutet nicht eine geringe Effizienz, wie Nginx und Nodejs sind ebenfalls Single-Threaded-Programme, ihre Effizienz ist jedoch nicht gering.

Der Grund dafür ist, dass Redis auf dem Speicher und der Netzwerkbandbreite basiert, nicht auf der CPU. Bevor die CPU den Engpass erreicht, kann es sein, dass der Maschinenspeicher voll ist oder die Bandbreite den Engpass erreicht. Daher ist die CPU nicht der Hauptgrund, daher wird natürlich Single-Threading verwendet. Darüber hinaus ist die Verwendung von Multi-Threading problematischer.

Aber in Redis 4.0 wurde begonnen, Multithreading wie Hintergrundlöschung und andere Funktionen zu unterstützen.

Einfach ausgedrückt verwendete Redis vor 4.0 den Single-Thread-Modus aus den folgenden drei Gründen:

  • Durch die Verwendung von Redis im Single-Thread-Modus sind Entwicklung und Wartung einfacher, da der Single-Thread-Modus für die Entwicklung und das Debuggen praktisch ist.

  • Selbst bei Verwendung eines Single-Threaded-Modells können mehrere Client-Anfragen gleichzeitig verarbeitet werden, hauptsächlich weil Redis intern Epoll-basiertes Multiplexing verwendet.

  • Für Redis ist der Hauptleistungsengpass der Speicher oder die Netzwerkbandbreite, nicht die CPU.

Aber Redis hat in Version 4.0 und höher das verzögerte Löschen (auch asynchrones Löschen genannt) eingeführt, was bedeutet, dass wir eine asynchrone Methode zum Löschen von Daten in Redis verwenden können, zum Beispiel:

  • Unlink-Schlüssel: Ähnlich dem Del-Schlüssel , löscht den angegebenen Schlüssel. Wenn der Schlüssel nicht vorhanden ist, wird der Schlüssel übersprungen. Aber del führt zu einer Blockierung, und der Befehl zum Aufheben der Verknüpfung wird den Speicher in einem anderen Thread wiederverwenden, d. lösche alle aktuellen Daten in der Datenbank [http://www.redis.cn/commands/flushdb.html];

  • flushall async: lösche alle Daten in der Datenbank [http://www.redis.cn/ Befehle/Flushall.html].

  • Der Vorteil dieser Verarbeitung besteht darin, dass der Hauptthread von Redis nicht hängen bleibt und diese Vorgänge zur Ausführung an den Hintergrundthread übergeben werden.

  • 【Mit der Del-Anweisung können Daten normalerweise schnell gelöscht werden. Wenn der gelöschte Schlüssel jedoch ein sehr großes Objekt ist, z. B. beim Löschen eines Hash-Sets mit Tausenden von Elementen, führt die Del-Anweisung dazu, dass der Redis-Hauptthread einfriert Daher kann die Verwendung von Lazy Deletion das Problem des Redis-Einfrierens effektiv vermeiden. 】

Testpunktanalyse:

Fragen zum Redis-Thread-Modell (Single-Threaded oder Multi-Threaded) sind fast eine der Fragen, die zu Redis gestellt werden müssen, aber nicht viele Leute können sie gut beantworten Sie können nur antworten, dass Redis Single-Threading ist und die vielen Vorteile von Single-Threading erwähnt wurden, aber es gibt nur sehr wenige Leute, die die Funktionen von Multi-Threading in Redis4.0 und Redis6.0, insbesondere in Redis6, genau beantworten können .0. In Bezug auf die relevanten Kenntnisse in Single-Threading und Multi-Threading gibt es auch die folgenden Interviewfragen. 1. Da der Redis-Hauptthread ein Single-Thread ist, warum ist er so schnell?

2. IO-Multiplexing in Redis einführen?

3. Multithreading in Redis6.0 einführen?

1. Warum ist Redis so schnell?

Die Gründe sind wie folgt: a Speicherbasierte Vorgänge: Alle Daten in Redis werden im Speicher gespeichert, sodass sich alle Vorgänge auf Speicherebene befinden, sodass die Leistung relativ hoch ist.

b. Einfache Datenstruktur: Die Datenstruktur von Redis ist relativ einfach und speziell für Redis konzipiert. Die zeitliche Komplexität der Suche und des Betriebs dieser einfachen Datenstrukturen beträgt O(1).

c. Multiplexing und nicht blockierendes IO: Redis verwendet die IO-Multiplexing-Funktion, um Clients mit mehreren Socket-Verbindungen zu überwachen, sodass ein Thread zur Bewältigung mehrerer Situationen verwendet werden kann, wodurch die durch Thread-Umschaltung verursachten Probleme reduziert werden vermeidet E/A-blockierende Vorgänge und verbessert dadurch die Leistung von Redis erheblich.

d. Kontextwechsel vermeiden: Da es sich um ein Single-Thread-Modell handelt, werden unnötiger Kontextwechsel und Multi-Thread-Konkurrenz vermieden. Dies spart Zeit und Leistungsaufwand, der durch Multi-Thread-Wechsel verursacht wird Deadlock-Probleme auftreten.

Offizielle Benchmark-Testergebnisse zeigen, dass Single-Threaded Redis einen Durchsatz von 10 W/S erreichen kann.

2.Was ist IO-Multiplexing?

Die Lese- und Schreibmethoden des Sockets blockieren standardmäßig. Wenn beispielsweise die Lesemethode „read“ aufgerufen wird und der Puffer keine Daten enthält, bleibt der Thread hier hängen, bis sich Daten im Puffer befinden oder die Verbindung wird geschlossen, die Lesemethode kehrt zurück und der Thread kann weiterhin andere Geschäfte abwickeln.

Aber dies verringert offensichtlich die Ausführungseffizienz des Programms, und Redis verwendet nicht blockierende E/A, was bedeutet, dass der E/A-Lese- und Schreibvorgang nicht mehr blockiert und die Lese- und Schreibmethoden sofort abgeschlossen und zurückgegeben werden Verwenden Sie die Strategie, so viel zu lesen, wie es lesen kann, und so viel zu schreiben, wie es schreiben kann, um E/A-Vorgänge auszuführen, was offensichtlich eher unserem Streben nach Leistung entspricht.

Aber bei dieser Art von nicht blockierendem E/A gibt es auch ein Problem: Wenn wir einen Lesevorgang ausführen, lesen wir möglicherweise nur einen Teil der Daten. Das Gleiche gilt für das Schreiben von Daten, wenn der Puffer voll ist und wir Die Daten wurden noch nicht geschrieben, daher wird es problematisch, wann die effektiven Daten geschrieben werden.

Das Multiplexen von E/A löst das oben genannte Problem. Der einfachste Weg, das E/A-Multiplexen zu verwenden, ist die Verwendung der Auswahlfunktion. Diese Funktion ist eine API-Schnittstelle, die vom Betriebssystem für Benutzerprogramme bereitgestellt wird und zur Überwachung mehrerer Lese- und Schreibstatus verwendet wird des Dateideskriptors, sodass die Lese- und Schreibereignisse des Dateideskriptors überwacht werden können. Wenn die entsprechende Zeit überwacht wird, kann der Thread benachrichtigt werden, das entsprechende Geschäft zu verarbeiten, wodurch die normale Ausführung der Redis-Lese- und Schreibfunktion sichergestellt wird.

【Allerdings ist die Select-Funktion grundsätzlich nicht auf das aktuelle Betriebssystem anwendbar und stattdessen wird die Epoll-Funktion (Linux) aufgerufen. macOS verwendet Kqueue (von Unix geerbt), da die Select-Funktion bei vielen davon eine schlechte Leistung aufweist von Dateideskriptoren. Sehr schlecht. 】

3. Multithreading in Redis6.0?

Die Vorteile von Single-Threaded Redis sind sehr groß. Es reduziert nicht nur die Verantwortung für die interne Implementierung von Redis, sondern ermöglicht auch die Ausführung aller Vorgänge ohne Sperren, und es gibt keine Leistungs- und Zeitverzögerungen durch Deadlocks und Thread-Wechsel . Verbrauch; aber auch seine Mängel sind offensichtlich. Der Single-Thread-Mechanismus macht es schwierig, die QPS (Abfragen pro Sekunde) von Redis effektiv zu verbessern (obwohl er schnell genug ist, müssen die Leute immer noch höhere Ziele verfolgen).

Obwohl Redis in Version 4.0 Multithreading eingeführt hat, kann diese Version von Multithreading nur zum asynchronen Löschen großer Datenmengen verwendet werden und ist für Nichtlöschvorgänge nicht von großer Bedeutung.

Wenn wir Redis-Multithreading verwenden, können wir den Druck der synchronen Lese- und Schreib-E/A von Redis teilen, die Multi-Core-CPU-Ressourcen voll ausnutzen und die QPS von Redis effektiv verbessern. Obwohl Redis IO-Multiplexing verwendet und auf nicht blockierendem IO basiert, blockiert das Lesen und Schreiben von IO selbst. Wenn sich beispielsweise Daten im Socket befinden, kopiert Redis zunächst die Daten aus dem Kernelbereich in den Benutzerbereich und führt dann die entsprechenden Vorgänge aus. Dieser Kopiervorgang ist jedoch blockiert, und wenn die Datenmenge größer ist Die zum Kopieren erforderliche Zeit nimmt zu, und diese Vorgänge werden auf der Grundlage eines einzelnen Threads ausgeführt.

Daher wurde Redis6.0 die Multithreading-Funktion hinzugefügt, um die E/A-Lese- und Schreibleistung zu verbessern. Die Hauptidee der Implementierung besteht darin, die E/A-Lese- und Schreibaufgaben des Hauptthreads zur Ausführung auf eine Gruppe unabhängiger Threads aufzuteilen , so dass Das Lesen und Schreiben mehrerer Sockets kann parallelisiert werden, Redis-Befehle werden jedoch weiterhin seriell vom Hauptthread ausgeführt.

Aber Hinweis: Redis 6.0 deaktiviert Multithreading standardmäßig, kann aber aktiviert werden, indem io-threads-do-reads in der Konfigurationsdatei redis.conf auf true gesetzt wird. Aber das reicht nicht aus. Darüber hinaus müssen wir auch die Anzahl der Threads festlegen, um die Multithreading-Funktion korrekt zu aktivieren. Wir müssen auch die Redis-Konfiguration ändern, z. B. die Einstellung von 4 Threads.

【Bezüglich der Einstellung der Anzahl der Threads lautet die offizielle Empfehlung: Wenn es sich um eine 4-Kern-CPU handelt, stellen Sie die Anzahl der Threads auf 2 oder 3 ein. Wenn es sich um eine 8-Kern-CPU handelt, stellen Sie die Anzahl der Threads ein Anzahl der Threads auf 6. Kurz gesagt, die Anzahl der Threads muss kleiner sein als die der Maschine. Die Anzahl der CPU-Kerne und Threads ist nicht unbedingt besser. 】

In Bezug auf die Leistung von Redis erwähnte der Autor von Redis auf der RedisConf-Konferenz 2019, dass die in Redis 6.0 eingeführte Multithread-IO-Funktion die Leistung mindestens verdoppelt hat. Chinesen führten auch Vergleichstests mit der 4-Thread-Version von Redis und der Single-Thread-Version von Redis auf Alibaba Cloud durch. Sie stellten fest, dass die Testergebnisse mit den Aussagen des Redis-Autors übereinstimmten und die Leistung im Grunde verdoppelt werden konnte.

Zusammenfassung:

In diesem Artikel werden die Gründe vorgestellt, warum Redis vor 4.0 im Einzelthread immer noch schnell war: basierend auf Speicheroperationen, einfacher Datenstruktur, IO-Multiplexing und nicht blockierendem IO, wodurch unnötiger Thread-Kontextwechsel vermieden wird. Und in Redis 4.0 wurde begonnen, Multithreading zu unterstützen, was sich hauptsächlich im asynchronen Löschen großer Datenmengen widerspiegelt, z. B. Unlink Key, Flushdb Async, Flushall Async usw. Das Multithreading von Redis 6.0 erhöht die Parallelitätsfähigkeit des IO-Lesens und -Schreibens, um die Leistung von Redis besser zu verbessern.

Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Programmierlehre! !

Das obige ist der detaillierte Inhalt vonIst Redis Single-Threaded oder Multi-Threaded?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn