Heim  >  Artikel  >  Datenbank  >  So verteilen Sie Redis

So verteilen Sie Redis

步履不停
步履不停Original
2019-06-24 10:30:441770Durchsuche

So verteilen Sie Redis

1 Warum Redis verwenden

Bei der Verwendung von Redis in einem Projekt gibt es zwei Hauptüberlegungen: Leistung und Parallelität. Wenn es sich nur um andere Funktionen wie verteilte Sperren handelt, gibt es stattdessen andere Middlewares wie Zookpeer, und die Verwendung von Redis ist nicht erforderlich.

Leistung:

Wie in der Abbildung unten gezeigt, ist es besonders geeignet, wenn wir auf SQL stoßen, dessen Ausführung besonders lange dauert und die Ergebnisse nicht ausreichen nicht häufig ändern. Legen Sie die laufenden Ergebnisse in den Cache . Auf diese Weise werden nachfolgende Anfragen aus dem Cache gelesen, sodass schnell auf Anfragen reagiert werden kann.

Besonders im Flash-Sale-System klickt fast jeder gleichzeitig und gibt Bestellungen auf. . . Es wird derselbe Vorgang ausgeführt: Abfragen der Datenbank nach Daten.

So verteilen Sie Redis

Abhängig vom Interaktionseffekt gibt es keinen festen Standard für die Reaktionszeit. In einer idealen Welt müssen unsere Seitensprünge sofort aufgelöst werden, und In-Page-Vorgänge müssen sofort aufgelöst werden.

Parallelität:

Wie in der folgenden Abbildung gezeigt, greifen bei großer Parallelität alle Anforderungen direkt auf die Datenbank zu und es tritt eine Verbindungsausnahme in der Datenbank auf . Zu diesem Zeitpunkt müssen Sie Redis verwenden, um einen Puffervorgang durchzuführen, damit die Anforderung zuerst auf Redis zugreifen kann, anstatt direkt auf die Datenbank zuzugreifen.

So verteilen Sie Redis

Häufig gestellte Fragen zur Verwendung von Redis

  • Cache- und Datenbank-Double-Write-Konsistenzprobleme
  • Cache Avalanche-Problem
  • Cache-Aufschlüsselungsproblem
  • Cache-Parallelitätskonkurrenzproblem

2. Warum ist Single-Threaded Redis so schnell

Diese Frage ist eine Untersuchung des internen Mechanismus von Redis. Viele Menschen wissen nicht, dass Redis über ein Single-Thread-Arbeitsmodell verfügt.

Die Hauptgründe sind die folgenden drei Punkte:

  • Reiner Speicherbetrieb
  • Einzelthread-Betrieb, Vermeidung häufiger Kontextwechsel
  • Übernimmt einen nicht blockierenden I/O-Multiplexing-Mechanismus

Lassen Sie uns über den I/O-Multiplexing-Mechanismus im Detail sprechen: Xiao Ming eröffnete ein Fastfood in Stadt A. DianDian ist für den Fast-Food-Service in der Stadt verantwortlich. Aufgrund finanzieller Engpässe stellte Xiao Ming eine Gruppe von Zustellern ein. Dann stellte Xiao Qu fest, dass die Mittel nicht ausreichten und er nur ein Auto für die Expresszustellung kaufen konnte.

Geschäftsmethode 1

Jedes Mal, wenn ein Kunde eine Bestellung aufgibt, sorgt Xiao Ming dafür, dass ein Zusteller ein Auge darauf behält und dann jemanden fährt, der sie ausliefert. Langsam entdeckte Xiaoqu die folgenden Probleme bei dieser Geschäftsmethode:

Die ganze Zeit wurde damit verbracht, Autos zu besorgen, und die meisten Zusteller waren untätig und konnten die Ware nicht bekommen kann zur Zustellung verwendet werden.

  • Als die Anzahl der Bestellungen zunahm, gab es auch immer mehr Zusteller. Xiao Ming stellte fest, dass der Expressladen immer voller wurde und es keine Möglichkeit gab, neue Zusteller einzustellen.
  • Die Koordination zwischen den Zustellern braucht Zeit.
  • Aufgrund der oben genannten Mängel lernte Xiao Ming aus der Erfahrung und schlug die zweite Geschäftsmethode vor.
Geschäftsmodus 2

Xiao Ming stellt nur einen Zusteller ein. Wenn ein Kunde eine Bestellung aufgibt, markiert Xiao Ming den Lieferort und platziert ihn an einem Ort. Lassen Sie schließlich den Zusteller das Auto fahren, um die Artikel einzeln auszuliefern, und kommen Sie nach der Lieferung zurück, um den nächsten abzuholen. Vergleicht man die beiden oben genannten Geschäftsmethoden, ist es offensichtlich, dass die zweite effizienter ist.

