Genau genommen ist es unmöglich, die Konsistenz für jede nicht-atomare Operation zu garantieren, es sei denn, blockierende Lese- und Schreibvorgänge werden verwendet, um eine starke Konsistenz zu erreichen, also das Ziel, das wir in der verfolgen Die Cache-Architektur ist letztendliche Konsistenz.
Caching verbessert die Leistung, indem es auf starke Konsistenz verzichtet.
Dies wird durch die CAP-Theorie bestimmt. Das anwendbare Szenario für das Cache-System ist das Szenario ohne starke Konsistenz, das zum AP in CAP gehört.
Die folgenden drei Cache-Lese- und Schreibstrategien haben ihre eigenen Vor- und Nachteile, und es gibt keine beste.
Cache-Aside-Muster, dh Cache-Modus umgehen Es wird vorgeschlagen, das Problem der Dateninkonsistenz zwischen Cache und Datenbank so weit wie möglich zu lösen.
Lesen: Daten aus dem Cache lesen und direkt nach dem Lesen zurückkehren. Wenn es nicht gelesen werden kann, laden Sie es aus der Datenbank, schreiben Sie es in den Cache und geben Sie dann die Antwort zurück.
Schreiben Sie : Aktualisieren Sie beim Aktualisieren zuerst die Datenbank und löschen Sie dann den Cache .
Read-/Write-Through-Muster Auf der Serverseite wird der Cache als Hauptdatenspeicher betrachtet und Die Daten werden daraus gelesen und Daten hineingeschrieben. Die Aufgabe des Cache-Dienstes besteht darin, DB-Daten zu lesen und zu schreiben und so die Belastung der Anwendung zu verringern.
Da das von uns häufig verwendete verteilte Cache-Redis nicht über die Cache-Funktion zum Schreiben von Daten in die Datenbank verfügt, wird es nicht häufig verwendet.
Schreiben : Überprüfen Sie zuerst den Cache. Wenn er nicht im Cache vorhanden ist, aktualisieren Sie die Datenbank direkt. Wenn es im Cache vorhanden ist, wird zuerst der Cache aktualisiert, und dann aktualisiert der Cache-Dienst die Datenbank selbst (Cache und Datenbank gleichzeitig aktualisieren ).
Lesen: Daten aus dem Cache lesen und nach dem Lesen direkt zurückkehren. Wenn es nicht gelesen werden kann, laden Sie es zuerst aus der Datenbank, schreiben Sie es in den Cache und geben Sie dann die Antwort zurück.
Write Behind Pattern ist dem Read/Write Through Pattern sehr ähnlich. Beide sind für den Cache und die Datenbank verantwortlich und schreiben.
Es gibt jedoch große Unterschiede zwischen den beiden: Read/Write Through aktualisiert den Cache und die Datenbank synchron, während Write Behind Caching nur den Cache aktualisiert und die Datenbank nicht direkt aktualisiert besteht darin, zur asynchronen Batch-Methode zu wechseln, um die Datenbank zu aktualisieren.
Offensichtlich bringt diese Methode größere Herausforderungen für die Datenkonsistenz mit sich. Wenn beispielsweise die Cache-Daten möglicherweise nicht asynchron zur Datenbank aktualisiert werden, kann es zu größeren Problemen kommen Katastrophe.
Diese Strategie ist in unserem täglichen Entwicklungsprozess ebenfalls sehr selten, bedeutet jedoch nicht, dass es nur wenige Anwendungsszenarien gibt, z. B. das asynchrone Schreiben von Nachrichten in der Nachrichtenwarteschlange auf die Festplatte und den InnoDB-Pufferpoolmechanismus von MySQL . Hier kommt diese Strategie.
Write Behind Pattern Die Schreibleistung von DB ist sehr hoch, was sich sehr gut für einige Szenarien eignet, in denen sich die Daten häufig ändern und die Anforderungen an die Datenkonsistenz nicht so hoch sind, wie z. B. die Anzahl der Aufrufe und Likes .
Der Bypass-Cache-Modus ist das, was wir im täglichen Leben am häufigsten verwenden. Basierend auf dem oben vorgestellten Bypass-Cache-Modus haben wir möglicherweise die folgenden Fragen.
Zu diesem Zeitpunkt speichert der Cache die Daten von A (alte Daten) und die Datenbank speichert die Daten von B (neue Daten). Die DatenWarum löscht der Schreibvorgang den Cache, anstatt ihn zu aktualisieren? Bei Schreibvorgängen besteht der erste Schritt darin, die Datenbank zu aktualisieren. Thread B initiiert einen weiteren Schreibvorgang und aktualisiert im zweiten Schritt die Datenbank. Aus Netzwerk- und anderen Gründen aktualisiert Thread B zuerst den Cache und Thread A aktualisiert den Cache.
sind inkonsistent und es erscheinen fehlerhafte Daten . La. Wenn den Cache löscht, anstatt ihn zu aktualisieren
, tritt dieses Problem mit schmutzigen Daten nicht auf.Tatsächlich ist es möglich, den Cache zu aktualisieren, wenn Schreibvorgänge erforderlich sind. Wir müssen jedoch eine Sperre/verteilte Sperre hinzufügen, um sicherzustellen, dass beim Aktualisieren des Caches keine Thread-Sicherheitsprobleme auftreten. Warum müssen wir beim Schreiben von Daten zuerst die Datenbank aktualisieren und dann den Cache löschen? Angenommen, Anforderung 1 ist ein Schreibvorgang, wenn Cache A zuerst gelöscht wird, Anforderung 2 ist ein Lesevorgang, Cache A wird zuerst gelesen und festgestellt, dass der Cache gelöscht ist (durch Anforderung 1 gelöscht), und dann wird die Datenbank gelesen, aber Anforderung 1 hatte noch keine Zeit, wenn die Daten rechtzeitig aktualisiert wurden , Anfrage 2 liest die alten Daten und Anfrage 2 legt auch die alten gelesenen Daten in den Cache, was zu Dateninkonsistenzen führt.
Tatsächlich können Sie zuerst den Cache löschen und dann die Datenbank aktualisieren, wenn Sie die
Strategie zum verzögerten doppelten Löschen, da in dieser 1 Sekunde viele Faktoren passieren können und die Unsicherheit zu groß ist.1 Sekunde lang verwenden und den Cache löschen Auch hier können Sie die zwischengespeicherten schmutzigen Daten innerhalb von 1 Sekunde erneut löschen. Es muss nicht unbedingt 1 Sekunde sein, es hängt von Ihrem Unternehmen ab,
Aber dieser Ansatz wird nicht empfohlen
Ist es beim Schreiben von Daten in Ordnung, zuerst die Datenbank zu aktualisieren und dann den Cache zu löschen?
Antwort:
Theoretisch kann es immer noch zu Dateninkonsistenzen kommen, aber die Wahrscheinlichkeit ist sehr gering. Angenommen, es gibt zwei Anfragen, eine fordert A auf, eine Abfrageoperation durchzuführen, und eine fordert B auf, eine Aktualisierungsoperation durchzuführen, dann wird die folgende Situation auftreten
(1) Der Cache ist gerade abgelaufen
(2) Fordern Sie A an, die Datenbank abzufragen und einen alten Wert zu erhalten
(3) Fordern Sie B an, den neuen Wert in die Datenbank zu schreiben
(4) Fordern Sie B an, den Cache zu löschen
(5 ) Fordern Sie A auf, den alten Wert in den Cache zu schreiben. Wenn die obige Situation eintritt, treten tatsächlich fehlerhafte Daten auf.
Allerdings ist die Wahrscheinlichkeit, dass dies geschieht, nicht hoch
Es gibt eine angeborene Bedingung für das Eintreten der oben genannten Situation, das heißt, der Datenbankschreibvorgang in Schritt (3) dauert weniger Zeit als der Datenbanklesevorgang in Schritt (2) Es ist möglich, dass Schritt (4) vor Schritt (5) erfolgt.
Wenn Sie jedoch sorgfältig darüber nachdenken, ist der Lesevorgang der Datenbank viel schneller als der Schreibvorgang (warum trennen wir sonst Lesen und Schreiben? Die Bedeutung der Lese- und Schreibtrennung liegt darin, dass der Lesevorgang schneller ist und verbraucht weniger Ressourcen), sodass die Schritte (3) weniger Zeit in Anspruch nehmen als Schritt (2). Diese Situation tritt selten auf.
Gibt es noch andere Gründe für die Inkonsistenz?
Antwort: Wenn das Löschen des Caches fehlschlägt, führt dies zu Inkonsistenzen.
Wie lässt sich das Problem lösen?
Verwenden Sie Canal, um das Binlog der Datenbank zu abonnieren und die Daten zu erhalten, die betrieben werden müssen. Starten Sie ein anderes Programm, um die Informationen von diesem Abonnementprogramm abzurufen, und löschen Sie den Cache.
Defekt 1: Die ersten angeforderten Daten dürfen sich nicht im Cache befinden
Lösung: Hotspot-Daten können vorab in den Cache gelegt werden.
Fehler 2: Häufige Schreibvorgänge führen dazu, dass die Daten im Cache häufig gelöscht werden, was sich auf die Cache-Trefferquote auswirkt.
Starkes Konsistenzszenario zwischen Datenbank- und Cache-Daten: Beim Aktualisieren der Datenbank wird auch der Cache aktualisiert, wir müssen jedoch eine Sperre/verteilte Sperre hinzufügen, um sicherzustellen, dass beim Aktualisieren des Caches keine Thread-Sicherheitsprobleme auftreten. Szenarien, in denen die Datenbank- und Cache-Daten inkonsistent sind, können vorübergehend zugelassen werden: Beim Aktualisieren der Datenbank wird auch der Cache aktualisiert, dem Cache wird jedoch eine relativ kurze Ablaufzeit hinzugefügt. Dadurch wird sichergestellt, dass die Auswirkungen auch dann auftreten, wenn die Daten inkonsistent sind wird relativ klein sein.
Das obige ist der detaillierte Inhalt vonSo lösen Sie das Dual-Write-Problem zwischen Redis und MySQL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!