Warum ist Redis mit Single-Thread so schnell?
Warum verwendet Redis einen einzelnen Thread?
Der Overhead von Multi-Threading
Wenn es kein gutes Systemdesign gibt, führt die Verwendung von Multi-Threading normalerweise zu den rechts gezeigten Ergebnissen (beachten Sie die Ordinate). Wenn Sie die Anzahl der Threads zum ersten Mal erhöhen, erhöht sich die Systemdurchsatzrate. Wenn Sie die Anzahl der Threads weiter erhöhen, steigt die Systemdurchsatzrate langsam an oder nimmt sogar ab.
Der entscheidende Engpass ist: Es gibt in der Regel gemeinsam genutzte Ressourcen im System, auf die mehrere Threads gleichzeitig zugreifen. Um die Korrektheit der gemeinsam genutzten Ressourcen sicherzustellen, sind zusätzliche Mechanismen erforderlich, um die Thread-Sicherheit zu gewährleisten, wie z B. eine Verriegelung, die mit zusätzlichen Kosten verbunden ist.
Nehmen Sie als Beispiel den am häufigsten verwendeten List
-Typ. Angenommen, Redis verwendet ein Multi-Thread-Design und es gibt zwei Threads A und B, die LPUSHList bzw. /code>- und <code>LPUSH
-Operationen, um bei jeder Ausführung das gleiche Ergebnis zu erzielen, d. h. [B-Thread entnimmt die von A-Thread eingegebenen Daten], diese beiden Prozesse müssen seriell ausgeführt werden. Dies ist das Problem der gleichzeitigen Zugriffskontrolle gemeinsam genutzter Ressourcen, mit dem das Multithread-Programmiermodell konfrontiert ist. List
类型来举例吧,假设Redis采用多线程设计,有两个线程A和B分别对List
做LPUSH
和LPUSH
操作,为了使得每次执行都是相同的结果,即【B线程取出A线程放入的数据】就需要让这两个过程串行执行。这就是多线程编程模式面临的共享资源的并发访问控制问题。
并发访问控制一直是多线程开发中的一个难点问题:如果只是简单地采用一个互斥锁,就会出现即使增加了线程,大部分线程也在等待获取互斥锁,并行变串行,系统吞吐率并没有随着线程的增加而增加。
同时加入并发访问控制后也会降低系统代码的可读性和可维护性,所以Redis干脆直接采用了单线程模式。
Warum ist Redis mit Single-Thread so schnell??
之所以使用单线程是Redis设计者多方面衡量的结果。
Redis的大部分操作在内存上完成
采用了高效的数据结构,例如哈希表和跳表
采用了多路复用机制,使其在网络IO操作中能并发处理大量的客户端请求,实现高吞吐率
既然Redis使用单线程进行IO,如果线程被阻塞了就无法进行多路复用了,所以不难想象,Redis肯定还针对网络和IO操作的潜在阻塞点进行了设计。
网络与IO操作的潜在阻塞点
在网络通信里,服务器为了处理一个Get请求,需要监听客户端请求(bind/listen
),和客户端建立连接(accept
),从socket中读取请求(recv
),解析客户端发送请求(parse
),最后给客户端返回结果(send
)。
最基本的一种单线程实现是依次执行上面的操作。
上面标红的accept和recv操作都是潜在的阻塞点:
当Redis监听到有连接请求,但却一直不能成功建立起连接时,就会阻塞在
accept()
函数这里,其他客户端此时也无法和Redis建立连接当Redis通过
recv()
从一个客户端读取数据时,如果数据一直没有到达,也会一直阻塞
基于多路复用的高性能IO模型
为了解决IO中的阻塞问题,Redis采用了Linux的IO多路复用机制,该机制允许内核中,同时存在多个监听套接字和已连接套接字(select/epoll
)。
内核会一直监听这些套接字上的连接或数据请求。Redis会处理到达的请求,从而实现了一个线程处理多个IO流的效果。
此时,Redis线程就不会阻塞在某一个特定的客户端请求处理上,所以它可以同时和多个客户端连接并处理请求。
回调机制
select/epoll一旦监测到FD上有请求到达时,就会触发相应的事件被放进一个队列里,Redis线程对该事件队列不断进行处理,所以就实现了基于事件的回调。
例如,Redis会对Accept和Read事件注册accept
和get
回调函数。当Linux内核监听到有连接请求或读数据请求时,就会触发Accept事件和Read事件,此时,内核就会回调Redis相应的accept
和get