In der obigen Metapher:

  • Jeder Zusteller→Jeder Thread
  • Jede Bestellung→Jeder Socket (E/A-Stream)
  • Der Lieferort der Bestellung→ Unterschiedlicher Status des Sockets
  • Kundenanfrage zur Essenslieferung→Anfrage des Kunden
  • Mingqus Geschäftsmethode→Der vom Server ausgeführte Code
  • Die Anzahl der Kerne einer Auto→CPU

Wir haben also die folgende Schlussfolgerung:

  • Die erste Geschäftsmethode ist das traditionelle Parallelitätsmodell, jeder Jeder E/A-Stream (Reihenfolge) wird von einem neuen Thread (Delivery Worker) verwaltet.
  • Die zweite Verwaltungsmethode ist das I/O-Multiplexing. Es gibt nur einen einzigen Thread (einen Zusteller), der mehrere I/O-Streams verwaltet, indem er den Status jedes I/O-Streams (den Zustellungsort jedes Zustellers) verfolgt.

Das Folgende ist eine Analogie zum echten Redis-Thread-Modell, wie in der Abbildung gezeigt:

So verteilen Sie Redis

Der Redis-Client weist unterschiedliche Eigenschaften auf, wenn Betriebs-Socket vom Ereignistyp. Auf der Serverseite gibt es einen I/O-Multiplexer, der es in eine Warteschlange stellt. Anschließend entnimmt der Dateiereignis-Dispatcher die Datei der Reihe nach aus der Warteschlange und leitet sie an verschiedene Ereignisprozessoren weiter.

Drei Redis-Datentypen und Nutzungsszenarien

Ein qualifizierter Programmierer wird diese fünf Typen verwenden.

String

Der gebräuchlichste Set/Get-Vorgang. Wert kann ein String oder eine Zahl sein. Im Allgemeinen erfolgt eine Zwischenspeicherung komplexer Zählfunktionen .

Hash

Hier speichert Value ein strukturiertes Objekt, und es ist bequemer, ein bestimmtes Feld darin zu bedienen. Bei der einmaligen Anmeldung habe ich diese Datenstruktur zum Speichern von Benutzerinformationen verwendet, dabei CookieId als Schlüssel verwendet und 30 Minuten als Cache-Ablaufzeit festgelegt, was einen sitzungsähnlichen Effekt sehr gut simulieren kann.

Liste

Mithilfe der Listendatenstruktur können Sie einfache Nachrichtenwarteschlangenfunktionen ausführen. Darüber hinaus können Sie den Befehl lrange verwenden, um eine Redis-basierte Paging-Funktion zu implementieren , die eine hervorragende Leistung und ein gutes Benutzererlebnis bietet.

Set

Weil Set eine Sammlung eindeutiger Werte ist. Daher kann die globale Deduplizierungsfunktion implementiert werden. Unsere Systeme werden im Allgemeinen in Clustern bereitgestellt, und die Verwendung des mit der JVM gelieferten Sets ist problematisch. Darüber hinaus können Sie mithilfe von Schnitt-, Vereinigungs-, Differenz- und anderen Operationen allgemeine Präferenzen, alle Präferenzen, Ihre eigenen einzigartigen Präferenzen und andere Funktionen berechnen.

Sortiertes Set

Sortiertes Set verfügt über einen zusätzlichen Gewichtungsparameter Score, und die Elemente im Set können nach Score angeordnet werden. Sie können die Ranking-Anwendung verwenden, um TOP N-Operationen zu erhalten. Sorted Set kann verwendet werden, um verzögerte Aufgaben zu erledigen.

Vier Redis-Ablaufstrategien und Speicherbeseitigungsmechanismen

Ob Redis zu Hause verwendet wird, lässt sich daraus erkennen. Beispielsweise kann Ihr Redis nur 5G-Daten speichern, aber wenn Sie 10G schreiben, werden 5G-Daten gelöscht. Wie haben Sie es gelöscht? Haben Sie über dieses Problem nachgedacht?

Richtige Antwort: Redis verwendet eine Strategie für regelmäßiges Löschen und verzögertes Löschen.

Warum nicht die geplante Löschstrategie verwenden?

Geplantes Löschen, verwenden Sie einen Timer, um den Schlüssel zu überwachen und ihn automatisch zu löschen, wenn er abläuft . Obwohl der Speicher rechtzeitig freigegeben wird, verbraucht er viele CPU-Ressourcen. Bei großen gleichzeitigen Anfragen muss die CPU Zeit mit der Verarbeitung von Anfragen verbringen, anstatt Schlüssel zu löschen, daher wird diese Strategie nicht übernommen.

So funktioniert regelmäßiges Löschen + verzögertes Löschen

