czwartek, 2 października 2014

Quick@Easy cache added



Problem : Spring Data + JPA + Second level Cache
Rozwiązanie : dodać hibernate-cache do dependency
 Zaleta : Wykorzystanie cache second level w celu zwiększenia wydajności aplikacji

Problem2 : Monitoring
Rozwiązanie2 : dodać hibernate-jmx do dependency włączyć obsługę JMX w springu
Zaleta2 : Wiem co się dzieje + eliminacja bottlenecks w aplikacji. Ułatwienie znalezienia problemu N+1 



Ogólne korzyści z użycia cache w Twojej aplikacji są oczywiste : 
   - redukcja zapytań do db
   - redukcja tworzenia obiektów
   - redukcja użycia CPU omijamy często powtórną serializację (poprawny wyjściowy format danych)
   - redukcja ruchu na kablu 

Charakterystyka ehcache : (Hibernate korzysta z niego domyślnie Easy Hibernate Cache)

Zalety : 
  - łatwość impl
  - sprawdza się w większości przypadków
  - wbudowany alg eksmisji
  - wbudowane statystyki i dostęp przez JMX
  - możliwa replikacja i dystrybucja danych
  - kontrola wykorzystania sterty
  - łatwa i rozbudowana konfiguracja regionów
  - szybkość działania

Przykład konfiguracji :

Teraz musimy powiedzieć ehcache'owi jak skonfigurować regiony, strategię i politykę ....
Startuje od projektu z poprzedniego posta czyli JPA + Spring Data. Pierwsze co muszę zrobić to powiedzieć jak chce skonfigurować cache :


Krótkie objaśnienie :
W celu określenia polityki cache stosuje się plik ehcache.xml.
timeToIdleSeconds - określa ważność w sekundach od momentu pobrania ostatniego elementu z bufora
timeToIdleLiveSecond - określa ważność w sekundach od momentu umieszczenia w buforze
maxElementsInMemory - max liczba elementów przechowywana w pamięci
overflowToDisk - buforowanie z użyciem dysku twardego
eternal - true -> elementy w cache nigdy nie wygasają (timeToIdealSeconds, timeToLiveSeconds)


Odpalam aplikację i widzę :
Problem : Unable to resolve name [org.hibernate.cache.ehcache.EhCacheRegionFactory] as strategy [org.hibernate.cache.spi.RegionFactory]

org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.ehcache.EhCacheRegionFactory] 

No tak brakuje jakiś zależności, więc dodaje na szybko:
Już lepiej...


Trochę teorii na temat cache - hibernate :
L1:
 - dotyczy encji
 - Cache L1 jest domyślnie włączony zawsze :)
 - skojarzony z sesją Hibernate , (JPA entityManager)
 - optymalizacja wąskiej przestrzeni pracy
 - pobieranie po id,
 -  zwielokrotnienie find()  - jeden select w SQL (is dirty pattern)
 -  zwieloktornienie merge - ale operacja Update  (is dirty pattern)
 L2 :
  - cache dotyczy encji lub kolekcji
  - skojarzony z fabryką sesji (JPA EntityManagerFactory)
  - cache dla całej kolekcji czy grafu zapytania find()
  - najpierw następuje sprawdzenie w L1 w następnej kolejności w L2

Problem : Kiedy użyć L2 , a kiedy nie ?
  Tak : 
   - odciążenie bazy - poprawa wydajności
   - sprawdza się dla zapytań często wykonywach
   - sprawdza się doskonale jak każdy cache dla obiektów rzadko lub wcale nie modyfikowanych np słowniki

  Nie : 
   - dla dużych zbiorów danych będzie to zabójstwo OutOfMemoryException
   - słabe rozwiązanie dla encji często lub współbieżnie modyfikowanych

Strategie : 

Read-only - Najbardziej wydajna : encje są często czytane ale nigdy nie są modyfikowane -> słowniki
Nonstrict read-write : encje są rzadko modyfikowane
Read-write  : Większy narzut encje są modyfikowane

Teraz płynnie przychodzimy przez konfiguracją wszystkich pozostałych warstw aplikacji :
Encja : 
Repository :
Konfiguracja EntityManager'a :
Test :
Pytanie czy naprawdę działa ?
Teraz jeszcze jeden bajer chce podłączyć JMX i zobaczyć te statystyki na konsoli :
Aby to zadziałało potrzebuje następnych dependecies (jmx + ehcache):
Wynik : używam hibernate-jconsole :) - polecam ...


















Tyle :) Kod po posta - > tutaj Uwaga : pod branch'em cache ;)

Brak komentarzy:

Prześlij komentarz