Heim  >  Artikel  >  Datenbank  >  Redis-Schlüsselpunktanalyse

Redis-Schlüsselpunktanalyse

王林
王林nach vorne
2021-01-26 09:20:192026Durchsuche

Redis-Schlüsselpunktanalyse

1. Einführung

Redis (Remote Dictionary Server), also ein Remote-Wörterbuchdienst, ist eine in ANSI C-Sprache geschriebene Open-Source-Protokolldatenbank, die das Netzwerk unterstützt und darauf basieren kann Speicher oder Persistenz. Und bietet APIs in mehreren Sprachen.

(Lernvideo-Sharing: Redis-Video-Tutorial)

Aufgrund seines schnellen Starts, seiner hohen Ausführungseffizienz, mehrerer Datenstrukturen, der Unterstützung für Persistenz und Clustering sowie anderer Funktionen und Merkmale wird es von vielen Internetunternehmen verwendet. Bei unsachgemäßer Verwendung und Bedienung kann es jedoch schwerwiegende Folgen wie Speicherverschwendung und sogar Systemausfälle haben.

2. Schlüsselpunktanalyse

2.1 Verwenden Sie den richtigen Datentyp

Unter den 5 Datentypen in Redis ist der String-Typ der am häufigsten verwendete und einfachste. Die Fähigkeit, ein Problem zu lösen, bedeutet jedoch nicht, dass Sie den richtigen Datentyp verwenden.

Um beispielsweise Benutzerinformationen (Name, Alter, Stadt) in Redis zu speichern, gibt es unten drei Optionen:

Option 1: String-Typ verwenden, jedes Attribut wird als Schlüssel behandelt

set user:1:name laowang
set user:1:age 40
set user:1:city shanghai

Vorteile: einfach und intuitiv , jedes Jedes Attribut unterstützt Aktualisierungsvorgänge
Nachteile: Verwendung zu vieler Schlüssel, Belegung einer großen Speichermenge und schlechte Aggregation von Benutzerinformationen, wodurch Verwaltung und Wartung problematisch werden

Option 2: Verwenden Sie den Zeichenfolgentyp, um Benutzerinformationen in eine zu serialisieren string Save

// 序列化用户信息
String userInfo = serialize(user)
set user:1 userInfo

Vorteile: Vereinfachte Speicherschritte
Nachteile: Es gibt einen gewissen Overhead bei der Serialisierung und Deserialisierung

Option 3: Hash-Typ verwenden, ein Feld-Wert-Paar für jedes Attribut verwenden, aber nur einen Schlüssel verwenden

hmset user:1 name laowang age 40 city shanghai

Vorteile: Durch die einfache und intuitive Verwendung kann der Speicherplatz reduziert werden

Zusammenfassung: Versuchen Sie, die Schlüssel in Redis zu reduzieren.

2.2 Vorsicht vor großen Schlüsseln

Großer Schlüssel bezieht sich im Allgemeinen auf einen Schlüssel mit einem sehr großen Zeichenfolgentypwert (größer als 10 KB) oder einen Schlüssel mit einer großen Anzahl von Hash-, Listen-, Mengen- oder geordneten Mengenelementen (größer als). 5000).

Großer Schlüssel hat viele negative Auswirkungen auf Redis:

Ungleichmäßiger Speicher: In einer Clusterumgebung wird der große Schlüssel einem bestimmten Knotenrechner zugewiesen, da nicht bekannt ist, welchem ​​Knoten er zugeordnet ist und der Knoten einen belegt große Speichermenge, Dies ist nicht förderlich für die einheitliche Speicherverwaltung in einer Clusterumgebung

Timeout-Blockierung: Da es sich bei Redis um einen Single-Thread-Vorgang handelt, ist die Bedienung großer Schlüssel zeitaufwändig und kann leicht zu Blockierungen führen

