Wann und wie wird der Cache der zweiten Ebene im Ruhezustand verwendet?


90

Ich habe Probleme zu verstehen, wann der Ruhezustand den Cache der zweiten Ebene erreicht und wann er den Cache ungültig macht.

Folgendes verstehe ich derzeit:

  • Der Cache der zweiten Ebene speichert Entitäten zwischen Sitzungen. Der Bereich ist die SessionFactory
  • Sie müssen angeben, welche Entitäten zwischengespeichert werden sollen. Standardmäßig wird keine Entität zwischengespeichert
  • Der Abfragecache speichert die Ergebnisse von Abfragen im Cache.

Was ich nicht verstehe ist

  • Wann trifft der Ruhezustand diesen Cache?
  • Angenommen, ich habe den Cache der zweiten Ebene eingerichtet, aber nicht das Abfrage-Caching. Ich möchte meine Kunden zwischenspeichern, es gibt 50000 von ihnen. Wie kann ich die Kunden aus dem Cache abrufen?
  • Ich gehe davon aus, dass ich sie per ID aus dem Cache abrufen kann. Das wäre einfach, aber auch nicht zwischenspeicherwürdig. Aber was ist, wenn ich mit all meinen Kunden rechnen möchte? Angenommen, ich möchte eine Liste der Kunden anzeigen. Wie würde ich dann auf sie zugreifen?
  • Wie würde ich alle meine Kunden erreichen, wenn das Zwischenspeichern von Abfragen deaktiviert ist?
  • Was würde passieren, wenn jemand einen der Kunden aktualisieren würde?
    • Würde dieser Kunde im Cache ungültig werden oder würden alle Kunden ungültig werden?

Oder denke ich, dass Caching völlig falsch ist? Was wäre in diesem Fall angemessener für die Verwendung des Cache der zweiten Ebene? Die Dokumentation zum Ruhezustand ist überhaupt nicht klar, wie der Cache in der Realität funktioniert. Es gibt nur Anweisungen zum Einrichten.

Update: Ich habe verstanden, dass der Cache der zweiten Ebene (ohne Abfrage-Cache) gut zum Laden von Daten anhand von IDs geeignet ist. Zum Beispiel habe ich ein Benutzerobjekt, das ich in jeder Anforderung in einer Webanwendung auf Berechtigungen prüfen möchte. Wäre dies ein guter Fall, um den Datenbankzugriff durch Zwischenspeichern des Benutzers im Cache der zweiten Ebene zu reduzieren? Als würde ich die Benutzer-ID in der Sitzung speichern oder wo und wann immer ich nach Berechtigungen suchen muss, würde ich den Benutzer anhand seiner ID laden und Berechtigungen überprüfen.


Antworten:


100

Lassen Sie uns zunächst über den Cache auf Prozessebene (oder den Cache der zweiten Ebene, wie sie im Ruhezustand genannt werden) sprechen. Damit es funktioniert, sollten Sie

  1. Konfigurieren Sie den Cache-Anbieter
  2. Teilen Sie dem Ruhezustand mit, welche Entitäten zwischengespeichert werden sollen (direkt in der Datei hbm.xml, wenn Sie diese Art der Zuordnung verwenden).

Sie teilen dem Cache-Anbieter mit, wie viele Objekte er speichern soll und wann / warum sie ungültig werden sollen. Angenommen, Sie haben eine Buch- und eine Autorenentität. Jedes Mal, wenn Sie sie aus der Datenbank abrufen, werden nur diejenigen aus der tatsächlichen Datenbank ausgewählt, die sich nicht im Cache befinden. Dies erhöht die Leistung erheblich. Es ist nützlich, wenn:

  • Sie schreiben nur über den Ruhezustand in die Datenbank (da Sie wissen müssen, wann Entitäten im Cache geändert oder ungültig gemacht werden müssen).
  • Sie lesen häufig Objekte
  • Sie haben einen einzelnen Knoten und keine Replikation. Andernfalls müssen Sie den Cache selbst replizieren (verwenden Sie verteilte Caches wie JGroups), was die Komplexität erhöht und nicht so gut skaliert wie Share-Nothing-Apps.

Wann funktioniert der Cache?

  • Wenn Sie session.get()oder session.load()das zuvor ausgewählte Objekt sich im Cache befinden. Cache ist ein Speicher, in dem ID der Schlüssel und die Eigenschaften die Werte sind. Nur wenn die Möglichkeit besteht, nach ID zu suchen, können Sie das Schlagen der Datenbank vermeiden.
  • Wenn Ihre Assoziationen faul geladen sind (oder eifrig mit Auswahlen anstelle von Verknüpfungen geladen sind)