- 🎜Die meisten Vorgänge von Redis werden im Speicher ausgeführt🎜
- 🎜Unter Verwendung effizienter Datenstrukturen wie Hash-Tabellen und Skip-Tabellen🎜
- 🎜Verwendet einen Multiplex-Mechanismus, sodass eine große Anzahl von Client-Anfragen gleichzeitig in Netzwerk-IO-Vorgängen verarbeitet und ein hoher Durchsatz erzielt werden kann🎜 🎜🎜Da Redis einen einzelnen Thread für IO verwendet, wenn der Thread blockiert ist Multiplexing kann nicht durchgeführt werden, daher ist es nicht schwer vorstellbar, dass Redis auch für potenzielle Blockierungspunkte im Netzwerk- und IO-Betrieb ausgelegt sein muss. 🎜🎜Potenzielle Blockierungspunkte im Netzwerk- und E/A-Betrieb🎜🎜Um bei der Netzwerkkommunikation eine Get-Anfrage zu verarbeiten, muss der Server auf die Client-Anfrage hören (
- 🎜Wenn Redis eine Verbindungsanforderung erkennt, die Verbindung jedoch nicht erfolgreich herstellen kann, wird es im
accept( )
Funktion, andere Clients können zu diesem Zeitpunkt keine Verbindung mit Redis herstellen🎜 - 🎜Wenn Redis
recv()
von einem Client übergibt Wenn das Ende Daten liest, wenn Wenn die Daten nicht angekommen sind, werden sie immer blockiert Listening-Sockets und verbundene Sockets müssen gleichzeitig im Kernel vorhanden sein (select/epoll
). 🎜🎜Der Kernel wartet immer auf Verbindungen oder Datenanfragen auf diesen Sockets. Redis verarbeitet eingehende Anforderungen und erzielt so den Effekt, dass ein Thread mehrere E/A-Streams verarbeitet. 🎜🎜🎜🎜An dieser Stelle Gleichzeitig blockiert der Redis-Thread die Verarbeitung einer bestimmten Client-Anforderung nicht, sodass er gleichzeitig eine Verbindung zu mehreren Clients herstellen und Anforderungen verarbeiten kann. 🎜🎜Rückrufmechanismus🎜🎜Sobald select/epoll erkennt, dass eine Anfrage auf FD eintrifft, löst es das entsprechende Ereignis aus und stellt es in eine Warteschlange, sodass ereignisbasierte Rückrufe implementiert werden. 🎜🎜Zum Beispiel registriert Redis die Rückruffunktionen
accept
undget
für Accept- und Read-Ereignisse. Wenn der Linux-Kernel eine Verbindungsanforderung oder eine Datenleseanforderung überwacht, löst er das Accept-Ereignis und das Read-Ereignis aus. Zu diesem Zeitpunkt ruft der Kernel die entsprechendenaccept
undget auf. Code> der zu verarbeitenden Redis-Funktion. 🎜🎜Leistungsengpässe von Redis🎜🎜Nach der obigen Analyse weist Redis immer noch einige Leistungsengpässe auf, obwohl mehrere Clientanforderungen gleichzeitig über den Multiplexing-Mechanismus überwacht werden können. Dies ist auch eine Situation, die wir in unserer täglichen Programmierung vermeiden müssen . 🎜<h4 id="Zeitaufwändige-Vorgänge">1. Zeitaufwändige Vorgänge</h4> <p>Wenn eine Anfrage in Redis lange dauert, wirkt sich dies auf die Leistung des gesamten Servers aus. Nachfolgende Anfragen müssen auf die Verarbeitung der vorherigen zeitaufwändigen Anfrage warten, bevor sie verarbeitet werden können. </p> <p>Dies muss beim Entwerfen von Geschäftsszenarien vermieden werden. Der <code>lazy-free
-Mechanismus von Redis erfordert auch die zeitaufwändige Freigabe von Speicher in einem asynchronen Thread zur Ausführung.2. Szenario mit hoher Parallelität
Wenn die Parallelität sehr groß ist, gibt es einen Leistungsengpass beim Lesen und Schreiben von Client-E/A-Daten mit einem einzelnen Thread. Obwohl der E/A-Multiplexmechanismus verwendet wird, kann er immer noch nur den Client lesen Daten sequentiell mit einem einzelnen Thread, der nicht die Vorteile mehrerer CPU-Kerne nutzen kann.
Redis in 6.0 kann CPU-Multi-Core und Multi-Threading zum Lesen und Schreiben von Client-Daten verwenden, aber nur das Lesen und Schreiben für den Client erfolgt parallel und die eigentliche Ausführung jedes Befehls erfolgt weiterhin Single-Threaded.
Weitere interessante Fragen zu Redis
Ich möchte diese Gelegenheit nutzen, um einige interessante Fragen zu Redis zu stellen.
Warum Redis verwenden, ist es nicht schlecht, direkt auf den Speicher zuzugreifen?
Tatsächlich ist dieser Artikel nicht klar definiert. Für einige Daten, die sich nicht häufig ändern, kann er nicht direkt im Speicher abgelegt werden. Beim Aktualisieren von Daten kann es zu Konsistenzproblemen kommen, d. h. die Daten werden möglicherweise nur auf einem Server geändert, sodass die Daten nur im lokalen Speicher vorhanden sind. Durch den Zugriff auf den Redis-Server kann das Konsistenzproblem mithilfe von Redis gelöst werden.
Was soll ich tun, wenn zu viele Daten vorhanden sind, die nicht im Speicher gespeichert werden können? Was soll ich beispielsweise tun, wenn ich 100 GB Daten zwischenspeichern möchte?
Hier gibt es auch eine Werbung für das verteilte Open-Source-KV-Cache-System von Taobao. Theoretisch ist das Gesamtdatenvolumen unbegrenzt und es wurde auch auf Verfügbarkeit, Skalierbarkeit und Zuverlässigkeit optimiert . Upgrade, interessierte Freunde können es herausfinden~
bind/listen
) und eine Verbindung mit dieser herstellen den Client (accept
), lesen Sie die Anfrage vom Socket (recv
), analysieren Sie die vom Client gesendete Anfrage (parse
) und schließlich Geben Sie das Ergebnis an den Client zurück (send
). 🎜🎜Die grundlegendste Single-Thread-Implementierung besteht darin, die oben genannten Vorgänge nacheinander auszuführen. 🎜🎜
Das obige ist der detaillierte Inhalt vonWarum ist Redis mit Single-Thread so schnell?. 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

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

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