Abgelaufene Löschung: Große Schlüssel lassen sich nicht nur langsam lesen und schreiben, sondern auch langsam löschen, und das Löschen abgelaufener großer Schlüssel ist auch zeitaufwändiger. Die Migration ist schwierig: Aufgrund der großen Datenmenge können Sicherungen und Wiederherstellungen problemlos durchgeführt werden Dies kann zu Behinderungen und Betriebsausfällen führen


Da wir nun die Gefahren großer Schlüssel kennen, wie beurteilen und befragen wir große Schlüssel? Tatsächlich stellt redis-cli den Parameter --bigkeys bereit. Geben Sie redis-cli --bigkeys ein, um den großen Schlüssel abzufragen.

Nachdem wir den großen Schlüssel gefunden haben, teilen wir ihn normalerweise zur Aufbewahrung in mehrere kleine Schlüssel auf. Dieser Ansatz scheint der Zusammenfassung in 2.1 zu widersprechen, aber jede Lösung hat Vor- und Nachteile, und die Abwägung der Vor- und Nachteile hängt von der tatsächlichen Situation ab.

Zusammenfassung: Versuchen Sie, große Schlüssel in Redis zu reduzieren.

Ergänzung: Wenn Sie den von einem bestimmten Schlüssel belegten Speicherplatz überprüfen möchten, können Sie den Befehl zur Speichernutzung verwenden. Hinweis: Dieser Befehl ist nur in Redis 4.0+ verfügbar. Wenn Sie ihn verwenden möchten, müssen Sie Redis auf 4.0+ aktualisieren.

2.3 Speicherverbrauch

Auch wenn wir den richtigen Datentyp zum Speichern von Daten verwenden und den großen Schlüssel in kleine Schlüssel aufteilen, treten immer noch Probleme mit dem Speicherverbrauch auf. Wie kommt es also zum Speicherverbrauch von Redis? Im Allgemeinen verursacht durch die folgenden 3 Situationen:

Das Geschäft entwickelt sich weiter und die gespeicherten Daten nehmen weiter zu (unvermeidlich)

Ungültige/abgelaufene Daten werden nicht rechtzeitig verarbeitet (können optimiert werden)

Kalte Daten werden nicht herabgestuft (kann optimiert werden)


Bevor wir Fall 2 optimieren, müssen wir zunächst wissen, warum das Problem besteht, abgelaufene Daten nicht rechtzeitig zu verarbeiten. Dies hängt mit den drei von Redis bereitgestellten Strategien zum Löschen abgelaufener Daten zusammen:

Geplantes Löschen: für jeden Schlüssel Mit einer festgelegten Ablaufzeit wird ein Timer erstellt und sofort gelöscht, sobald die Ablaufzeit erreicht ist.

Verzögertes Löschen: Beim Zugriff auf einen Schlüssel wird beurteilt, ob der Schlüssel abgelaufen ist. Wenn er abgelaufen ist, wird er gelöscht

Periodisches Löschen: Scannen Sie das Redis-Wörterbuch in regelmäßigen Abständen nach abgelaufenen Schlüsseln und löschen Sie einige abgelaufene Schlüssel.

Da für das geplante Löschen die Erstellung eines Timers erforderlich ist, wird viel Speicher beansprucht, und das genaue Löschen einer großen Anzahl von Schlüsseln auch verbrauchen viele CPU-Ressourcen, daher verwendet Redis sowohl die Strategie des verzögerten als auch des geplanten Löschens. Wenn der Client den abgelaufenen Schlüssel nicht anfordert oder der reguläre Löschthread den Schlüssel nicht scannt und löscht, belegt der Schlüssel weiterhin Speicher, was zu einer Speicherverschwendung führt.

Nachdem wir die Ursache des Speicherverbrauchs kennen, können wir schnell eine Optimierungslösung finden: manuelles Löschen.

Nach der Verwendung des Caches müssen wir die Methode/den Befehl del manuell aufrufen, um ihn zu löschen, auch wenn der Cache eine Ablaufzeit hat. Wenn es nicht sofort gelöscht werden kann, können wir auch einen Timer im Code starten, um diese abgelaufenen Schlüssel regelmäßig zu löschen. Im Vergleich zu den beiden Löschstrategien von Redis erfolgt die manuelle Datenlöschung viel schneller.

