Frage Wann und wie verwende ich den Second-Level-Cache im Hibernate-Modus?


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

Das verstehe ich derzeit:

  • Second-Level-Cache speichert Entitäten zwischen Sitzungen, Bereich ist die SessionFactory
  • Sie müssen angeben, welche Entitäten zwischengespeichert werden, keine Entität wird standardmäßig zwischengespeichert
  • Der Abfragecache speichert Ergebnisse von Abfragen im Cache.

Was ich nicht verstehe ist

  • Wann schlägt der Winterschlaf diesen Cache?
  • Nehmen wir an, ich habe den Cache der zweiten Ebene, aber nicht das Zwischenspeichern der Abfrage eingerichtet. Ich möchte meine Kunden cachen, es gibt 50000 von ihnen. Wie kann ich die Kunden aus dem Cache abrufen?
  • Ich nehme an, ich kann sie per ID aus dem Cache bekommen. Das wäre zwar einfach, aber auch nicht cachingwürdig. Aber was, wenn ich mit all meinen Kunden kalkulieren möchte. Nehmen wir an, ich möchte eine Liste der Kunden zeigen, wie würde ich dann darauf zugreifen?
  • Wie würde ich alle meine Kunden erhalten, wenn das Ablegen von Abfragen deaktiviert ist?
  • Was würde passieren, wenn jemand einen der Kunden aktualisiert?
    • Wird dieser Kunde im Cache ungültig oder werden alle Kunden für ungültig erklärt?

Oder denke ich Caching total falsch? Was wäre in diesem Fall geeignetere Verwendungen des Second-Level-Caches? Die Winterschlaf-Dokumentation ist überhaupt nicht klar, wie der Cache in der Realität funktioniert. Es gibt nur Anweisungen, wie man es einrichten kann.

Aktualisieren: Also habe ich verstanden, dass Second-Level-Cache (ohne Abfrage-Cache) gut für das Laden von Daten nach IDs wäre. Zum Beispiel habe ich Benutzerobjekt, das ich auf Berechtigungen in jeder Anfrage in einer Webanwendung überprüfen möchte. Wäre es sinnvoll, den Datenbankzugriff zu reduzieren, indem der Benutzer im Second-Level-Cache zwischengespeichert wird? So wie ich die Benutzer-ID in der Sitzung speichern würde oder wo auch immer und wann ich nach Berechtigungen suchen müsste, würde ich den Benutzer anhand seiner ID- und Prüfberechtigungen laden.


75
2017-08-14 18:34


Ursprung


Antworten:


Lassen Sie uns zunächst über den Cache auf Prozessebene (oder den Cache der zweiten Ebene, wie er in Hibernate genannt wird) sprechen. Damit es funktioniert, sollten Sie

  1. Cacheprovider konfigurieren
  2. Sagen Sie Hibernate, welche Entitäten zwischengespeichert werden sollen (rechts in der Datei hbm.xml, wenn Sie diese Art der Zuordnung verwenden).

Sie teilen dem Cache-Provider mit, wie viele Objekte er speichern soll und wann / warum er für ungültig erklärt werden soll. Nehmen wir an, Sie haben eine Buch- und eine Autoren-Entität. Jedes Mal, wenn Sie sie aus der Datenbank abrufen, werden nur diejenigen aus der Datenbank ausgewählt, die nicht im Cache gespeichert sind. Dies erhöht die Leistung erheblich. Es ist nützlich, wenn:

  • Sie schreiben nur über Hibernate in die Datenbank (weil sie wissen muss, wann Entitäten im Cache geändert oder ungültig gemacht werden sollen)
  • Du liest oft Objekte
  • Sie haben einen einzelnen Knoten, und Sie haben keine Replikation. Andernfalls müssen Sie den Cache selbst replizieren (verwenden Sie verteilte Caches wie JGroups), was zu mehr Komplexität führt und nicht so gut skaliert wie Share-Nothing-Apps.

Wann funktioniert Cache?

  • Wenn du session.get() oder session.load() das Objekt, das zuvor ausgewählt wurde und sich im Cache befindet. Cache ist ein Speicher, bei dem ID der Schlüssel und die Eigenschaften die Werte sind. Also nur wenn es eine Möglichkeit gibt, nach ID zu suchen, könnten Sie das Schlagen der DB eliminieren.
  • Wenn Ihre Zuordnungen lazy-geladen sind (oder mit selects statt mit Joins geladen werden)