Regelmäßiges Löschen, Redis prüft standardmäßig alle 100 ms und löscht abgelaufene Schlüssel. Es ist zu beachten, dass Redis nicht alle 100 ms alle Schlüssel überprüft, sondern diese zufällig zur Überprüfung auswählt. Wenn Sie nur eine reguläre Löschstrategie anwenden, werden viele Schlüssel mit der Zeit nicht gelöscht. Daher ist das verzögerte Löschen praktisch.

Gibt es kein anderes Problem, wenn Sie das reguläre Löschen + das verzögerte Löschen übernehmen?

Nein, wenn das regelmäßige Löschen den Schlüssel nicht löscht. Und Sie haben den Schlüssel nicht rechtzeitig angefordert, was bedeutet, dass die verzögerte Löschung nicht wirksam wurde. Auf diese Weise wird die Erinnerung an Redis immer höher. Dann sollte der Speicherbeseitigungsmechanismus übernommen werden.

Es gibt eine Konfigurationszeile in redis.conf:

# maxmemory-policy volatile-lru

Diese Konfiguration ist mit der Speichereliminierungsstrategie ausgestattet:

  • noeviction: Wenn der Speicher nicht ausreicht, um die neu geschriebenen Daten aufzunehmen, meldet der neue Schreibvorgang einen Fehler.
  • allkeys-lru: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, entfernen Sie im Schlüsselbereich den zuletzt verwendeten Schlüssel. (Empfohlen, wird derzeit im Projekt verwendet) (Der zuletzt verwendete Algorithmus)
  • allkeys-random: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, wird ein Schlüssel zufällig aus dem Schlüsselraum entfernt. (Niemand sollte es verwenden. Wenn Sie es nicht löschen, verwenden Sie zumindest den Schlüssel und löschen Sie ihn nach dem Zufallsprinzip)
  • volatile-lru: Wenn der Speicher nicht ausreicht, um die neu geschriebenen Daten aufzunehmen, im Schlüsselraum mit festgelegter Ablaufzeit. Entfernen Sie den zuletzt verwendeten Schlüssel. Diese Situation kommt im Allgemeinen vor, wenn Redis sowohl als Cache als auch als persistenter Speicher verwendet wird. (Nicht empfohlen)
  • volatile-random: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, entfernen Sie zufällig einen Schlüssel aus dem Schlüsselraum mit einer festgelegten Ablaufzeit. (Immer noch nicht empfohlen)
  • volatile-ttl: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, wird im Schlüsselraum mit festgelegter Ablaufzeit zuerst der Schlüssel mit einer früheren Ablaufzeit entfernt. (Nicht empfohlen)

Fünf Redis- und Datenbank-Double-Write-Konsistenzprobleme

Konsistenzprobleme können weiter unterteilt werden in eventuelle Konsistenz und starke Konsistenz . Wenn Datenbank und Cache doppelt geschrieben werden, kommt es zwangsläufig zu Inkonsistenzen. Die Voraussetzung ist, dass die Daten nicht zwischengespeichert werden können, wenn strenge Konsistenzanforderungen bestehen. Alles, was wir tun, kann nur letztendliche Konsistenz garantieren.

Darüber hinaus kann die von uns gefundene Lösung grundsätzlich nur die Wahrscheinlichkeit von Inkonsistenzen verringern. Daher können Daten mit hohen Konsistenzanforderungen nicht zwischengespeichert werden. Nehmen Sie zunächst eine korrekte Aktualisierungsstrategie an, aktualisieren Sie zuerst die Datenbank und löschen Sie dann den Cache . Zweitens: Da möglicherweise ein Fehler beim Löschen des Caches auftritt, stellen Sie einfach eine Kompensationsmaßnahme bereit, z. B. die Verwendung einer Nachrichtenwarteschlange.

6 Umgang mit Cache-Penetrations- und Cache-Avalanche-Problemen

Diese beiden Probleme sind für kleine und mittlere traditionelle Softwareunternehmen im Allgemeinen schwer zu bewältigen. Wenn Sie ein großes gleichzeitiges Projekt mit einem Datenverkehr von Millionen haben, müssen diese beiden Aspekte gründlich berücksichtigt werden. Cache-Penetration bedeutet, dass Hacker absichtlich Daten anfordern, die nicht im Cache vorhanden sind, wodurch alle Anforderungen an die Datenbank gesendet werden und die Datenbankverbindung abnormal wird.