1. Starten Sie das Menü [Start], geben Sie [cmd] ein, klicken Sie mit der rechten Maustaste auf [Eingabeaufforderung] und wählen Sie Als [Administrator] ausführen. 2. Geben Sie nacheinander die folgenden Befehle ein (kopieren und fügen Sie sie sorgfältig ein): SCconfigwuauservstart=auto, drücken Sie die Eingabetaste. SCconfigbitsstart=auto, drücken Sie die Eingabetaste. SCconfigcryptsvcstart=auto, drücken Sie die Eingabetaste. SCconfigtrustedinstallerstart=auto, drücken Sie die Eingabetaste. SCconfigwuauservtype=share, drücken Sie die Eingabetaste. netstopwuauserv, drücken Sie die Eingabetaste für netstopcryptS

Engpässe bei PHP-Funktionen führen zu geringer Leistung, was durch die folgenden Schritte behoben werden kann: Suchen Sie die Engpassfunktion und verwenden Sie Tools zur Leistungsanalyse. Ergebnisse zwischenspeichern, um Neuberechnungen zu reduzieren. Verarbeiten Sie Aufgaben parallel, um die Ausführungseffizienz zu verbessern. Optimieren Sie die Zeichenfolgenverkettung und verwenden Sie stattdessen integrierte Funktionen. Verwenden Sie integrierte Funktionen anstelle benutzerdefinierter Funktionen.