Aber es funktioniert nicht, wenn:

  • Wenn Sie nicht nach ID auswählen. Nochmals - Der Cache der zweiten Ebene speichert eine Zuordnung der IDs von Entitäten zu anderen Eigenschaften (es werden nicht die Objekte, sondern die Daten selbst gespeichert). Wenn Ihre Suche also folgendermaßen aussieht: from Authors where name = :namedann schlagen Sie nicht auf den Cache.
  • Wenn Sie HQL verwenden (auch wenn Sie verwenden where id = ?).
  • Wenn Sie in Ihrem Mapping festlegen fetch="join", dass zum Laden von Zuordnungen Verknüpfungen überall anstelle separater select-Anweisungen verwendet werden. Der Cache auf Prozessebene funktioniert nur bei untergeordneten Objekten, wenn er fetch="select"verwendet wird.
  • Selbst wenn Sie dies fetch="select"in HQL getan haben, verwenden Sie Verknüpfungen, um Zuordnungen auszuwählen. Diese Verknüpfungen werden sofort ausgegeben und überschreiben alles, was Sie in hbm.xml oder Anmerkungen angegeben haben.

Nun zum Abfrage-Cache. Sie sollten beachten, dass es sich nicht um einen separaten Cache handelt, sondern um eine Ergänzung zum Cache auf Prozessebene. Angenommen, Sie haben eine Länderentität. Es ist statisch, sodass Sie wissen, dass jedes Mal dieselbe Ergebnismenge angezeigt wird, wenn Sie sagen from Country. Dies ist ein perfekter Kandidat für den Abfrage-Cache. Er speichert eine Liste von IDs in sich selbst. Wenn Sie das nächste Mal alle Länder auswählen, wird diese Liste an den Cache auf Prozessebene zurückgegeben, und dieser gibt wiederum Objekte für jede ID zurück da diese Objekte bereits im Cache der 2. Ebene gespeichert sind. Der Abfragecache wird jedes Mal ungültig, wenn sich etwas im Zusammenhang mit der Entität ändert. Angenommen, Sie haben konfiguriert from Authors, dass sie in einen Abfrage-Cache gestellt werden sollen. Dies ist nicht effektiv, da der Autor häufig wechselt.


Erfordert die Abfrage "Vom Autor einen Abruf verbinden a.books" den Abfrage-Cache, um Autoren aus dem Cache abzurufen?
Palto

1
Nein, der Abfragecache ist nur für statische Daten vorgesehen und speichert nur IDs. Die Autoren werden aus dem Cache der 2. Ebene entnommen.
Stanislav Bashkyrtsev

@ctapobep: nicht wahr was du sagst! "from Author a fetch join a.books" funktioniert einwandfrei, wenn die Feldbücher der Entität Author mit Anmerkungen versehen sind (fetch EAGER) ... ich denke, es ist zu spät
Bilal BBB

So eine tolle Antwort! Ich werde mich die ganze Zeit daran erinnern! : d
Mohammadreza Khatami

Ruft er nach dem Aktivieren des 'Abfrage-Cache' die Daten aus dem Cache ab, wenn Sie eine andere Eigenschaft als id auswählen?
Arun Raaj

41
  • Der Cache der 2. Ebene ist ein Schlüsselwertspeicher. Es funktioniert nur, wenn Sie Ihre Entitäten anhand der ID erhalten
  • Der Cache der 2. Ebene wird pro Entität ungültig / aktualisiert, wenn eine Entität über den Ruhezustand aktualisiert / gelöscht wird. Es wird nicht ungültig, wenn die Datenbank auf andere Weise aktualisiert wird.
  • Verwenden Sie für Abfragen (z. B. Kundenliste) den Abfrage-Cache.

In der Realität ist es nützlich, einen verteilten Schlüsselwert-Cache zu haben - genau das ist memcached und unterstützt Facebook, Twitter und viele mehr. Wenn Sie jedoch keine Suche nach ID haben, ist dies nicht sehr nützlich.


12

Spät zur Party, wollte aber systematisch diese Frage beantworten, die viele Entwickler stellen.

Ihre Frage hier einzeln zu beantworten, ist meine Antwort.

F. Wann ist der Ruhezustand im Cache?