Cache-Penetrationslösung:

  • Verwenden Sie Mutex-Sperre, holen Sie sich zuerst die Sperre und dann Fordern Sie dann die Datenbank an. Wenn die Sperre nicht erhalten wird, schläft es eine Weile und versucht es erneut.
  • Mit der asynchronen Aktualisierungsstrategie wird direkt zurückgegeben, unabhängig davon, ob der Schlüssel einen Wert hat. Im Wert Wert wird eine Cache-Ablaufzeit verwaltet. Wenn der Cache abläuft, wird asynchron ein Thread gestartet, um die Datenbank zu lesen und den Cache zu aktualisieren. Der Cache-Vorwärmvorgang (Laden des Caches vor dem Starten des Projekts) ist erforderlich.
  • Stellen Sie einen Abfangmechanismus bereit, der schnell feststellen kann, ob die Anfrage gültig ist, indem Sie beispielsweise Bloom-Filter verwenden, um intern eine Reihe legaler und gültiger Schlüssel zu verwalten. Stellen Sie schnell fest, ob der in der Anfrage enthaltene Schlüssel legal und gültig ist. Wenn es illegal ist, kehren Sie direkt zurück.

Cache-Lawine, das heißt, der Cache fällt gleichzeitig in einem großen Bereich aus. Zu diesem Zeitpunkt kommt eine weitere Welle von Anfragen und infolgedessen die Anfragen werden alle an die Datenbank gesendet, was zu einer abnormalen Datenbankverbindung führt.

Cache-Lawinenlösung:

  • Fügen Sie einen zufälligen Wert zur Cache-Ablaufzeit hinzu, um kollektive Fehler zu vermeiden.
  • verwendet Mutex-Sperre, aber der Durchsatz dieser Lösung sinkt erheblich.
  • Doppelter Cache. Wir haben zwei Caches, Cache A und Cache B. Die Ablaufzeit von Cache A beträgt 20 Minuten, für Cache B gibt es keine Ablaufzeit. Führen Sie den Cache-Aufwärmvorgang selbst durch.
  • Teilen Sie dann die folgenden Punkte auf: Lesen Sie die Datenbank aus Cache A und kehren Sie direkt zurück, wenn A keine Daten enthält, lesen Sie Daten direkt aus B, kehren Sie direkt zurück und starten Sie asynchron einen Aktualisierungsthread Der Update-Thread aktualisiert gleichzeitig Cache A und Cache B.

8 So lösen Sie das gleichzeitig konkurrierende Schlüsselproblem von Redis

Dieses Problem ist ungefähr so: Mehrere Subsysteme legen gleichzeitig einen Schlüssel fest. Worauf sollten wir zu diesem Zeitpunkt achten? Jeder empfiehlt grundsätzlich die Verwendung des Redis-Transaktionsmechanismus.

Es wird jedoch nicht empfohlen, den Redis-Transaktionsmechanismus zu verwenden. Da es sich bei unserer Produktionsumgebung grundsätzlich um eine Redis-Clusterumgebung handelt, werden Daten-Sharding-Vorgänge durchgeführt. Wenn eine Transaktion mehrere Schlüsseloperationen umfasst, werden diese mehreren Schlüssel nicht unbedingt auf demselben Redis-Server gespeichert. Daher ist der Transaktionsmechanismus von Redis sehr nutzlos.

Wenn Sie mit diesem Schlüssel arbeiten, ist keine Bestellung erforderlich

In diesem Fall bereiten Sie einen vor Verteilung Typ Sperre , jeder greift nach dem Schloss und führt beim Ergreifen des Schlosses einfach die Set-Operation aus, was relativ einfach ist.

Wenn Sie mit diesem Schlüssel arbeiten, erfordert die Bestellung

Angenommen, es gibt einen Schlüssel1, muss System A dies tun Setzen Sie Schlüssel1 auf WertA, System B muss Schlüssel1 auf WertB setzen und System C muss Schlüssel1 auf WertC setzen.

Erwarten Sie, dass sich der Wert von Schlüssel1 in der Reihenfolge WertA > WertC ändert. Wenn wir zu diesem Zeitpunkt Daten in die Datenbank schreiben, müssen wir einen Zeitstempel speichern.

Angenommen, der Zeitstempel lautet wie folgt :

System A-Taste 1 {WertA 3:00}

System B-Taste 1 { valueB 3:05}

System C-Schlüssel 1 {valueC 3:10}

Unter der Annahme, dass System B zuerst das Schloss greift, setzen Sie key1 auf { valueB 3 :05}. Als nächstes greift System A nach der Sperre und stellt fest, dass der Zeitstempel seines eigenen Werts A früher ist als der Zeitstempel im Cache, sodass es den Set-Vorgang nicht ausführt und so weiter. Andere Methoden wie die Verwendung von Warteschlangen und die Umwandlung der Set-Methode in seriellen Zugriff können ebenfalls verwendet werden.

Weitere technische Artikel zum Thema Redis finden Sie in der Spalte Redis-Tutorial, um mehr darüber zu erfahren!

Das obige ist der detaillierte Inhalt vonSo verteilen Sie Redis. 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