Das Problem in Fall 3 ist nicht groß. Zur Optimierung können wir die Eliminierungsstrategie von Redis anpassen.

2.4 Ausführung mehrerer Befehle

Redis ist ein synchroner Anfragedienst, der auf einer Anfrage und einer Antwort basiert. Das heißt, wenn mehrere Clients Befehle an den Redis-Server senden, kann der Redis-Server nur den Befehl eines der Clients empfangen und verarbeiten. Die anderen Clients können nur darauf warten, dass der Redis-Server den aktuellen Befehl verarbeitet und antwortet, bevor er fortfährt und andere Befehlsanfragen verarbeiten.

Redis verarbeitet Befehle in drei Prozessen: Befehle empfangen, Befehle verarbeiten und Ergebnisse zurückgeben. Da sich alle verarbeiteten Daten im Speicher befinden, liegt die Verarbeitungszeit normalerweise im Nanosekundenbereich, was sehr schnell ist (mit Ausnahme großer Schlüssel). Daher treten die meisten zeitaufwändigen Situationen bei der Annahme von Befehlen und der Rückgabe von Ergebnissen auf. Wenn der Client mehrere Befehle an den Redis-Server sendet und die Verarbeitung eines Befehls lange dauert, können andere Befehle nur warten, was sich auf die Gesamtleistung auswirkt.

Um diese Art von Problem zu lösen, stellt Redis eine Pipeline bereit. Der Client kann mehrere Befehle in die Pipeline einfügen und diese dann zur Verarbeitung auf einmal an den Redis-Server senden die Ergebnisse in einem Rutsch an den Kunden weiter. Diese Verarbeitung reduziert die Anzahl der Interaktionen zwischen dem Client und dem Redis-Server, wodurch die Roundtrip-Zeit verkürzt und die Leistung verbessert wird.

Ergänzung:

Vergleich zwischen

Redis-Pipeline und nativen Batch-Befehlen:

Native Batch-Befehle sind atomar, Pipeline ist nicht atomar.

Native Batch-Befehle können jeweils nur einen Befehl ausführen, während die Pipeline die Ausführung mehrerer Befehle unterstützt

Native Batch Der Befehl wird auf der Serverseite implementiert, und die Pipeline muss auf der Serverseite und auf dem Client implementiert werden.

Hinweise zur Verwendung der Redis-Pipeline:

Die Anzahl der über die Pipeline geladenen Befehle kann nicht sein zu viele

Die Befehle in der Pipeline werden in der gepufferten Reihenfolge ausgeführt, es kann jedoch sein, dass von anderen Clients gesendete Befehle eingestreut werden, das heißt, das Timing ist nicht garantiert

pipeline Wenn während der Ausführung einer Anweisung eine Ausnahme auftritt, Nachfolgende Anweisungen werden weiterhin ausgeführt, das heißt, die Atomizität ist nicht garantiert Die Abfrageregel besteht darin, zuerst den Cache zu überprüfen, dann die Datenbank abzufragen, die gefundenen Daten in den Cache zu legen und sie schließlich an den Client zurückzugeben. Wenn die angeforderten Daten nicht vorhanden sind, wird letztendlich jede Anforderung an die Datenbank gesendet, was zu einer Cache-Penetration führt.

Cache-Penetration stellt ein großes Sicherheitsrisiko dar. Wenn jemand ein Tool verwendet, um eine große Anzahl von Anfragen für nicht vorhandene Daten zu senden, fließt eine große Anzahl von Anfragen in die Datenbank, was zu einem erhöhten Druck auf die Datenbank führt, was zu einer Beschädigung der Datenbank führen kann Ausfallzeiten und dann Es beeinträchtigt den normalen Betrieb der gesamten Anwendung und führt zu einer Systemlähmung.