A. Der Cache der ersten Ebene ist dem Sitzungsobjekt zugeordnet . Der Cache der zweiten Ebene ist dem Session Factory-Objekt zugeordnet . Wenn das Objekt in der ersten nicht gefunden wird, wird die zweite Ebene überprüft.

F. Angenommen, ich habe den Cache der zweiten Ebene eingerichtet, aber nicht das Abfrage-Caching. Ich möchte meine Kunden zwischenspeichern, es gibt 50000 von ihnen. Wie kann ich die Kunden aus dem Cache abrufen?

A. Sie haben diese Antwort in Ihrem Update erhalten. Außerdem speichert der Abfragecache nur die Liste der IDs des Objekts, und diese Objekte mit ihren IDs werden im selben Cache der zweiten Ebene gespeichert . Wenn Sie also den Abfragecache aktivieren, verwenden Sie dieselbe Ressource. Ordentlich richtig?

F. Ich gehe davon aus, dass ich sie per ID aus dem Cache abrufen kann. Das wäre einfach, aber auch nicht zwischenspeicherwürdig. Aber was ist, wenn ich mit all meinen Kunden rechnen möchte? Angenommen, ich möchte eine Liste der Kunden anzeigen. Wie würde ich dann auf sie zugreifen?

A. Oben beantwortet.

Frage: Wie würde ich alle meine Kunden erreichen, wenn das Zwischenspeichern von Abfragen deaktiviert ist?

A. Oben beantwortet.

F. Was würde passieren, wenn jemand einen der Kunden aktualisieren würde? Würde dieser Kunde im Cache ungültig werden oder würden alle Kunden ungültig werden?

A. Der Ruhezustand hat keine Ahnung, aber Sie könnten andere IMDG / verteilte Caches von Drittanbietern verwenden, um sie als Cache der zweiten Ebene im Ruhezustand zu implementieren und sie ungültig zu machen. zB TayzGrid ist ein solches Produkt und es gibt mehr, denke ich.


0

Der Cache der zweiten Ebene im Ruhezustand ist etwas schwierig zu verstehen und zu implementieren. Folgendes können wir anhand Ihrer Fragen sagen:

Wann hat Hibernate diesen Cache erreicht?

Wie Sie vorschlagen, wird der L2-Cache im Ruhezustand (falls aktiviert; standardmäßig nicht aktiviert) erst nach dem L1-Cache abgefragt. Dies ist ein Schlüsselwert-Cache, dessen Daten über mehrere Sitzungen hinweg erhalten bleiben.

Angenommen, ich habe den Cache der zweiten Ebene eingerichtet, aber nicht das Abfrage-Caching. Ich möchte meine Kunden zwischenspeichern, es gibt 50000 von ihnen. Wie kann ich die Kunden aus dem Cache abrufen?

Das Zwischenspeichern von Abfragen ist für diesen Anwendungsfall am besten geeignet, da die Kundendaten statisch sind und aus einer relationalen Datenbank abgerufen werden.

Was würde passieren, wenn jemand einen der Kunden aktualisieren würde? Würde dieser Kunde im Cache ungültig werden oder würden alle Kunden ungültig werden?

Dies hängt von der spezifischen Cache-Strategie für den Ruhezustand ab, die Sie verwenden. Der Ruhezustand hat tatsächlich vier verschiedene Cache-Strategien:

READ_ONLY : Objekte ändern sich nicht einmal im Cache.

NONSTRICT_READ_WRITE : Objekte ändern sich (eventuell), nachdem der entsprechende Datenbankeintrag aktualisiert wurde. Dies garantiert eine eventuelle Konsistenz.

READ_WRITE : Objekte ändern sich (sofort), nachdem der entsprechende Datenbankeintrag aktualisiert wurde. Dies garantiert eine starke Konsistenz durch Verwendung von "weichen" Schlössern.

TRANSAKTIONAL : Objekte ändern sich mithilfe verteilter XA-Transaktionen, um die Datenintegrität sicherzustellen. Dies garantiert entweder den vollständigen Erfolg oder das Zurücksetzen aller Änderungen. In allen vier Fällen würde das Aktualisieren eines einzelnen Datenbankeintrags jedoch nicht die gesamte Liste der Kunden im Cache ungültig machen. Der Ruhezustand ist etwas schlauer :)

Weitere Informationen zur Funktionsweise des L2-Caching im Ruhezustand finden Sie im Artikel „Was ist der L2-Cache im Ruhezustand?“ Oder im ausführlichen Artikel „ Caching im Ruhezustand mit Redis“

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.