Aber es funktioniert nicht, wenn:

  • Wenn Sie nicht nach ID auswählen. Wiederum - der Cache der zweiten Ebene speichert eine Zuordnung der IDs der Entitäten zu anderen Eigenschaften (sie speichert keine Objekte, sondern die Daten selbst). Wenn Ihre Suche folgendermaßen aussieht: from Authors where name = :name, dann triffst du nicht den Cache.
  • Wenn Sie HQL verwenden (auch wenn Sie verwenden where id = ?).
  • Wenn Sie in Ihrem Mapping festgelegt haben fetch="join"Dies bedeutet, dass zum Laden von Assoziationen Joins überall anstelle von separaten Select-Anweisungen verwendet werden. Der Cache auf Prozessebene funktioniert nur dann auf untergeordneten Objekten fetch="select" wird eingesetzt.
  • Selbst wenn du es getan hast fetch="select" aber dann in HQL verwenden Sie Joins, um Verknüpfungen auszuwählen - diese Joins werden sofort ausgegeben und überschreiben, was auch immer Sie in hbm.xml oder Anmerkungen angegeben haben.

Jetzt über den Abfrage-Cache. Sie sollten beachten, dass es sich nicht um einen separaten Cache handelt, sondern um einen Zusatz zum Cache auf Prozessebene. Angenommen, Sie haben eine Ländereinheit. Es ist statisch, also wissen Sie, dass jedes Mal, wenn Sie sagen, das gleiche Ergebnis eingestellt wird from Country. Dies ist ein perfekter Kandidat für den Abfrage-Cache, es speichert eine Liste von IDs Wenn Sie das nächste Mal alle Länder auswählen, wird diese Liste an den Prozesslevel-Cache zurückgegeben, und der letztere gibt Objekte für jede ID zurück, da diese Objekte bereits im Cache der zweiten Ebene gespeichert sind. Der Abfragecache wird jedesmal ungültig gemacht, wenn sich etwas mit der Entität ändert. Nehmen wir an, Sie haben konfiguriert from Authors in einen Abfrage-Cache platziert werden. Es wird nicht effektiv sein, da der Autor sich oft ändert. Daher sollten Sie den Abfrage-Cache nur für mehr oder weniger statische Daten verwenden.


80
2017-08-14 21:23



  • Der Cache der 2. Ebene ist ein Schlüssel-Wert-Speicher. Es funktioniert nur, wenn Sie Ihre Entitäten per ID erhalten
  • Der Cache der zweiten Ebene wird für jede Entität ungültig gemacht / aktualisiert, wenn eine Entität über Hibernate aktualisiert / gelöscht wird. Es wird nicht ungültig gemacht, wenn die Datenbank auf andere Weise aktualisiert wird.
  • für Abfragen (z. B. Liste der Kunden) verwenden Sie den Abfrage-Cache.

In der Praxis ist es sinnvoll, einen Schlüssel-Wert-verteilten Cache zu haben - das ist Memcached, und es versorgt Facebook, Twitter und viele mehr. Aber wenn Sie keine Lookups nach ID haben, wird es nicht sehr nützlich sein.


32
2017-08-14 18:52



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

Ihre Frage nacheinander zu beantworten ist meine Antwort.

Q. Wann schlägt Hibernate diesen Cache?

EIN. First Level Cache ist mit dem verbunden Sitzungsobjekt. Das Second Level Cache ist mit dem verbunden Sitzungs-Factory-Objekt. Wenn das Objekt nicht in der ersten gefunden wird, wird die zweite Ebene überprüft.

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

A. Sie haben das in Ihrem Update beantwortet. Auch der Query-Cache speichert nur die Liste der IDs des Objekts und die Objekte, deren IDs in der gleich Second-Level-Cache. Wenn Sie den Abfragecache aktivieren, verwenden Sie dieselbe Ressource. Ordentlich richtig?

F. Ich nehme an, dass ich sie per ID aus dem Cache abrufen kann. Das wäre zwar einfach, aber auch nicht cachingwürdig. Aber was, wenn ich mit all meinen Kunden kalkulieren möchte. Nehmen wir an, ich möchte eine Liste der Kunden zeigen, wie würde ich dann darauf zugreifen?

A. Beantwortet oben.

Frage: Wie bekomme ich alle meine Kunden, wenn das Ablegen von Abfragen deaktiviert ist?

A. Beantwortet oben.

F. Was würde passieren, wenn jemand einen der Kunden aktualisiert? Wird dieser Kunde im Cache ungültig oder werden alle Kunden für ungültig erklärt?

A. Hibernate hat keine Ahnung, aber Sie könnten andere IMDG / verteilte Caches von Drittanbietern als implementiert verwenden den Cache der zweiten Ebene in den Ruhezustand versetzen und sie für ungültig erklären. z.B. TayzGrid ist ein solches Produkt und es gibt mehr, denke ich.


10
2017-12-17 09:59