İkinci Seviye Cache — Hangi Cache, Hangi Soruya Cevap Verir?
Önce şunu oku: Entity equals ve hashCode — Aynı Sipariş mi? , Spring Cache — @Cacheable Kimin Cevabını Hatırlıyor?
30 saniyede özet
İkinci seviye cache, bir kez okunan kayıtları sonraki isteklerle paylaşır; ama yalnızca id ile okumayı hızlandırır. Hibernate'in görmediği bir değişiklik olursa da süre dolana kadar eski veriyi göstermeye devam eder.
Ekip veritabanı yükünü azaltmak için query cache’i açtı. Kategori sayfası beklenenin tersine yavaşladı. Bir hafta sonra da fiyat ekranı, başka bir servisin güncellediği fiyatları saatlerce eski gösterdi.
-
Bayt: Veritabanı yükünü azaltmak için query cache'i açtık!
-
Sen: Güzel, sayfa hızlandı mı?
-
Bayt: Tersine, yavaşladı. Bir hafta sonra da fiyatlar saatlerce eski göründü.
-
Bayt: Cache tam olarak neyi saklıyor, ve kimden habersiz kalıyor? Ona bakalım.
Masadaki kitap, salondaki kitap
Birinci seviye cache, persistence context’in kendisidir ve istekle birlikte biter. İki farklı istekte find(7) iki SELECT demektir.
second-level cachePersistence context'ler arasında paylaşılan, entity durumunu id'ye göre tutan Hibernate cache'i. İsteğe bağlıdır; bir sağlayıcı (JCache, Infinispan) ve entity başına işaret ister.Sözlükte gör → (L2) istekler arasında paylaşılır ve entity durumunu id’ye göre tutar. İsteğe bağlıdır: bir sağlayıcı (JCache, Infinispan) ve entity başına @Cache işareti ister.
L2 id ile okumaları hızlandırır: find, getReference, ilişki yüklemeleri. JPQL sorgusu ise hangi satırların sonuca gireceğini bilmek için yine veritabanına gider.
Kafam karıştı, daha basit anlat
Birinci seviye cache senin masandaki kitaptır, iş bitince rafa kalkar. İkinci seviye cache ise salondaki ortak raf: herkes oradan alabilir.
Hibernate'in birinci seviye cache'i ile ikinci seviye (L2) cache'i arasındaki fark nedir?
Product için L2 açık. Aynı kategori sorgusu (JPQL) iki farklı istekte çalıştırılıyor; query cache kapalı. İkinci istekte ne olur?
Query cache aslında ne saklar?
Query cache açık, Product için L2 kapalı. 20 ürün döndüren aynı sorgu ikinci kez çalışıyor. Kaç SQL gider? Cevabı göster
20. query cacheBir sorgunun sonucu olarak yalnızca id listesini saklayan cache. Sorgudaki tablolardan biri Hibernate üzerinden değişince geçersiz olur; entity'ler L2'de değilse N+1 üretir.Sözlükte gör → sonuçları değil, yalnızca id’leri saklar. Entity’ler L2’de olmadığı için her id ayrı bir SELECT ile yüklenir.
Adım adım oku
- Birinci seviye cache masandaki kitaplardır: istek bitince hepsi rafa döner.
- L2 cache ortak okuma salonudur: bütün istekler oradaki kitabı veritabanına gitmeden okur.
- Başka bir servis veritabanındaki fiyatı doğrudan değiştirirse salon bundan haberdar olmaz ve eski baskıyı vermeye devam eder.
- Query cache yalnızca sonuçtaki kimlikleri, yani raf numaralarını saklar. L2 kapalıysa her kitap yine tek tek getirilir.
Query cache, sorgudaki tablolardan biri Hibernate üzerinden her değiştiğinde geçersiz olur. Sık yazılan bir tabloda neredeyse hiç hit almaz.
Kafam karıştı, daha basit anlat
Query cache cevabın kendisini değil, yalnızca hangi kitapların geldiğinin listesini saklar. Kitaplar rafta yoksa her birini ayrı ayrı getirmen gerekir.
Query cache açıldı, ama sorgu sayısı düşmek yerine arttı: tek bir sorgu yerine 20 SELECT görülüyor. Neden?
Ülke listesi uygulama açıldıktan sonra hiç değişmiyor. L2 için en uygun eşzamanlılık stratejisi hangisi?
Kendin gör
Hangi cache, hangi soruya cevap verir?
Tohum 638400Oynat ya da adımla.
Şu an ne oldu?
Her istek yeni bir persistence context
Birinci seviye cache istekle birlikte biter. İstekler arasında paylaşılan tek şey, açıksa, L2 ve query cache'tir.
Görevler0/3
Query cache ile sorgu sayısını artıraçık
İpucu
Query cache açık, entity cache kapalı.
L2'den eski bir fiyat okuaçık
İpucu
Fiyatı Hibernate'in görmediği biri değiştirsin.
Uygulama fiyatı değiştirirken en az SQL ile güncel kalaçık
İpucu
İki cache birlikte.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Query cache açık, L2 kapalı: ikinci sorgu 20 SELECT.
- L2’yi aç. İkinci sorgu ve tekrar eden find SQL’siz.
- Yazanı “Bu uygulama” yap. Cache güncel kaldı, toplam 3 SQL.
- Yazanı “Başka bir servis” yap. Son okuma eski fiyatı verdi.
Fiyat yönetim servisi fiyatları doğrudan veritabanına yazıyor. Sipariş servisi bazen saatlerce eski fiyat gösteriyor. Hatalı satır hangisi?
Her veriyi L2'ye uygunluğuna göre ayır.
Tuzaklar
Birden çok pod ve yerel L2. Her pod’un kendi kopyası vardır; bir pod’un yazması diğerlerinin kopyasını değiştirmez. Kümelenmiş bir sağlayıcı kullan ya da L2’yi değişmeyen veriyle sınırla.
Native SQL ile yazmak. Hangi entity’nin etkilendiğini bildirmezsen Hibernate bütün L2 bölgelerini boşaltır.
Her entity’yi cache’lemek. Sık değişen veri sürekli geçersiz kılınır; kazanç yok, eskime riski var.
Kafam karıştı, daha basit anlat
Her sunucunun kendi ortak rafı varsa, birinde değişen kitap ötekilerde eski kalır. Bu cache’i en iyi, pek değişmeyen verilerde kullan.
Uygulama üç pod'da çalışıyor ve L2 sağlayıcısı her pod'da yerel bir bellek cache'i. Bir pod ürünü güncellediğinde diğerleri ne görür?
Aşağıdaki örnek bir bankanın referans verisinden ve L2’yi yalnızca uygun veriye açıyor: hiç değişmeyen para birimleri READ_ONLY, yalnızca bu uygulamanın yazdığı ürün ağacı READ_WRITE, query cache tek bir sık sorguda ve hepsi istatistikle doğrulanıyor.
Derinleş · Bankacılık referans verisi için ikinci seviye cache 6 dosya · ~103 satır · ilk okumada atlayabilirsin
Kendini sına
Birinci seviye cache, persistence context'in kendisidir ve istekle biter.
Query cache açık bir sorgu, siparişler tablosuna dakikada yüzlerce yazma yapılan bir sistemde hiç hit almıyor. Neden?
Aklında kalacak üç şey
- 1 Birinci seviye cache istekle birlikte biter. İstekler arasında id ile okumayı yalnızca isteğe bağlı L2 cache hızlandırır; JPQL sorguları yine veritabanına gider.
- 2 Query cache sonuçları değil id'leri saklar. Kayıtlar L2'de değilse her id için ayrı SELECT gider.
- 3 L2 yalnızca Hibernate üzerinden yapılan yazmaları bilir. Başka bir servisin ya da elle çalıştırılan SQL'in değiştirdiği veri L2'ye ulaşmaz.
4 kart sonraki derste seni bekliyor