Heim  >  Artikel  >  Datenbank  >  So lösen Sie das Redis-Cache-Problem

So lösen Sie das Redis-Cache-Problem

PHPz
PHPznach vorne
2023-06-03 17:56:411161Durchsuche

LevelDB ist da!

Dies ist eine Open-Source-NOSQL-Speicher-Engine-Bibliothek von Google, die ein unverzichtbares Werkzeug im Bereich der modernen verteilten Speicherung ist. Darauf aufbauend entwickelte Facebook eine weitere NOSQL-Speicher-Engine-Bibliothek, RocksDB, die der fortschrittlichen technischen Architektur von LevelDB folgt und gleichzeitig einige der Mängel von LevelDB behebt. Sie können RocksDB mit einer Wasserstoffbombe vergleichen, die leistungsfähiger ist als LevelDB. Viele moderne Open-Source-Datenbanken verwenden RocksDB als zugrunde liegende Speicher-Engine, und TiDB ist eines der bekanntesten Beispiele.

Aber warum sollte ich über LevelDB statt über RocksDB sprechen? Der Grund dafür ist, dass die technische Architektur von LevelDB einfacher, klarer und verständlicher ist. Wenn wir LevelDB zunächst gründlich verstehen und dann einen Blick auf RocksDB werfen, wird es sehr leicht zu verstehen sein, dass es sich bei RocksDB nur um eine Reihe von Optimierungen handelt, die auf LevelDB basieren. Wenn wir das RocksDB-Problem lösen, begrüßt uns nicht weit voraus das nuklearbetriebene Raumschiff von TiDB.

Was stimmt mit dem Redis-Cache nicht?

Wenn wir Redis als Cache nutzen, gibt es in der Regel noch eine persistente Datenbank, die die kompletten Cold- und Hot-Daten aufzeichnet. Die Datenkonsistenz zwischen Redis und der Persistenzschichtdatenbank wird von der Anwendung selbst gesteuert. Wenn sich keine Daten im Cache befinden, muss die Anwendung die Daten aus der Persistenzschicht laden und in den Cache stellen. Bei Datenaktualisierungen muss der Cache ungültig gemacht werden.

<code class="hljs javascript">function getUser(String userId) User {<br>  User user = redis.get(userId);<br>  if user == null {<br>    user = db.get(userId);<br>    if user != null {<br>      redis.set(userId, user);<br>    }<br>  }<br>  return user;<br>}<br><br>function updateUser(String userId, User user) {<br>  db.update(userId, user);<br>  redis.expire(userId);<br>}<br></code>


Freunde mit Entwicklungserfahrung in diesem Bereich wissen, dass das Schreiben eines solchen Codes ziemlich mühsam ist. Alle Geschäftscodes, die Caching beinhalten, müssen diesen Teil der Logik hinzufügen.

Genau genommen müssen wir auch das Problem der Cache-Konsistenz sorgfältig berücksichtigen. Beispielsweise führt die Datenbank in der updateUser-Methode die Aktualisierung korrekt aus, aber die zwischengespeicherten Redis werden aufgrund von Netzwerk-Jitter und anderen Gründen nicht ungültig gemacht, ebenso wie die Daten Die im Cache gespeicherten Daten sind abgelaufen. Leser können davon ausgehen, dass auch dann andere Probleme auftreten können, wenn die Reihenfolge der Cache-Einrichtung und der Aktualisierung des persistenten Speichers umgekehrt wird.

Situationen mit hoher Parallelität mit mehreren Prozessen können auch zu Cache-Inkonsistenzen führen. Wenn ein Prozess beispielsweise die Methode getUser() für eine bestimmte Benutzer-ID aufruft, muss sie aus der Datenbank geladen werden, weil sie sich nicht im Cache befindet. Die Ergebnisse wurden gerade geladen und wir sind dabei, den Cache einzurichten. Zu diesem Zeitpunkt wird der Speicher-FullGC-Code für eine Weile angehalten, und zu diesem Zeitpunkt ruft ein anderer Prozess die updateUser-Methode auf, um die Datenbank zu aktualisieren und den Cache ungültig zu machen Tatsächlich gibt es keinen Cache in den Cache-Daten. Dann beendet der vorherige Prozess schließlich fullgc und beginnt mit dem Einrichten des Caches. Zu diesem Zeitpunkt werden die abgelaufenen Daten zwischengespeichert.

Wie wird LevelDB gelöst?

LevelDB kombiniert den Redis-Cache und die Persistenzschicht in einem und hilft Ihnen so, den Cache und die Persistenzschicht gleichzeitig zu verwalten. Mit LevelDB kann Ihr Code wie folgt vereinfacht werden:

<code class="hljs javascript">function getUser(String userId) User {<br>  return leveldb.get(userId);<br>}<br><br>function updateUser(String userId, User user) {<br>  leveldb.set(userId, user);<br>}<br></code>


und Sie müssen sich keine Sorgen mehr über Probleme mit der Cache-Konsistenz machen, ob die Datenaktualisierungen von LevelDB erfolgreich sind oder nicht, und es gibt keinen Schrödinger-Zwischenzustand. Benutzer müssen nicht auf die Details der Datenkonsistenz achten, da LevelDB Speichercache und Festplattendateien der Persistenzschicht intern integriert.

Was genau ist LevelDB?

Wir haben bereits erwähnt, dass es sich um eine nicht relationale Speicher-Engine handelt, die sich vom Konzept von Redis unterscheidet. Redis ist eine vollständige Datenbank, während LevelDB nur eine Engine ist. Vergleicht man die Datenbank mit einem High-End-Sportwagen, ist die Speicher-Engine ihr Motor, also ihr Kern und Herz. Mit dieser Engine können wir sie mit einer Reihe von Zubehörteilen und Dekorationen verpacken, um eine Datenbank zu erstellen. Aber unterschätzen Sie nicht Accessoires und Dekorationen. Es ist sehr schwierig, das ultimative Packaging LevelDB in eine einfache und benutzerfreundliche Datenbank zu integrieren, indem man zu viele exquisite Accessoires hinzufügt. LevelDB und RocksDB gibt es schon seit so vielen Jahren, aber nur sehr wenige können darauf basierend eine vollständige Datenbank auf Produktionsebene aufbauen.

LevelDB kann als In-Memory-Schlüsselwertdatenbank betrachtet werden. Es bietet eine grundlegende Get/Set-API, über die wir Daten im Code lesen und schreiben können. Sie können es sich auch als eine erweiterte HashMap mit unbegrenzter Größe vorstellen. Wir können unbegrenzt Schlüssel-/Wertdaten darin unterbringen, solange die Festplatte hineinpasst.

Da es sich nur um eine In-Memory-Datenbank handelt, können die darin gespeicherten Daten nicht zwischen Prozessen oder Maschinen geteilt werden. Wie kann LevelDB im verteilten Bereich seine Talente unter Beweis stellen?

Um dies zu erreichen, muss die Netzwerk-API über die LevelDB-In-Memory-Datenbank gepackt werden. Wenn sich mehrere Prozesse auf verschiedenen Maschinen befinden und auf die Ressource zugreifen möchten, müssen alle einheitlich über die Netzwerk-API-Schnittstelle darauf zugreifen. Dies bildet eine einfache Datenbank. Wenden Sie das Redis-Protokoll an, um die Netzwerkschicht zu kapseln, und Sie können den Redis-Client zum Lesen und Schreiben der Datenbank verwenden.

Wenn wir die hohe Verfügbarkeit der Datenbank berücksichtigen möchten, können wir sie in eine verteilte NOSQL-Datenbank mit einer Master-Slave-Struktur umwandeln, indem wir der oben genannten eigenständigen Datenbank die Master-Slave-Replikationsfunktion hinzufügen. Durch Hinzufügen einer Weiterleitungs-Proxy-Schicht (Lastausgleichsmodul wie LVS, F5 usw.) vor der Master-Slave-Datenbank kann eine Echtzeitumschaltung der Master-Slave-Datenbank erreicht werden.

Wenn die von Ihnen benötigte Datenkapazität so groß ist, dass die Festplatte einer einzelnen Maschine sie nicht aufnehmen kann, ist ein Daten-Sharding-Mechanismus erforderlich, um die gesamten Datenbankdaten auf mehrere Maschinen zu verteilen. Jede Maschine ist nur für das Lesen und Schreiben eines Teils davon verantwortlich die Daten. Es gibt viele Daten-Sharding-Lösungen wie Codis oder einen Client-Weiterleitungsmechanismus wie Redis-Cluster. Sie können Shards auch mit dem verteilten Konsistenzalgorithmus von TiDB verwalten. Am einfachsten und am leichtesten zu verstehen ist das Forward-Proxy-Sharding von Codis.

Wenn die Datenmenge weiter wächst und neue Knoten benötigt werden, müssen die Daten auf den alten Knoten teilweise auf die neuen Knoten migriert werden. Was den Ausgleich und die Migration der Daten verwaltet, ist ein neues erweitertes Zubehörteil – der Datenbalancer.

Das obige ist der detaillierte Inhalt vonSo lösen Sie das Redis-Cache-Problem. 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