Mam problem ze zrozumieniem, kiedy hibernacja osiąga pamięć podręczną drugiego poziomu, a kiedy unieważnia pamięć podręczną.
Oto, co obecnie rozumiem:
- Pamięć podręczna drugiego poziomu przechowuje jednostki między sesjami, zakres to SessionFactory
- Musisz powiedzieć, które jednostki mają być buforowane, żadna jednostka nie zostanie domyślnie zapisana w pamięci podręcznej
- Pamięć podręczna zapytań przechowuje wyniki zapytań w pamięci podręcznej.
To, czego nie rozumiem, to
- Kiedy hibernacja uderza w tę pamięć podręczną?
- Powiedzmy, że skonfigurowałem pamięć podręczną drugiego poziomu, ale nie buforowanie zapytań. Chcę buforować moich klientów, jest ich 50000. W jaki sposób mogę odzyskać klientów z pamięci podręcznej?
- Zakładam, że mogę je uzyskać przez identyfikator z pamięci podręcznej. Byłoby to łatwe, ale nie warte buforowania. Ale co, jeśli chcę przeprowadzić obliczenia dla wszystkich moich klientów. Powiedzmy, że chcę wyświetlić listę klientów, w jaki sposób mogę uzyskać do nich dostęp?
- Jak mogę zdobyć wszystkich moich klientów, jeśli buforowanie zapytań jest wyłączone?
- Co by się stało, gdyby ktoś zaktualizował jednego z klientów?
- Czy ten klient zostałby unieważniony w pamięci podręcznej, czy wszyscy klienci zostaliby unieważnieni?
A może myślę, że buforowanie jest całkowicie złe? Jakie byłyby bardziej odpowiednie zastosowania pamięci podręcznej drugiego poziomu w takim przypadku? Dokumentacja hibernacji nie jest wcale jasna, jak w rzeczywistości działa pamięć podręczna. Są tylko instrukcje, jak to skonfigurować.
Aktualizacja: Więc zrozumiałem, że pamięć podręczna drugiego poziomu (bez pamięci podręcznej zapytań) byłaby dobra do ładowania danych według identyfikatorów. Na przykład mam obiekt użytkownika, dla którego chcę sprawdzić uprawnienia w każdym żądaniu w aplikacji internetowej. Czy byłby to dobry przypadek ograniczenia dostępu do bazy danych poprzez buforowanie użytkownika w pamięci podręcznej drugiego poziomu? Jakbym przechowywał identyfikator użytkownika w sesji lub gdziekolwiek, a kiedy muszę sprawdzić uprawnienia, załadowałbym użytkownika według jego identyfikatora i sprawdziłbym uprawnienia.
Odpowiedzi:
Przede wszystkim porozmawiajmy o pamięci podręcznej na poziomie procesu (lub pamięci podręcznej drugiego poziomu, jak to nazywają w Hibernate). Aby to zadziałało, powinieneś
Informujesz dostawcę pamięci podręcznej, ile obiektów ma przechowywać i kiedy / dlaczego powinny zostać unieważnione. Powiedzmy, że masz encje Book i Author, za każdym razem, gdy otrzymujesz je z DB, tylko te, które nie są w pamięci podręcznej, zostaną wybrane z faktycznie DB. Zwiększa to znacznie wydajność. Przydaje się, gdy:
Kiedy więc działa pamięć podręczna?
session.get()
lubsession.load()
obiekt, który został wcześniej wybrany i znajduje się w pamięci podręcznej. Pamięć podręczna to magazyn, w którym ID jest kluczem, a właściwości są wartościami. Więc tylko wtedy, gdy istnieje możliwość wyszukiwania według identyfikatora, możesz wyeliminować uderzanie w DB.Ale to nie działa, gdy:
from Authors where name = :name
to nie trafisz do pamięci podręcznej.where id = ?
).fetch="join"
, oznacza to, że do załadowania asocjacji wszędzie będą używane sprzężenia zamiast oddzielnych instrukcji select. Pamięć podręczna na poziomie procesu działa na obiektach potomnych tylko wtedy, gdyfetch="select"
jest używana.fetch="select"
ale wtedy w HQL używasz łączenia do wybierania asocjacji - te sprzężenia zostaną wydane od razu i nadpiszą wszystko, co określono w hbm.xml lub adnotacjach.Teraz o pamięci podręcznej zapytań. Należy zauważyć, że nie jest to oddzielna pamięć podręczna, jest to dodatek do pamięci podręcznej na poziomie procesu. Załóżmy, że masz jednostkę Country. Jest statyczny, więc wiesz, że za każdym razem, gdy powiesz, będzie ten sam zestaw wyników
from Country
. Jest to idealny kandydat do pamięci podręcznej zapytań, będzie przechowywać listę identyfikatorów w sobie, a gdy następnym razem wybierzesz wszystkie kraje, zwróci tę listę do pamięci podręcznej na poziomie procesu, a ta z kolei zwróci obiekty dla każdego identyfikatora ponieważ te obiekty są już przechowywane w pamięci podręcznej drugiego poziomu. Pamięć podręczna zapytań jest unieważniana za każdym razem, gdy zmienia się cokolwiek związanego z jednostką. Powiedzmy, że skonfigurowano Cięfrom Authors
do umieszczenia w pamięci podręcznej zapytań. Nie będzie to skuteczne, ponieważ Autor często się zmieniaźródło
W rzeczywistości przydatne jest posiadanie rozproszonej pamięci podręcznej klucza i wartości - to właśnie jest memcached i obsługuje Facebooka, Twittera i wiele innych. Ale jeśli nie masz wyszukiwań według identyfikatora, nie będzie to zbyt przydatne.
źródło
Spóźniłem się na imprezę ale chciałem systematycznie odpowiadać na te pytania, które zadaje wielu programistów.
Odpowiadam na twoje pytanie jedno po drugim.
A. Pamięć podręczna pierwszego poziomu jest powiązana z obiektem Session . Second Level Cache jest związany z obiektu Session Factory . Jeśli obiekt nie zostanie znaleziony na pierwszym, sprawdzany jest drugi poziom.
A. Otrzymałeś odpowiedź w swojej aktualizacji. Również pamięć podręczna zapytań przechowuje tylko listę identyfikatorów obiektu, a te obiekty, w których ich identyfikatory są przechowywane w tej samej pamięci podręcznej drugiego poziomu. Jeśli więc włączysz pamięć podręczną zapytań, użyjesz tego samego zasobu. Schludnie, prawda?
A. Odpowiedział powyżej.
A. Odpowiedział powyżej.
O. Hibernate nie ma pojęcia, ale możesz użyć innych IMDG / rozproszonych pamięci podręcznych innych firm do zaimplementowania jako hibernacji pamięci podręcznej drugiego poziomu i unieważnić je. np. TayzGrid jest jednym z takich produktów i myślę, że jest ich więcej.
źródło
Pamięć podręczna drugiego poziomu Hibernacji jest trochę trudna do zrozumienia i wdrożenia. Oto, co możemy powiedzieć na podstawie Twoich pytań:
Jak sugerujesz, zapytanie o pamięć podręczną Hibernate L2 (jeśli jest włączone; nie jest domyślnie włączone) jest sprawdzane tylko po pamięci podręcznej L1. Jest to pamięć podręczna klucz-wartość, której dane są przechowywane w wielu sesjach.
Buforowanie zapytań byłoby najlepsze w tym przypadku użycia, ponieważ dane klienta są statyczne i pobierane z relacyjnej bazy danych.
To zależy od konkretnej strategii pamięci podręcznej Hibernacji, której używasz. Hibernate faktycznie ma cztery różne strategie pamięci podręcznej:
TYLKO ODCZYT : Obiekty nie zmieniają się raz w pamięci podręcznej.
NONSTRICT_READ_WRITE : Obiekty zmieniają się (ostatecznie) po zaktualizowaniu odpowiedniego wpisu w bazie danych; gwarantuje to ostateczną spójność.
READ_WRITE : Obiekty zmieniają się (natychmiast) po zaktualizowaniu odpowiedniego wpisu w bazie danych; gwarantuje to mocną spójność dzięki zastosowaniu „miękkich” zamków.
TRANSAKCYJNE : obiekty zmieniają się za pomocą rozproszonych transakcji XA, zapewniając integralność danych; gwarantuje to całkowity sukces lub cofnięcie wszystkich zmian. Jednak we wszystkich czterech przypadkach zaktualizowanie pojedynczego wpisu bazy danych nie unieważniłoby całej listy klientów w pamięci podręcznej. Hibernate jest trochę mądrzejszy :)
Aby dowiedzieć się więcej o tym, jak działa buforowanie L2 w Hibernate, możesz zapoznać się z artykułem „Co to jest pamięć podręczna Hibernate L2” lub szczegółowym artykułem Buforowanie w Hibernate with Redis
źródło