Um diese Art von Problemen zu lösen, liegt der Fokus auf der Reduzierung des Zugriffs auf die Datenbank. In der Regel gibt es folgende Lösungen:

Redis-SchlüsselpunktanalyseCache-Vorwärmung: Nachdem das System freigegeben und online ist, werden relevante Daten vorab direkt in das Cache-System geladen

Legen Sie den Standardwert fest: Wenn die Anfrage schließlich in der Datenbank landet und die Datenbank die Daten nicht finden kann, legen Sie einen Standardwert für den Cache-Schlüssel fest und legen Sie ihn im Cache ab. Hinweis: Da dieser Standardwert bedeutungslos ist, müssen wir dies tun Legen Sie die Ablaufzeit fest, um die Speichernutzung zu reduzieren

Bloom-Filter: Hashen Sie alle möglichen Daten in eine ausreichend große Bitmap. Daten, die nicht vorhanden sind, werden definitiv von der Bitmap abgefangen

2.6 Cache-Lawine: Einfach ausgedrückt Bezieht sich auf eine große Anzahl von Zugriffen auf zwischengespeicherte Daten, die jedoch nicht abgefragt werden und dann die Datenbank anfordern. Dies führt zu einem erhöhten Druck auf die Datenbank, einer verringerten Leistung und überwältigenden Ausfallzeiten, wodurch der normale Betrieb des gesamten Systems beeinträchtigt und sogar verursacht wird Systemlähmung.


Ein komplettes System besteht beispielsweise aus drei Subsystemen: System A, System B und System C. Ihre Datenanforderungskette ist System A -> System B -> Wenn sich keine Daten im Cache befinden und die Datenbank ausgefallen ist, kann System C die Daten nicht abfragen und antworten und kann sich nur in der Wartephase für erneute Versuche befinden, was Auswirkungen auf System B und System A hat. Eine Anomalie in einem Knoten verursacht eine Reihe von Problemen, genau wie ein Windstoß, der durch einen schneebedeckten Berg weht und eine Lawine auslöst.

Bei diesem Anblick fragen sich einige Leser vielleicht: Was ist der Unterschied zwischen Cache-Penetration und Cache-Lawine?

Die Cache-Penetration konzentriert sich auf die Tatsache, dass sich die angeforderten Daten nicht im Cache befinden. Das Anfordern der Datenbank ist also so, als würde man die Datenbank direkt über den Cache anfordern.

Cache Avalanche konzentriert sich auf große Anfragen. Da die Daten im Cache nicht abgefragt werden können, führt der Zugriff auf die Datenbank zu einem erhöhten Druck auf die Datenbank und zu einer Reihe von Ausnahmen.

Um das Cache-Lawinenproblem zu lösen, müssen wir zunächst die Ursache des Problems kennen:

Redis selbst hat ein Problem

Der Hotspot-Datensatz schlägt fehl



Aus Grund 1 können wir Master-Slave, Clustering, und versuchen Sie, alle Anfragen im Cache zu behalten. Suchen Sie nach Daten im Cache und reduzieren Sie den Zugriff auf die Datenbank.

Für Grund 2: Staffeln Sie beim Festlegen der Ablaufzeit für den Cache die Ablaufzeit (z. B. durch Hinzufügen oder Subtrahieren eines zufälligen Werts). Basiszeit), um einen Ausfall des zentralen Caches zu vermeiden. Gleichzeitig können wir auch einen lokalen Cache (z. B. ehcache) einrichten, um den Schnittstellenfluss einzuschränken oder den Dienst herabzustufen, wodurch auch der Zugriffsdruck auf die Datenbank verringert werden kann.

3. Referenzmaterialien

Pipeline-Operationen in Redis

Redis-Anwendung – Bloom-Filter

Verwandte Empfehlungen: Redis-Datenbank-Tutorial

Das obige ist der detaillierte Inhalt vonRedis-Schlüsselpunktanalyse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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