Was soll ich tun, wenn der Double-Write-Cache von Redis und MySQL inkonsistent ist? In diesem Artikel erfahren Sie, wie Sie das Problem der Inkonsistenz beim doppelten Schreiben im Cache lösen können.
Redis und MySQL Double-Write-Cache sind inkonsistent:
Aber in Bezug auf die Aktualisierung des Caches gibt es derzeit keinen umfassenden Blog, der diese Lösungen analysiert. Also schrieb der Blogger diesen Artikel zitternd und riskierte, von allen kritisiert zu werden. 更新完数据库,是更新缓存呢,还是删除缓存。
又或者是先删除缓存,再更新数据库,其实大家存在很大的争议。
Ablaufzeit für zwischengespeicherte Daten festlegen
Lassen Sie mich zunächst erklären, dass das Festlegen der Ablaufzeit für den Cache eine Lösung ist, um letztendlich Konsistenz sicherzustellen. Bei dieser Lösung können wir die Ablaufzeit für die im Cache gespeicherten Daten festlegen. Alle Schreibvorgänge unterliegen der Datenbank und wir müssen nur für Cache-Vorgänge unser Bestes geben. Das heißt, wenn das Schreiben in die Datenbank erfolgreich ist und die Cache-Aktualisierung fehlschlägt, lesen nachfolgende Leseanforderungen natürlich neue Werte aus der Datenbank und füllen den Cache auf, solange die Ablaufzeit erreicht ist. Daher basieren die im Folgenden besprochenen Ideen nicht auf der Lösung, eine Ablaufzeit für den Cache festzulegen. Hier besprechen wir zunächst dreiUpdate-Strategien:
Aktualisieren Sie zuerst die Datenbank und dann den Cache.Dieser Plan wird im Allgemeinen von allen abgelehnt. Warum? Es gibt die folgenden zwei Punkte:
(2) Thread B hat die Datenbank aktualisiert
(3) Thread B hat den Cache aktualisiert
(4) Thread A hat den Cache aktualisiert
Löschen Sie zuerst den Cache und aktualisieren Sie dann die DatenbankDer Grund, warum diese Lösung zu Inkonsistenzen führt, ist. Gleichzeitig fordert einer von A eine Aktualisierungsoperation und der andere von B eine Abfrageoperation an. Dann tritt die folgende Situation ein: (1) Fordern Sie A auf, einen Schreibvorgang durchzuführen und den Cache zu löschen.
(2) Fordern Sie B auf, eine Abfrage durchzuführen und festzustellen, dass der Cache nicht vorhanden ist.
(3) Fordern Sie B auf, die Datenbank abzufragen Holen Sie sich den alten Wert
(4) Fordern Sie B an, den alten Wert abzurufen. Der Wert wird in den Cache geschrieben.
(5) Fordern Sie A an, den neuen Wert in die Datenbank zu schreiben. Die obige Situation führt zu Inkonsistenzen. Wenn Sie außerdem keine Ablaufzeitstrategie für den Cache festlegen, handelt es sich bei den Daten immer um fehlerhafte Daten.
Also, wie kann man es lösen? Übernehmen Sie die Strategie des verzögerten doppelten Löschens
Cache-verzögertes doppeltes Löschen
public class CacheServiceImpl implements ICacheService { @Resource private RedisOperator redisOperator; @Autowired private IShopService shopService; //1. 采用延时双删,解决数据库和缓存的一致性 @Override public void updateHotCount(String id) { try { //删除缓存 redisOperator.del("redis_key_" + id); //更新数据库 shopService.updataHotShop(); Thread.sleep(1000);//休眠1秒 //延时删除 redisOperator.del("redis_key_" + id); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public Integer getHotCount(String id) { return null; }}
Löschen Sie zuerst den Cache
)OK, in diesem Fall ist der Grund für die Dateninkonsistenz wie folgt. Es gibt immer noch zwei Anfragen, eine fordert A an um den Aktualisierungsvorgang durchzuführen, und der andere fordert B auf, den Aktualisierungsvorgang auszuführen. (1) Fordern Sie A auf, einen Schreibvorgang durchzuführen, den Cache zu löschen, fordern Sie A auf, Daten in die Hauptbibliothek zu schreiben, und haben Sie noch nicht mit der Synchronisierung der Slave-Bibliothek begonnen.
(2) (innerhalb von 1 s) fordern Sie B auf, die abzufragen Cache, aber kein Cache gefunden, Anforderung B zum Gehen Bei der Abfrage aus der Datenbank ist die Master-Slave-Synchronisation noch nicht abgeschlossen. Der alte Wert wird gefunden und der alte Wert wird in den Cache geschrieben. (3) Die Master-Datenbank schließt die Master-Slave-Synchronisation ab und die Slave-Datenbank ändert sich auf den neuen WertDer obige Prozess ist das Problem der Dateninkonsistenz, und es wird auch eine Strategie zur Verzögerung der doppelten Löschung verwendet. Die Ruhezeit wird jedoch so geändert, dass sie auf der Master-Slave-Synchronisationsverzögerungszeit plus ein paar hundert ms basiert
Was soll ich tun, wenn diese Synchronisationseliminierungsstrategie übernommen wird, wenn der Durchsatz reduziert wird?ok, dann führen Sie den zweiten Löschvorgang asynchron durch. Starten Sie selbst einen Thread und löschen Sie ihn asynchron. Auf diese Weise muss die schriftliche Anfrage nicht eine Zeit lang ruhen, bevor sie zurückgesendet wird. Dadurch wird der Durchsatz erhöht.
Zweite Löschung, was soll ich tun, wenn die Löschung fehlschlägt?
Das ist eine sehr gute Frage, denn wenn der Löschvorgang zum zweiten Mal fehlschlägt, kommt es zu folgender Situation. Es gibt noch zwei Anfragen, eine fordert A auf, eine Aktualisierungsoperation durchzuführen, und die andere fordert B auf, eine Abfrageoperation durchzuführen. Der Einfachheit halber wird davon ausgegangen, dass es sich um eine einzelne Datenbank handelt:
(1) Fordern Sie A auf, eine Schreiboperation durchzuführen und den Cache löschen
(2) Fordern Sie B auf, den Cache abzufragen und zu entdecken. Der Cache existiert nicht
(3) Fordern Sie B auf, die Datenbank abzufragen, um den alten Wert zu erhalten
(4) Fordern Sie B auf, den alten Wert in den Cache zu schreiben
( 5) Anforderung A, den neuen Wert in die Datenbank zu schreiben
(6) Anforderung A versucht, Anforderung B zu löschen. Das Schreiben in den zwischengespeicherten Wert ist fehlgeschlagen.
ok, das heißt. Wenn das Löschen des Caches zum zweiten Mal fehlschlägt, tritt die Inkonsistenz zwischen Cache und Datenbank erneut auf.
Wie kann man es lösen?
Für die spezifische Lösung schauen wir uns die Analyse des Bloggers zur Aktualisierungsstrategie an, bei der zuerst die Datenbank aktualisiert und dann der Cache gelöscht wird.
Ob es sich um eine verzögerte doppelte Löschung oder einen Cache-Aside-Mechanismus handelt, der zuerst die Datenbank betreibt und dann den Cache löscht, kann es zu Dateninkonsistenzproblemen kommen, die dadurch verursacht werden, dass der Cache im nicht gelöscht wird zweiter Schritt. Sie können diese Lösung zur Optimierung verwenden: Wenn der Löschvorgang fehlschlägt, löschen Sie ihn noch einige Male, um sicherzustellen, dass der Cache-Löschvorgang erfolgreich ist. ~ So können Sie den Lösch-Cache-Wiederholungsmechanismus
Diese Lösung hat jedoch den Nachteil, dass sie viele Eingriffe in den Branchencode verursacht. Wir haben also die zweite Option: Starten Sie ein Abonnementprogramm, um das Binlog der Datenbank zu abonnieren und die Daten zu erhalten, die bearbeitet werden müssen. Starten Sie in der Anwendung ein neues Programm, um die Informationen aus diesem Abonnementprogramm abzurufen und den Cache zu löschen.
Der Vorgang ist wie in der folgenden Abbildung dargestellt:
(1) Datenbankdaten aktualisieren
(2) Die Datenbank schreibt die Vorgangsinformationen in das Binlog-Protokoll
( 3) Abonnentenextraktion Herausnehmen der erforderlichen Daten und des Schlüssels
(4) Starten Sie einen neuen nicht geschäftlichen Code, um die Informationen zu erhalten
(5) Versuchen Sie, den Cache-Vorgang zu löschen und stellen Sie fest, dass der Löschvorgang fehlgeschlagen ist
(6) Senden Sie die Informationen zur Nachrichtenwarteschlange
(7) Empfangen Sie die Nachricht erneut. Erhalten Sie die Daten in der Warteschlange und wiederholen Sie den Vorgang.
Bemerkungen: Das obige Binlog-Abonnementprogramm verfügt über eine vorgefertigte Middleware namens Canal in MySQL, die die Funktion des Abonnierens von Binlog-Protokollen vervollständigen kann. Was Oracle betrifft, weiß der Blogger derzeit nicht, ob es bereits fertige Middleware gibt, die genutzt werden kann. Darüber hinaus verwendet der Blogger für den Wiederholungsmechanismus eine Nachrichtenwarteschlange. Wenn die Konsistenzanforderungen nicht sehr hoch sind, starten Sie einfach einen neuen Thread im Programm und versuchen Sie es von Zeit zu Zeit erneut. Sie können dies flexibel verwenden, aber ich gebe nur eine Idee.
Dieser Artikel ist eigentlich eine Zusammenfassung der vorhandenen Konsistenzlösungen im Internet. In Bezug auf die Aktualisierungsstrategie, bei der zuerst der Cache gelöscht und dann die Datenbank aktualisiert wird, ist auch die Aufrechterhaltung einer Speicherwarteschlange geplant. Der Blogger hat sich das angesehen und festgestellt, dass die Implementierung äußerst kompliziert und unnötig ist und daher nicht angegeben werden muss im Artikel. Abschließend hoffe ich, dass Sie alle etwas gewonnen haben.
【Verwandte Empfehlung: MySQL-Video-Tutorial】
Das obige ist der detaillierte Inhalt vonWas soll ich tun, wenn die Double-Write-Caches von Redis und MySQL inkonsistent sind? Lösungsaustausch. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!