Die Caching-Strategie in GolangAPI kann die Leistung verbessern und die Serverlast reduzieren. Häufig verwendete Strategien sind: LRU, LFU, FIFO und TTL. Zu den Optimierungstechniken gehören die Auswahl geeigneter Cache-Speicher, hierarchisches Caching, Invalidierungsmanagement sowie Überwachung und Optimierung. Im praktischen Fall wird der LRU-Cache verwendet, um die API zum Abrufen von Benutzerinformationen aus der Datenbank zu optimieren. Andernfalls kann der Cache nach dem Abrufen aus der Datenbank aktualisiert werden.

In der PHP-Entwicklung verbessert der Caching-Mechanismus die Leistung, indem er häufig aufgerufene Daten vorübergehend im Speicher oder auf der Festplatte speichert und so die Anzahl der Datenbankzugriffe reduziert. Zu den Cache-Typen gehören hauptsächlich Speicher-, Datei- und Datenbank-Cache. In PHP können Sie integrierte Funktionen oder Bibliotheken von Drittanbietern verwenden, um Caching zu implementieren, wie zum Beispiel Cache_get() und Memcache. Zu den gängigen praktischen Anwendungen gehören das Zwischenspeichern von Datenbankabfrageergebnissen zur Optimierung der Abfrageleistung und das Zwischenspeichern von Seitenausgaben zur Beschleunigung des Renderings. Der Caching-Mechanismus verbessert effektiv die Reaktionsgeschwindigkeit der Website, verbessert das Benutzererlebnis und reduziert die Serverlast.

Durch die Verwendung des Redis-Cache kann die Leistung des PHP-Array-Pagings erheblich optimiert werden. Dies kann durch die folgenden Schritte erreicht werden: Installieren Sie den Redis-Client. Stellen Sie eine Verbindung zum Redis-Server her. Erstellen Sie Cache-Daten und speichern Sie jede Datenseite in einem Redis-Hash mit dem Schlüssel „page:{page_number}“. Rufen Sie Daten aus dem Cache ab und vermeiden Sie teure Vorgänge auf großen Arrays.

Zuerst müssen Sie die Systemsprache auf die Anzeige in vereinfachtem Chinesisch einstellen und neu starten. Wenn Sie die Anzeigesprache zuvor auf vereinfachtes Chinesisch geändert haben, können Sie diesen Schritt natürlich einfach überspringen. Beginnen Sie als Nächstes mit dem Betrieb der Registrierung regedit.exe, navigieren Sie direkt zu HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsLanguage in der linken Navigationsleiste oder der oberen Adressleiste und ändern Sie dann den InstallLanguage-Schlüsselwert und den Standardschlüsselwert auf 0804 (wenn Sie ihn in Englisch ändern möchten). us, Sie müssen zunächst die Anzeigesprache des Systems auf en-us einstellen, das System neu starten und dann alles auf 0409 ändern) Sie müssen das System an dieser Stelle neu starten.

Ja, Navicat kann eine Verbindung zu Redis herstellen, wodurch Benutzer Schlüssel verwalten, Werte anzeigen, Befehle ausführen, Aktivitäten überwachen und Probleme diagnostizieren können. Um eine Verbindung zu Redis herzustellen, wählen Sie in Navicat den Verbindungstyp „Redis“ und geben Sie die Serverdetails ein.

1. Doppelklicken Sie zunächst auf dem Desktop auf das Symbol [Dieser PC], um es zu öffnen. 2. Doppelklicken Sie dann mit der linken Maustaste, um [Laufwerk C] einzugeben. Systemdateien werden im Allgemeinen automatisch auf Laufwerk C gespeichert. 3. Suchen Sie dann den Ordner [Windows] auf dem Laufwerk C und doppelklicken Sie, um ihn aufzurufen. 4. Nachdem Sie den Ordner [Windows] aufgerufen haben, suchen Sie den Ordner [SoftwareDistribution]. 5. Suchen Sie nach der Eingabe den Ordner [Download], der alle Win11-Download- und Update-Dateien enthält. 6. Wenn wir diese Dateien löschen möchten, löschen Sie sie einfach direkt in diesem Ordner.
