Dieser Artikel bringt Ihnen relevantes Wissen über Redis, das hauptsächlich Probleme im Zusammenhang mit Cache-Konsistenz, Cache-Penetration, Cache-Aufschlüsselung, Cache-Lawine und Schreibsynchronisation zwischengespeicherter Daten und DB-Konsistenz behandelt wird für alle hilfreich sein.
Verwandte Empfehlungen: „Analyse von Hotkey-Speicherproblemen in Redis und Diskussion über Lösungen für Cache-Ausnahmen“
(1) Cache-Invalidierungskonsistenzproblem
Allgemeine Cache-Nutzung ist: Lesen Sie die Wenn der Cache nicht vorhanden ist, lesen Sie ihn zuerst aus der Datenbank und schreiben Sie das Ergebnis in den Cache. Wenn die Daten das nächste Mal gelesen werden, können die Daten direkt aus dem Cache abgerufen werden. [Verwandte Empfehlung: Redis-Video-Tutorial]
Bei der Datenänderung werden die zwischengespeicherten Daten direkt ungültig gemacht und dann der DB-Inhalt geändert, um eine erfolgreiche DB-Änderung zu vermeiden. Die zwischengespeicherten Daten werden jedoch aufgrund von Netzwerk- oder anderen Problemen nicht bereinigt, was dazu führt schmutzige Daten. Dies kann jedoch immer noch nicht verhindern, dass schmutzige Daten generiert werden. In einem gleichzeitigen Szenario: Gehen Sie davon aus, dass das Unternehmen eine große Anzahl von Lese- und Änderungsanforderungen für die Daten Key:Hello Value:World hat. Thread A liest „Key:Hello“ von OCS, ruft das Ergebnis „Not Found“ ab, beginnt mit der Datenanforderung von der Datenbank und ruft als Nächstes die Daten „Key:Hello Value:World“ ab. Anschließend bereitet er das Schreiben dieser Daten in OCS vor, jedoch vor dem Schreiben in OCS (Netzwerk). , Das Warten auf die CPU kann dazu führen, dass sich die Verarbeitungsgeschwindigkeit von Thread A verlangsamt.) Ein anderer Thread B fordert eine Änderung der Daten an. Schlüssel:Hallo Wert:OCS und führt zuerst die Invalidierungs-Cache-Aktion aus (da Thread B nicht weiß, ob diese Daten vorhanden sind). , sodass der Invalidierungsvorgang direkt ausgeführt wird. OCS hat die ungültige Anfrage erfolgreich verarbeitet. Kehren Sie zu Thread A zurück, um mit dem Schreiben von OCS fortzufahren und Key:Hello Value:World in den Cache zu schreiben. Thread B hat auch den DB-Dateninhalt erfolgreich in Key:Hello Value:OCS geändert. Um dieses Problem zu lösen, hat OCS das Memcached-Protokoll erweitert (die öffentliche Cloud wird es bald unterstützen) und die Schnittstelle deleteAndIncVersion hinzugefügt. Diese Schnittstelle löscht die Daten nicht wirklich, sondern markiert die Daten, um anzuzeigen, dass sie abgelaufen sind, und erhöht die Datenversionsnummer, wenn die Daten nicht vorhanden sind, wird NULL geschrieben und auch eine zufällige Datenversionsnummer generiert. OCS-Schreiben unterstützt den atomaren Vergleich von Versionsnummern: Unter der Annahme, dass die eingehende Versionsnummer mit der von OCS gespeicherten Datenversionsnummer übereinstimmt oder die Originaldaten nicht vorhanden sind, ist das Schreiben zulässig, andernfalls wird die Änderung abgelehnt.
Zurück zur aktuellen Szene: Thread A liest Key:Hello von OCS, ruft das Ergebnis „Not Found“ ab, beginnt mit der Anforderung von Daten von DB und ruft die Daten Key:Hello Value:World ab. Die Versionsnummerninformationen sind standardmäßig 1. Bevor A in OCS schreibt, initiiert ein anderer B-Thread eine Aktion zum Ändern der Daten. Key:Hello Value:OCS führt zunächst die Lösch-Cache-Aktion erfolgreich aus und generiert eine zufällige Version Zahl von 12345 (Konvention größer als 1000). Kehren Sie zu Thread A zurück und schreiben Sie weiter an OCS und fordern Sie das Schreiben von Key:Hello Value:World an. Zu diesem Zeitpunkt stellt das Cache-System fest, dass die eingehenden Versionsnummerninformationen nicht übereinstimmen (1! = 12345), der Schreibvorgang schlägt fehl Aufgabe von Thread A endet. ;Thread B hat auch den DB-Dateninhalt erfolgreich in Key:Hello Value:OCS geändert.
Zu diesem Zeitpunkt sind die Daten in OCS Key:Hello Value:NULL Version:12345; die Daten in DB sind Key:Hello Value:OCS. Bei nachfolgenden Leseaufgaben wird erneut versucht, die Daten in DB in OCS zu schreiben .
(2) Die Schreibsynchronisierung von zwischengespeicherten Daten und das Konsistenzproblem mit DB
Mit zunehmender Größe der Website und verbesserter Zuverlässigkeit wird es mit der Bereitstellung mehrerer IDCs konfrontiert sein. Zu diesem Zeitpunkt ist die Cache-Konsistenz zu einem wichtigen Thema geworden.
Um eine hohe Effizienz zu gewährleisten, verhindert das Cache-System zunächst einmal Festplatten-E/A, auch wenn BINLOG geschrieben wird. Aus Leistungsgründen kann das Cache-System natürlich nur synchron löschen, also nicht synchron schreiben Die Synchronisierung hat im Allgemeinen Vorrang vor dem Eintreffen der DB-Synchronisation (schließlich ist die Effizienz des Cache-Systems viel höher). Dann gibt es ein Szenario, in dem sich keine Daten im Cache und alte Daten in der DB befinden. Zu diesem Zeitpunkt liegt eine Geschäftsanforderung für Daten vor und der Lesecache wird nicht gefunden. Die aus der Datenbank gelesenen und in den Cache geladenen alten Daten sind immer noch alte Daten. Wenn die DB-Datensynchronisierung eintrifft, wird nur die Datenbank aktualisiert. und die zwischengespeicherten schmutzigen Daten können nicht gelöscht werden.
Wie aus der obigen Situation ersichtlich ist, liegt die Hauptursache der Inkonsistenz darin, dass heterogene Systeme nicht zusammenarbeiten können. Es kann nicht garantiert werden, dass DB-Daten zuerst synchronisiert werden und zwischengespeicherte Daten später synchronisiert werden. Wir müssen also überlegen, wie das Cache-System auf die DB-Synchronisierung wartet, oder können die beiden einen Synchronisierungsmechanismus gemeinsam nutzen? Die Cache-Synchronisierung basiert auch auf DB BINLOG, was eine praktikable Lösung darstellt.
Die Datenbank in IDC1 wird über BINLOG mit der Datenbank in IDC2 synchronisiert. In diesem Fall generiert die IDC2-DB-Datenänderung auch ein eigenes BINLOG. Die zwischengespeicherte Datensynchronisierung kann über IDC2-DB BINLOG durchgeführt werden. Nachdem das Cache-Synchronisationsmodul das BINLOG analysiert hat, wird der entsprechende Cache-Schlüssel ungültig gemacht und die Synchronisation von parallel auf seriell geändert, um die Reihenfolge sicherzustellen.
(3) Cache-Penetration (DB erlitt unnötigen Abfrageverkehr)
Methode 1: Es ist ein Bloom-Filter. Es handelt sich um einen äußerst platzsparenden probabilistischen Algorithmus und eine Datenstruktur, mit der bestimmt wird, ob sich ein Element in einer Menge befindet (ähnlich wie Hashset). Sein Kern ist ein langer binärer Vektor und eine Reihe von Hash-Funktionen. Implementieren Sie den Bloom-Filter mit der Guave von Google. 1) Es kommt zu einer Fehlberechnungsrate. 2) Unter normalen Umständen können Elemente nicht aus dem Bloom-Filter gelöscht werden. 3) Der Prozess der Bestimmung der Array-Länge Hash-Funktionen sind komplex und die Verteilung. Was sind die Verwendungsszenarien des Long-Filters? 1) Spam-Adressfilterung (die Anzahl der Adressen ist riesig) 2) Crawler-URL-Adressdeduplizierung 3) Lösung des Cache-Aufschlüsselungsproblems
Methode 2: Leere Ergebnisse speichern und die Zeit für leere Ergebnisse festlegen
(4) Cache-Lawine ( Das Festlegen des Caches auf die gleiche Ablaufzeit führt zu einer DB-Flut)
Methode 1: Die meisten Systemdesigner erwägen die Verwendung von Sperren oder Warteschlangen, um Single-Thread-(Prozess-)Schreibvorgänge in den Cache sicherzustellen und so zu vermeiden, dass viele gleichzeitige Anforderungen fallen während eines Ausfalls Auf dem zugrunde liegenden Speichersystem
Methode 2: Zufällige Ablaufzeit
(5) Cache-Zusammenbruch (Hotkey, kleine Lawine, verursacht durch eine große Anzahl gleichzeitiger Leseanforderungen)
Wenn der Cache zu einem bestimmten Zeitpunkt abläuft Zu diesem Zeitpunkt gibt es eine große Anzahl gleichzeitiger Anforderungen für diesen Schlüssel. Wenn diese Anforderungen feststellen, dass der Cache abgelaufen ist, laden sie normalerweise Daten aus der Backend-Datenbank und setzen sie in den Cache zurück. Zu diesem Zeitpunkt können große gleichzeitige Anforderungen die Backend-Datenbank sofort überlasten
Methode 1: 1. Verwenden Sie den vom Verteilungscache unterstützten Mutex-Schlüssel (Mutex-Schlüssel), um einen Mutex-Schlüssel festzulegen. Wenn der Vorgang erfolgreich zurückgegeben wird, führen Sie die Ladedatenbank durch Der Vorgang wird ausgeführt und der Cache zurückgesetzt, d. h. es erfolgt nur eine Lade-DB-Thread-Verarbeitung.
Methode 2: Verwenden Sie den Mutex-Schlüssel im Voraus: Legen Sie einen Timeout-Wert (Timeout1) innerhalb des Werts fest. Timeout1 ist kleiner als das tatsächliche Memcache-Timeout (Timeout2). Wenn Timeout1 aus dem Cache gelesen wird, wird festgestellt, dass es abgelaufen ist Wenn es soweit ist, verlängern Sie sofort Timeout1 und setzen Sie es in den Cache zurück. Laden Sie dann die Daten aus der Datenbank und legen Sie sie in den Cache. Dies erhöht das Eindringen des Geschäftscodes und erhöht die Codierungskomplexität. : Aus der Sicht von Redis gibt es tatsächlich keine Ablaufzeit, was sicherstellt, dass es kein Problem mit dem Ablauf des Hotspot-Schlüssels gibt, das heißt, dass er nicht „physisch“ abläuft. Aus funktionaler Sicht, wenn er nicht abläuft Wird es nicht statisch? Wir speichern die Ablaufzeit im Wert, der dem Schlüssel entspricht. Wenn festgestellt wird, dass er bald abläuft, wird der Cache über einen asynchronen Hintergrundthread erstellt, der ein „logischer“ Ablauf ist
(6) Häufige Cache-Füllung und Datenverlust im Cache-System. Das Problem
muss auf der Grundlage eines bestimmten Geschäfts analysiert werden. Normalerweise verwenden wir die LRU-Strategie zur Bewältigung von Überläufen und die RDB- und AOF-Persistenzstrategien von Redis, um die Datensicherheit zu gewährleisten unter bestimmten Umständen
Weitere Kenntnisse zum Thema Programmierung finden Sie unter:Programmiervideo
Das obige ist der detaillierte Inhalt vonLassen Sie uns gemeinsam die Redis-Cache-Konsistenz, Cache-Penetration, Cache-Aufschlüsselung und Cache-Avalanche-Probleme analysieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!