Heim  >  Artikel  >  Datenbank  >  So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

王林
王林nach vorne
2023-06-03 12:28:101320Durchsuche

    Double-Write-Konsistenz zwischen Redis und MySQL bezieht sich auf in dem Szenario, in dem Cache und Datenbank gleichzeitig zum Speichern von Daten verwendet werden (hauptsächlich bei hoher Parallelität), wie die Datenkonsistenz sichergestellt werden kann zwischen den beiden (der Inhalt ist derselbe oder so nah wie möglich) .

    Normaler Geschäftsprozess:

    So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

    Lesen ist kein Problem, das Problem ist der Schreibvorgang (Update). Zu diesem Zeitpunkt können mehrere Probleme auftreten. Wir müssen zuerst die Datenbank aktualisieren und dann Caching-Vorgänge durchführen. Beim Umgang mit dem Cache sollten Sie überlegen, ob Sie den Cache aktualisieren oder den Cache löschen oder zuerst den Cache und dann die Datenbank aktualisieren möchten. Zusammenfassend lässt sich sagen, dass Sie zuerst den Cache und dann die Datenbank betreiben oder zuerst die Datenbank und dann der Cache?

    Machen wir mit diesen Fragen weiter.

    Lassen Sie uns zunächst über den Vorgangscache sprechen, der zwei Typen umfasst: Cache aktualisieren und Cache löschen. Wie wählt man aus?

    Cache aktualisieren? Cache löschen?

    Gehen Sie davon aus, dass die Datenbank zuerst aktualisiert wird (da es problematischer ist, zuerst den Cache und dann die Datenbank zu betreiben, was später besprochen wird). Aktualisieren Sie dann den Cache.

    Wenn zwei Anfragen gleichzeitig dieselben Daten ändern, sind möglicherweise alte Daten im Cache vorhanden, da ihre Reihenfolge möglicherweise umgekehrt ist. Nachfolgende Leseanforderungen lesen alte Daten, und nur wenn der Cache ungültig wird, kann der korrekte Wert aus der Datenbank abgerufen werden.

    • Cache löschen

    Aktualisieren Sie zuerst die Datenbank und löschen Sie dann den Cache.

    Wenn der Cache ausfällt, kann Anforderung B Daten aus der Datenbank abfragen und den alten Wert abrufen. Zu diesem Zeitpunkt wird A aufgefordert, die Datenbank zu aktualisieren, den neuen Wert in die Datenbank zu schreiben und den Cache zu löschen. Anforderung B schreibt den alten Wert in den Cache, was zu schmutzigen Daten führtSo lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

    • Aus dem oben Gesagten ist ersichtlich, dass die Anforderungen für schmutzige Daten höher sind als die Anforderungen für die Aktualisierung des Caches. Die folgenden Bedingungen müssen erfüllt sein:

    Cache-Invalidierung

    So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQLLeseanfrage + Schreibanfrage-Parallelität

    1. Datenbank aktualisieren + Cache löschen Zeit ist kürzer als Datenbank lesen + Schreibcache-Zeit

    2. Die ersten beiden sind Für uns sehr zufriedenstellend. Schauen wir uns den dritten Punkt an: Wird das wirklich passieren?

      Die Datenbank ist beim Aktualisieren im Allgemeinen gesperrt und die Geschwindigkeit von Lesevorgängen ist viel schneller als die von Schreibvorgängen, sodass die Wahrscheinlichkeit, dass der dritte Punkt eintritt, äußerst gering ist (natürlich kann er passieren)
    3. Hinweis: Ich habe tatsächlich Ich verstehe das einfach nicht sehr gut. Es scheint, dass die Wahrscheinlichkeit des Auftretens tatsächlich gering ist, aber wenn es zu Netzwerkverzögerungen und anderen Situationen kommt, wird es dann nicht auch passieren? Ich hoffe, dass jemand mit guten Absichten die Verwirrung beseitigen kann, aber ich verstehe es sowieso nicht. Daher müssen Sie bei der Entscheidung, den Cache zu löschen, auch andere Technologien kombinieren, um Leistung und Konsistenz zu optimieren. Zum Beispiel:

    Verwenden Sie die Nachrichtenwarteschlange, um den Cache asynchron zu löschen oder zu aktualisieren, um ein Blockieren des Hauptthreads oder den Verlust von Nachrichten zu vermeiden.

    Verwenden Sie die verzögerte doppelte Löschung, um die Erfolgsquote beim Löschen zu erhöhen und das inkonsistente Zeitfenster zu verkürzen. Das heißt, der Cache wird sofort nach der Aktualisierung der Datenbank einmal geleert und dann nach einem bestimmten Zeitintervall erneut geleert.

    Vergleich

    • Beim Aktualisieren des Caches wird der Cache jedes Mal aktualisiert, die Daten im Cache werden jedoch möglicherweise nicht

      sofort gelesen

      , was dazu führt, dass viele Daten, auf die selten zugegriffen wird, im Cache gespeichert werden . , eine Verschwendung von Cache-Ressourcen. Und in vielen Fällen stimmt der in den Cache geschriebene Wert nicht eins zu eins mit dem Wert in der Datenbank überein. Es ist sehr wahrscheinlich, dass zuerst die Datenbank abgefragt wird und dann durch eine Reihe von „Berechnungen“ ein Wert ermittelt wird. bevor der Wert in den Cache geschrieben wird.
    • Es ist ersichtlich, dass dieses

      Cache-Aktualisierungsschema

      nicht nur zu einer geringen Cache-Auslastung führt, sondern auch zu einer Verschwendung von Maschinenleistung führt. Daher überlegen wir im Allgemeinen:
    • Löschen Sie den Cache.

    Aktualisieren Sie zuerst den Cache und dann die Datenbank.

    Beim Aktualisieren von Daten: Schreiben Sie zuerst die neuen Daten in den Cache (Redis) und dann die neuen Daten in die Datenbank ( MySQL)

    Aber es gibt ein Problem:

    Das Cache-Update ist erfolgreich, aber das Datenbank-Update schlägt fehl, was zu Dateninkonsistenzen führt

    Beispiel
    : Der Benutzer hat seinen Spitznamen geändert, das System Schreibt zuerst den neuen Spitznamen in den Cache und aktualisiert dann die Datenbank erneut. Während des Aktualisierungsprozesses der Datenbank kam es jedoch zu ungewöhnlichen Situationen wie Netzwerkausfällen oder Datenbankausfällen, was dazu führte, dass der Spitzname in der Datenbank nicht geändert wurde. Auf diese Weise stimmt der Spitzname im Cache nicht mit dem Spitznamen in der Datenbank überein.

    • Das Cache-Update ist erfolgreich, aber das Datenbank-Update verzögert sich, was dazu führt, dass andere Anfragen alte Daten lesen

    Beispiel: Der Benutzer gibt eine Bestellung für ein Produkt auf, in das das System zunächst den Bestellstatus schreibt den Cache und aktualisiert dann die Datenbank. Während des Aktualisierungsprozesses der Datenbank ist jedoch aufgrund großer Parallelität oder aus anderen Gründen die Schreibgeschwindigkeit der Datenbank langsamer als die Schreibgeschwindigkeit des Caches. Auf diese Weise lesen andere Anfragen den Bestellstatus als „bezahlt“ aus dem Cache, lesen jedoch den Bestellstatus als „unbezahlt“ aus der Datenbank.

    • Das Cache-Update ist erfolgreich, aber vor dem Datenbank-Update gibt es andere Anfragen, die den Cache und die Datenbank abfragen und die alten Daten zurück in den Cache schreiben, wodurch die neuen Daten überschrieben werden

    Beispiel: Benutzer A hat seinen Avatar geändert und auf den Server hochgeladen. Das System schreibt zunächst die neue Avatar-Adresse in den Cache und gibt sie zur Anzeige an Benutzer A zurück. Aktualisieren Sie dann die neue Avatar-Adresse in der Datenbank. Während dieses Vorgangs besuchte Benutzer B jedoch die persönliche Homepage von Benutzer A und las die neue Avatar-Adresse aus dem Cache. Die Cache-Ungültigmachung kann auf die Cache-Ablaufrichtlinie oder andere Gründe zurückzuführen sein, z. B. auf Neustartvorgänge, die dazu führen, dass der Cache geleert wird oder abläuft. Zu diesem Zeitpunkt besucht Benutzer B erneut die persönliche Homepage von Benutzer A, liest die alte Avatar-Adresse aus der Datenbank und schreibt sie zurück in den Cache. Dies kann dazu führen, dass die Avatar-Adresse im Cache nicht mit der Adresse in der Datenbank übereinstimmt.

    Oben wurde viel gesagt, aber die Zusammenfassung ist, dass das Cache-Update erfolgreich war, aber die Datenbank nicht aktualisiert wurde (Update fehlgeschlagen), was dazu führte, dass der Cache den neuesten Wert und das Dateninventar den alten speicherte Wert. Wenn der Cache ausfällt, wird der alte Wert in der Datenbank abgerufen.

    Ich war später auch verwirrt, da das Problem durch das Scheitern der Datenbankaktualisierung verursacht wurde. Kann ich das Problem der Dateninkonsistenz einfach dadurch lösen, dass die Datenbankaktualisierung erfolgreich ist, und die Aktualisierung erneut versuchen? Datenbank, bis die Datenbankaktualisierung abgeschlossen ist.

    Später stellte ich fest, dass ich zu naiv war und es viele Probleme gab, wie zum Beispiel:

    • Wenn der Grund für das Scheitern der Datenbankaktualisierung ein Datenbankausfall oder ein Netzwerkfehler ist, kann es sein, dass Sie ständig versuchen, die Datenbank zu aktualisieren Größerer Druck und Verzögerungen können sogar zu Schwierigkeiten bei der Datenbankwiederherstellung führen.

    • Wenn der Grund für das Scheitern der Datenbankaktualisierung ein Datenkonflikt oder ein Fehler in der Geschäftslogik ist, kann Ihr ständiger Versuch, die Datenbank zu aktualisieren, zu Datenverlust oder Datenverwirrung führen und sich sogar auf die Daten anderer Benutzer auswirken.

    • Wenn Sie immer wieder versuchen, die Datenbank zu aktualisieren, müssen Sie überlegen, wie Sie die Idempotenz und Reihenfolge der Wiederholungsversuche sicherstellen und wie Sie mit Ausnahmen umgehen, die während des Wiederholungsvorgangs auftreten.

    Diese Methode ist also keine sehr gute Lösung.

    Aktualisieren Sie zuerst die Datenbank und dann den Cache.

    Bei einem Aktualisierungsvorgang aktualisieren Sie zuerst die Datenbankdaten und dann die entsprechenden Cache-Daten.

    Diese Lösung birgt jedoch auch einige Probleme und Risiken, wie z :

    • Wenn die Datenbank erfolgreich aktualisiert wird, die Cache-Aktualisierung jedoch fehlschlägt, bleiben die alten Daten im Cache erhalten, während die Datenbank bereits neue Daten, also schmutzige Daten, enthält.

    • Wenn zwischen der Aktualisierung der Datenbank und der Aktualisierung des Caches eine weitere Anfrage dieselben Daten abfragt und festgestellt wird, dass der Cache vorhanden ist, werden die alten Daten aus dem Cache gelesen. Dies führt auch zu Inkonsistenzen zwischen Cache und Datenbank.

    Wenn daher der Update-Cache-Vorgang verwendet wird, egal, wer zuerst kommt, wenn in letzterem eine Ausnahme auftritt, hat dies Auswirkungen auf das Geschäft. (Standbild oben)

    So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

    Wie gehe ich also mit Ausnahmen um, um die Datenkonsistenz sicherzustellen?

    Die Ursache dieser Probleme liegt in der Multithread-Parallelität. Der einfachste Weg ist daher das Sperren (verteilte Sperre). . Wenn zwei Threads dieselben Daten ändern möchten, muss jeder Thread eine verteilte Sperre beantragen, bevor Änderungen vorgenommen werden. Nur der Thread, der die Sperre erhalten hat, darf die Datenbank und den Cache aktualisieren Warten Sie auf den nächsten Wiederholungsversuch. Der Grund dafür besteht darin, nur einen Thread auf Betriebsdaten und Cache zu beschränken, um Parallelitätsprobleme zu vermeiden.

    Aber das Abschließen ist zeit- und arbeitsintensiv und daher definitiv nicht zu empfehlen. Darüber hinaus werden die Daten im Cache bei jeder Aktualisierung möglicherweise nicht sofort gelesen. Dies kann dazu führen, dass viele Daten, auf die selten zugegriffen wird, im Cache gespeichert werden, wodurch Cache-Ressourcen verschwendet werden. Und in vielen Fällen stimmt der in den Cache geschriebene Wert nicht eins zu eins mit dem Wert in der Datenbank überein. Es ist sehr wahrscheinlich, dass zuerst die Datenbank abgefragt wird und dann durch eine Reihe von „Berechnungen“ ein Wert ermittelt wird. bevor der Wert in den Cache geschrieben wird.

    Es ist ersichtlich, dass diese Lösung aus Aktualisierung der Datenbank + Aktualisierung des Caches nicht nur eine geringe Cache-Auslastung aufweist, sondern auch eine Verschwendung von Maschinenleistung verursacht.

    Zu diesem Zeitpunkt müssen wir also eine andere Option in Betracht ziehen: Cache löschen

    Zuerst den Cache löschen und dann die Datenbank aktualisieren#🎜 🎜 #

    Wenn es einen Aktualisierungsvorgang gibt, löschen Sie zuerst die entsprechenden Cache-Daten und aktualisieren Sie dann die Datenbankdaten

    Diese Lösung weist jedoch auch einige Probleme auf und Risiken, zum Beispiel:

    • Wenn der Cache nicht aktualisiert werden kann, geht der Cache verloren und die nächste Abfrage muss erneut Daten aus der Datenbank laden. Hinzufügen einer Datenbank Stress und Reaktionszeit.

    • Wenn es zwischen dem Löschen des Caches und dem Aktualisieren der Datenbank weitere Anfragen für dieselben Daten gibt und festgestellt wird, dass der Cache nicht existiert, dann wird der alte vorhanden sein aus den Datenbankdaten gelesen und in den Cache geschrieben werden. Dies führt zu Inkonsistenzen zwischen dem Cache und der Datenbank.

    So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

    Aktualisieren Sie zuerst die Datenbank und löschen Sie dann den Cache.

    Wann Während des Aktualisierungsvorgangs werden zuerst die Datenbankdaten aktualisiert und dann der Cache gelöscht Der Cache schlägt fehl, es kann zu einer Anfrage kommen. B fragt die Daten aus der Datenbank ab und erhält den alten Wert. Zu diesem Zeitpunkt wird A aufgefordert, die Datenbank zu aktualisieren, den neuen Wert in die Datenbank zu schreiben und den Cache zu löschen. Anforderung B schreibt den alten Wert in den Cache, was zu schmutzigen Daten führt die Voraussetzungen für die Aktualisierung des Caches. Darüber hinaus müssen die folgenden Bedingungen erfüllt sein:

    #🎜🎜 #

    Leseanfrage + Schreibanfrage-Parallelität

    Datenbank aktualisieren + Cache löschen # 🎜🎜# dauert länger als #🎜 🎜#Datenbank lesen + Cache schreiben So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQLKurz

      Die ersten beiden sind sehr zufriedenstellend . Wird das wirklich passieren?
    1. Die Datenbank ist beim Aktualisieren im Allgemeinen gesperrt und der Lesevorgang ist viel schneller als der Schreibvorgang, sodass die Wahrscheinlichkeit, dass der dritte Punkt auftritt, äußerst gering istFür das Doppelte -Schreibproblem. Eine geeignetere Lösung besteht darin, den Cache nach der Aktualisierung der Datenbank zu löschen. Natürlich erfordert die spezifische Situation eine spezifische Analyse und kann nicht verallgemeinert werden.

    2. Wir haben die Probleme erklärt, die nach diesen Operationen auftreten werden. Was sollten wir also tun, um diese Probleme zu vermeiden?
    3. Löschen Sie zuerst den Cache, aktualisieren Sie dann die Datenbank und verwenden Sie dann einen asynchronen Thread oder eine Nachrichtenwarteschlange, um den Cache neu zu erstellen.

    4. Aktualisieren Sie zuerst die Datenbank, löschen Sie dann den Cache und legen Sie eine angemessene Ablaufzeit fest, um die Wirksamkeit des Caches sicherzustellen. Verwenden Sie verteilte Sperren oder optimistische Sperren, um den gleichzeitigen Zugriff zu steuern und sicherzustellen, dass jeweils nur eine Anforderung den Cache und die Datenbank bedienen kann

    5. # ?? aber die Kosten für einen erneuten Versuch sind zu hoch, ich habe es oben erwähnt, deshalb werde ich es nicht wiederholen.

    2. Asynchroner Wiederholungsversuch

    Da die Wiederholungsmethode Ressourcen beansprucht, werde ich sie asynchron durchführen. Wenn der Vorgang beim Löschen oder Aktualisieren des Caches fehlschlägt, wird nicht sofort ein Fehler zurückgegeben, sondern der Cache-Wiederholungsvorgang wird über einige Mechanismen (z. B. Nachrichtenwarteschlangen, geplante Aufgaben, Binlog-Abonnements usw.) ausgelöst. Mit dieser Methode können zwar Leistungseinbußen und Blockierungsprobleme beim synchronen Wiederholen des Caches vermieden werden, sie verlängert jedoch die Zeit, in der Cache- und Datenbankdaten inkonsistent sind.

    2.1 Verwenden Sie die Nachrichtenwarteschlange, um einen Wiederholungsversuch zu implementieren gehen nicht verloren, bis sie erfolgreich verbraucht wurden (Sie müssen sich keine Gedanken über einen Neustart des Projekts machen) : Downstream ruft die Nachricht aus der Warteschlange ab und löscht sie nach erfolgreichem Verbrauch. Andernfalls wird die Nachricht weiterhin an den Verbraucher übermittelt (gemäß unseren Wiederholungsanforderungen)

    # 🎜🎜#
      #🎜 🎜#
    • Die Verwendung der Nachrichtenwarteschlange zum asynchronen Wiederholen des Caches bedeutet, dass die Datenbank zuerst aktualisiert wird, wenn sich die Informationen ändern Dann wird der Cache gelöscht. Wenn der Löschvorgang fehlschlägt, wird der zu löschende Schlüssel an die Nachrichtenwarteschlange gesendet. Darüber hinaus ruft ein Verbraucherthread den zu löschenden Schlüssel aus der Nachrichtenwarteschlange ab und löscht oder aktualisiert den Redis-Cache basierend auf dem Schlüssel. Wenn der Vorgang fehlschlägt, wird er erneut an die Nachrichtenwarteschlange gesendet und erneut versucht.
    • Hinweis: Sie können es auch direkt an die Nachrichtenwarteschlange senden, ohne zuerst zu versuchen, es zu löschen, und die Nachrichtenwarteschlange
    • #🎜 warten lassen 🎜#Wenn Sie beispielsweise eine Benutzerinformationstabelle haben, möchten Sie die Benutzerinformationen in Redis speichern. Die folgenden Schritte können ausgeführt werden, wobei als Beispiel die Lösung der Verwendung des asynchronen Wiederholungscachings in der Nachrichtenwarteschlange verwendet wird:

      • Wenn sich Benutzerinformationen ändern, aktualisieren Sie zuerst die Datenbank und geben Sie das erfolgreiche Ergebnis an das Frontend zurück.

      • Versuchen Sie, den Cache zu löschen, wird der Vorgang beendet. Wenn er fehlschlägt, wird eine Nachricht für den Vorgang zum Löschen oder Aktualisieren des Caches generiert (z. B. einschließlich des Schlüssels und des Vorgangstyps). in die Nachrichtenwarteschlange (z. B. mit Kafka oder RabbitMQ).

      • Darüber hinaus gibt es einen Verbraucherthread, der diese Nachrichten abonniert und aus der Nachrichtenwarteschlange abruft und die entsprechenden Informationen in Redis basierend auf dem Nachrichteninhalt löscht oder aktualisiert.

      • Wenn der Cache erfolgreich gelöscht oder aktualisiert wurde, wird die Nachricht aus der Nachrichtenwarteschlange entfernt (verworfen), um wiederholte Vorgänge zu vermeiden.

      • Wenn das Löschen oder Aktualisieren des Caches fehlschlägt, implementieren Sie eine Fehlerstrategie, z. B. das Festlegen einer Verzögerungszeit oder eines Wiederholungslimits, und senden Sie die Nachricht dann zur Wiederholung erneut an die Nachrichtenwarteschlange.

      • Wenn die Wiederholungsversuche nach Überschreiten einer bestimmten Anzahl immer noch fehlschlagen, wird eine Fehlermeldung an die Business-Schicht gesendet und protokolliert.

      2.2 Binlog implementiert asynchrone Löschversuche

      Die Grundidee der Verwendung von Binlog zur Erzielung von Konsistenz besteht darin, Binlog-Protokolle zum Aufzeichnen von Datenbankänderungsvorgängen zu verwenden und dann Daten durch Master-Slave-Replikation oder inkrementelle Sicherung zu synchronisieren oder wiederherzustellen.

      Wenn wir beispielsweise eine Master-Datenbank und eine Slave-Datenbank haben, können wir Binlog für die Master-Datenbank aktivieren und die Slave-Datenbank als Replikationsknoten festlegen. Auf diese Weise wird bei jedem Änderungsvorgang in der Master-Datenbank das entsprechende Binlog-Protokoll an die Slave-Datenbank gesendet, und die Slave-Datenbank führt denselben Vorgang basierend auf dem Binlog-Protokoll aus, um die Datenkonsistenz sicherzustellen.

      Wenn wir Daten vor einem bestimmten Zeitpunkt wiederherstellen müssen, können wir dazu auch Binlog-Protokolle verwenden. Zuerst müssen wir die aktuellste vollständige Sicherungsdatei vor dem entsprechenden Zeitpunkt finden und sie in der Zieldatenbank wiederherstellen. Dann müssen wir alle inkrementellen Sicherungsdateien (d. h. Binlog-Protokolldateien) vor dem entsprechenden Zeitpunkt finden und sie der Reihe nach auf die Zieldatenbank anwenden. Auf diese Weise können wir den Datenstatus vor dem Zielzeitpunkt wiederherstellen.

      So lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL

      • Verwenden Sie Binlog, um den Redis-Cache in Echtzeit zu aktualisieren/löschen. Mit Canal tarnt sich der für die Cache-Aktualisierung verantwortliche Dienst als MySQL-Slave-Knoten, empfängt Binlog von MySQL, analysiert das Binlog, ruft Echtzeit-Datenänderungsinformationen ab und aktualisiert/löscht dann den Redis-Cache basierend auf den Änderungsinformationen

      • MQ+ Canal-Strategie, übermittelt die von Canal Server empfangenen Binlog-Daten zur Entkopplung direkt an MQ und verwendet MQ, um Binlog-Protokolle für die Datensynchronisierung asynchron zu konsumieren;

      MySQLs Binlog-Protokoll zeichnet Datenbankänderungsvorgänge wie Einfügungen auf. aktualisieren, löschen usw. Das Binlog-Protokoll hat zwei Hauptfunktionen: eine ist die Master-Slave-Replikation und die andere ist eine inkrementelle Sicherung.

      Master-Slave-Replikation ist der Prozess der Datensynchronisierung durch Synchronisierung von Daten aus einer Master-Datenbank mit einer oder mehreren Slave-Datenbanken. Die Master-Datenbank sendet ihr eigenes Binlog-Protokoll an die Slave-Datenbank, und die Slave-Datenbank führt denselben Vorgang basierend auf dem Binlog-Protokoll aus, um die Datenkonsistenz sicherzustellen. Durch die Implementierung dieses Ansatzes können die Datenverfügbarkeit und -zuverlässigkeit verbessert sowie Lastausgleich und Fehlerwiederherstellung erreicht werden.

      Inkrementelle Sicherung bezieht sich auf die regelmäßige Sicherung von Datenbankänderungen basierend auf einer vollständigen Sicherung. Unter Vollsicherung versteht man die vollständige Sicherung der gesamten Datenbankdaten in einer Datei. Der Zweck besteht darin, die neuesten Änderungen in der Datenbank mit früheren Sicherungen zusammenzuführen, um den neuesten Stand wiederherzustellen. Auf diese Weise können Sie nicht nur den für die Sicherung benötigten Platz und Zeit sparen, sondern auch die Wiederherstellung von Daten zu jedem beliebigen Zeitpunkt vereinfachen.

      An diesem Punkt können wir den Schluss ziehen, dass zur Gewährleistung der Konsistenz der Datenbank und des Caches empfohlen wird, die Lösung „Zuerst die Datenbank aktualisieren und dann den Cache löschen“ zu übernehmen und mit der „Nachrichtenwarteschlange“ zusammenzuarbeiten. oder „Abonnieren Sie das Änderungsprotokoll“, um dies zu tun.

      3. Verzögertes doppeltes Löschen

      Unser Fokus liegt darauf, zuerst die Datenbank zu aktualisieren und dann den Cache zu löschen. Was ist, wenn ich zuerst den Cache löschen und dann die Datenbank aktualisieren möchte?

      Erinnern Sie sich daran, was ich zuvor über das Löschen des Caches und das anschließende Aktualisieren der Datenbank gesagt habe. Das ist einfach zu handhaben. Das ist das Prinzip der Verzögerung Doppeltes Löschen. Die Grundidee ist:

      1. Zuerst den Cache löschen

      2. und dann die Datenbank aktualisieren

      3. Für einen bestimmten Zeitraum in den Ruhezustand versetzen (abhängig von den Systembedingungen)

      4. Den Cache löschen noch einmal

      Um eine Aktualisierung der Datenbank zu vermeiden, wurde diese Maßnahme ergriffen, nachdem andere Threads abgelaufene zwischengespeicherte Daten gelesen und in den Cache zurückgeschrieben hatten, was zu Dateninkonsistenzen führte.

      Zum Beispiel: Angenommen, es gibt eine Benutzerinformationstabelle, eine davon sind Benutzerpunkte. Jetzt arbeiten zwei Threads A und B gleichzeitig mit Benutzerpunkten:

      • Thread A möchte die Punkte des Benutzers um 100 Punkte erhöhen

      • Thread B möchte die Punkte des Benutzers um 50 Punkte verringern

      Wenn die verzögerte Doppellöschstrategie verwendet wird, kann der Ausführungsprozess der Threads A und B wie folgt aussehen:

      • Thread A löscht zuerst die Benutzerinformationen im Cache.

      • Thread A liest dann die Benutzerinformationen Aus der Datenbank wird festgestellt, dass die Benutzerbewertung 1000 beträgt. Thread A addiert 100 zur Benutzerbewertung, um 1100 zu erhalten, und aktualisiert sie in der Datenbank genug, damit die Datenbank synchronisiert werden kann)

      • Thread A löscht die Benutzerinformationen im Cache erneut

      • Thread B löscht zuerst die Benutzerinformationen im Cache

      • Thread B liest dann die Benutzerinformationen aus der Datenbank und stellt fest, dass die Benutzerpunkte 1100 sind (weil Thread A aktualisiert wurde)

      • Thread B subtrahiert 50 von den Benutzerpunkten auf 1050 und aktualisiert sie in der Datenbank

      • Thread B schläft 5 Sekunden lang (vorausgesetzt, diese Zeit reicht aus). damit die Datenbank synchronisiert werden kann)

      • Thread B löscht den Cache erneut Benutzerinformationen

      • Das Endergebnis ist: Die Benutzerpunkte in der Datenbank sind 1050 und es befinden sich keine Benutzerinformationen im Cache. Wenn die Benutzerinformationen das nächste Mal abgefragt werden, werden sie zuerst aus dem Cache gelesen, anstatt sie aus der Datenbank abzurufen und in den Cache zu schreiben. Dadurch wird die Datenkonsistenz gewährleistet.

      • Das verzögerte doppelte Löschen eignet sich für Szenarien mit hoher Parallelität, insbesondere für Situationen, in denen häufig Datenänderungsvorgänge und nur wenige Abfragevorgänge durchgeführt werden. Dies kann den Druck auf die Datenbank verringern und die Leistung verbessern, während gleichzeitig die letztendliche Konsistenz der Daten sichergestellt wird. Das verzögerte doppelte Löschen eignet sich auch für Szenarien, in denen die Datenbank eine Master-Slave-Synchronisierungsverzögerung aufweist, da dadurch vermieden werden kann, dass die alten zwischengespeicherten Daten gelesen und in den Cache zurückgeschrieben werden, nachdem die Datenbank aktualisiert wurde und bevor die Synchronisierung von der Slave-Datenbank abgeschlossen ist.
      • Hinweis: Diese Ruhezeit = die Zeit, die zum Lesen von Geschäftslogikdaten benötigt wird + ein paar hundert Millisekunden. Um sicherzustellen, dass die Leseanforderung endet, kann die Schreibanforderung zwischengespeicherte fehlerhafte Daten löschen, die möglicherweise durch die Leseanforderung mitgebracht wurden.

    Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem der Doppelschreibkonsistenz zwischen Redis und MySQL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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