Hazırda bekletme ikinci seviye önbelleği ne zaman ve nasıl kullanılır?


91

Hazırda bekletme modunun ikinci seviye önbelleğe ne zaman ulaştığını ve önbelleği ne zaman geçersiz kıldığını anlamakta güçlük çekiyorum.

Şu anda anladığım şey bu:

  • İkinci seviye önbellek, oturumlar arasında varlıkları saklar, kapsam SessionFactory'dir
  • Hangi varlıkların önbelleğe alınacağını söylemelisiniz, varsayılan olarak hiçbir varlık önbelleğe alınmaz
  • Sorgu önbelleği, sorgu sonuçlarını önbellekte depolar.

Anlamadığım şey

  • Hazırda bekletme bu önbelleğe ne zaman ulaşır?
  • Diyelim ki ikinci seviye önbelleği kurdum ama sorgu önbelleğini ayarlamadım. Müşterilerimi önbelleğe almak istiyorum, 50000 tane var. Müşterileri önbellekten hangi yollarla alabilirim?
  • Önbellekten id ile alabileceğimi varsayıyorum. Bu kolay olur ama aynı zamanda önbelleğe almaya değmez. Ama ya tüm müşterilerimle bazı hesaplamalar yapmak istersem. Diyelim ki müşterilerin bir listesini göstermek istiyorum, o zaman onlara nasıl erişebilirim?
  • Sorgu önbelleğe alma devre dışı bırakılırsa tüm müşterilerimi nasıl edinirim?
  • Biri müşterilerden birini güncellediğinde ne olur?
    • Bu müşteri önbellekte geçersiz mi olur yoksa tüm müşteriler geçersiz mi olur?

Yoksa önbelleğe almayı tamamen yanlış mı düşünüyorum? Bu durumda ikinci seviye önbelleğin daha uygun kullanımları nelerdir? Hazırda bekletme belgeleri, önbelleğin gerçekte nasıl çalıştığı hiç de net değildir. Sadece nasıl kurulacağına dair talimatlar var.

Güncelleme: Böylece, ikinci seviye önbelleğin (sorgu önbelleği olmadan) verileri id'lere göre yüklemek için iyi olacağını anladım. Örneğin, bir web uygulamasındaki her istekte izinleri kontrol etmek istediğim kullanıcı nesnem var. Bu, kullanıcıyı ikinci seviye önbelleğe alarak veritabanı erişimini azaltmak için iyi bir durum olur mu? Kullanıcı kimliğini oturumda veya izinleri kontrol etmem gereken her yerde saklayacağım gibi, kullanıcıyı kimliğine göre yükler ve izinleri kontrol ederdim.


Yanıtlar:


102

Öncelikle süreç seviyesi önbelleğinden (veya Hazırda Bekletme'de dedikleri 2. seviye önbellekten) bahsedelim. Çalışması için yapmalısın

  1. önbellek sağlayıcısını yapılandır
  2. Hibernate'e hangi varlıkları önbelleğe alacağını söyleyin (bu tür bir eşleme kullanıyorsanız, doğrudan hbm.xml dosyasında).

Önbellek sağlayıcısına kaç nesne depolaması gerektiğini ve ne zaman / neden geçersiz kılınması gerektiğini söylersiniz. Diyelim ki bir Kitabınız ve Yazar varlığınız var, bunları DB'den her aldığınızda, sadece önbellekte olmayanlar aslında DB'den seçilecektir. Bu, performansı önemli ölçüde artırır. Şu durumlarda kullanışlıdır:

  • Veritabanına yalnızca Hazırda Bekletme aracılığıyla yazarsınız (çünkü önbellekteki varlıkları ne zaman değiştireceğini veya geçersiz kılacağını bilmek için bir yola ihtiyaç duyar)
  • Sık sık nesneleri okursunuz
  • Tek bir düğümünüz var ve çoğaltmanız yok. Aksi takdirde, önbelleğin kendisini çoğaltmanız gerekir (JGroups gibi dağıtılmış önbellekleri kullanın), bu da daha fazla karmaşıklık ekler ve hiçbir şey paylaşmayan uygulamalar kadar iyi ölçeklenmez.

Öyleyse önbellek ne zaman çalışır?

  • Siz session.get()veya session.load()daha önce seçilen ve önbellekte bulunan nesne. Önbellek, kimliğin anahtar ve özelliklerin değerler olduğu bir depodur. Dolayısıyla, yalnızca kimliğe göre arama yapma imkanı olduğunda, DB'ye basmayı ortadan kaldırabilirsiniz.
  • İlişkilendirmeleriniz tembel (veya birleştirmeler yerine seçimlerle istekli) olduğunda

Ancak şu durumlarda işe yaramaz:

  • Kimliğe göre seçmezseniz. Yine - 2. düzey önbellek, varlıkların kimliklerinin diğer mülklerle bir haritasını saklar (aslında nesneleri değil, verileri kendisi depolar), yani aramanız şöyle görünüyorsa:from Authors where name = :name önbelleğe basmazsınız.
  • HQL kullandığınızda (kullansanız bile where id = ? ).
  • Haritalamanızda ayarlarsanız fetch="join" , bu, ilişkilendirmeleri yüklemek için birleştirmelerin ayrı select deyimleri yerine her yerde kullanılacağı anlamına gelir. İşlem düzeyi önbelleği, yalnızca fetch="select"kullanılıyorsa, alt nesnelerde çalışır .
  • Sahip olsanız bile, fetch="select"ancak daha sonra HQL'de ilişkilendirmeleri seçmek için birleştirme kullanırsınız - bu birleşimler hemen verilecek ve hbm.xml'de veya ek açıklamalarda belirttiğiniz her şeyin üzerine yazılacaktır.

Şimdi, Sorgu Önbelleği hakkında. Bunun ayrı bir önbellek olmadığını, işlem seviyesi önbelleğine ek olduğunu unutmamalısınız. Diyelim ki bir Ülke varlığınız var. Statiktir, yani her seferinde söylediğinizde aynı sonuç kümesinin olacağını bilirsiniz from Country. Bu, sorgu önbelleği için mükemmel bir adaydır , kendi içinde bir kimlik listesi depolar ve bir dahaki sefere tüm ülkeleri seçtiğinizde, bu listeyi işlem seviyesi önbelleğine döndürür ve ikincisi, sırayla, her kimlik için nesneleri döndürür. Bu nesneler zaten 2. seviye önbellekte saklandığından. Varlıkla ilgili herhangi bir şey her değiştiğinde sorgu önbelleği geçersiz kılınır. Diyelim ki from Authorsbir Sorgu Önbelleğine yerleştirilmek üzere yapılandırdınız . Yazar sık ​​sık değiştiği için etkili olmayacaktır.


"Yazardan bir getirme a.books'a katılma" sorgusu, yazarları önbellekten almak için Sorgu önbelleği gerektirir mi?
palto

1
Hayır, sorgu önbelleği yalnızca statik veriler içindir ve yalnızca kimlikleri depolar. Yazarlar 2. seviye önbellekten alınacaktır.
Stanislav Bashkyrtsev

@ctapobep: Söylediğiniz doğru değil! Yazar varlığın alan kitaplarına açıklama eklenmişse (EAGER'ı getir) "Yazardan bir getirme a.kitaplara katıl" iyi çalışıyor ... sanırım çok geç
Bilal BBB

Harika bir cevap! Her zaman hatırlayacağım! : d
Mohammadreza Khatami

'sorgu önbelleğini' etkinleştirdikten sonra, id dışında başka bir özelliğe göre seçim yaparsanız, verileri önbellekten alıyor mu?
Arun Raaj

43
  • 2. düzey önbellek, bir anahtar-değer deposu. Yalnızca varlıklarınızı kimliğe göre alırsanız çalışır
  • 2. düzey önbellek, bir varlık hazırda bekletme yoluyla güncellendiğinde / silindiğinde her varlık için geçersiz kılınır / güncellenir. Veritabanı farklı bir şekilde güncellenirse geçersiz sayılmaz.
  • sorgular için (örn. müşteri listesi) sorgu önbelleğini kullanın.

Gerçekte, anahtar-değer dağıtılmış bir önbelleğe sahip olmak faydalıdır - memcached budur ve facebook, twitter ve daha pek çok şeye güç sağlar. Ancak kimliğe göre aramalarınız yoksa, o zaman çok yararlı olmayacaktır.


Sorgu önbelleği (Projeksiyonlar, DTO kalıpları için Sonuç Dönüştürücüler ile çalışır) ve önbelleğe alınan sorguda kullanılan bir Varlığı güncelleştirirseniz geçersiz kılınır. Dediğiniz gibi, 2. düzey önbellek yalnızca varlığı kimliğe göre (ölçüt kısıtlamaları için çalışmaz) veya projeksiyonlu ölçütler (Yalnızca bazı özellikleri seçin) ile aldığınız sorgular için çalışır. BTW, "hazırda bekletme önbelleğinin nasıl çalıştığı" için en iyi (devam ettirilen) yanıt.
ics_mauricio

12

Partiye geç kaldı ancak birçok geliştiricinin sorduğu bu soruya sistematik olarak cevap vermek istedi.

Sorunuzu tek tek almak cevabım burada.

S. Hazırda bekletme bu önbelleğe ne zaman gelir?

A. Birinci Düzey önbellek , Session nesnesiyle ilişkilidir . İkinci Seviye Önbellek ile ilişkili Session Fabrikası nesne . İlkinde nesne bulunamazsa, ikinci seviye kontrol edilir.

S. İkinci düzey önbelleği kurduğumu ancak sorgu önbelleğini ayarlamadığımı varsayalım. Müşterilerimi önbelleğe almak istiyorum, 50000 tane var. Müşterileri önbellekten hangi yollarla alabilirim?

A. Bunu güncellemenizde yanıtladınız. Ayrıca sorgu önbelleği, yalnızca nesnenin kimliklerinin listesini depolar ve bu Nesneler, kimliklerine sahip aynı ikinci düzey önbellekte depolanır . Dolayısıyla, sorgu önbelleğini etkinleştirirseniz, aynı kaynağı kullanırsınız. Düzgün değil mi?

S. Onları id ile önbellekten alabileceğimi varsayıyorum. Bu kolay olurdu ama aynı zamanda önbelleğe almaya değmez. Ama ya tüm müşterilerimle bazı hesaplamalar yapmak istersem. Diyelim ki müşterilerin bir listesini göstermek istiyorum, o zaman onlara nasıl erişebilirim?

A. Yukarıda cevaplanmıştır.

S. Sorgu önbelleğe alma devre dışı bırakılırsa tüm müşterilerime nasıl ulaşabilirim?

A. Yukarıda cevaplanmıştır.

S. Biri müşterilerden birini güncellediğinde ne olur? Bu müşteri önbellekte geçersiz mi olur yoksa tüm müşteriler geçersiz mi olur?

A. Hibernate'in hiçbir fikri yoktur, ancak diğer üçüncü taraf IMDG / dağıtılmış önbelleklerini hazırda bekletme ikinci seviye önbellek olarak uygulamak ve geçersiz kılmak için kullanabilirsiniz. Örneğin TayzGrid böyle bir ürün ve sanırım daha fazlası var.


0

Hazırda bekletme ikinci düzey önbelleği anlamak ve uygulamak biraz zor. Sorularınıza göre söyleyebileceğimiz şeyler:

Hazırda Bekletme bu önbelleğe ne zaman gelir?

Önerdiğiniz gibi, Hazırda Beklet L2 önbelleği (etkinleştirilmişse; varsayılan olarak açık değildir) yalnızca L1 önbelleğinden sonra sorgulanır. Bu, verileri birden çok oturumda saklanan bir anahtar / değer önbelleğidir.

Diyelim ki ikinci seviye önbelleği kurdum ama sorgu önbelleğini ayarlamadım. Müşterilerimi önbelleğe almak istiyorum, 50000 tane var. Müşterileri önbellekten hangi yollarla alabilirim?

Müşteri verileri statik olduğundan ve ilişkisel bir veritabanından alındığından, sorgu önbelleğe alma bu kullanım durumu için en iyisidir.

Biri müşterilerden birini güncellediğinde ne olur? Bu müşteri önbellekte geçersiz mi olur yoksa tüm müşteriler geçersiz mi olur?

Kullandığınız belirli Hazırda Bekletme önbellek stratejisine bağlıdır. Hibernate'in aslında dört farklı önbellek stratejisi vardır:

READ_ONLY : Nesneler önbellek içinde bir kez değişmez.

NONSTRICT_READ_WRITE : İlgili veritabanı girdisi güncellendikten sonra nesneler değişir (sonunda); bu nihai tutarlılığı garanti eder.

READ_WRITE : İlgili veritabanı girişi güncellendikten sonra nesneler (hemen) değişir; bu, "yumuşak" kilitler kullanarak güçlü tutarlılığı garanti eder.

İŞLEMSEL : Nesneler, dağıtılmış XA işlemlerini kullanarak değişir ve veri bütünlüğünü sağlar; bu, toplam başarıyı veya tüm değişiklikleri geri almayı garanti eder. Bu durumların dördünde de tek bir veritabanı girişini güncellemek önbellekteki tüm müşteri listesini geçersiz kılmaz. Hazırda bekletme bundan biraz daha akıllı :)

Hazırda Bekletme'de L2 önbelleğe alma işleminin nasıl çalıştığı hakkında daha fazla bilgi edinmek için "Hazırda Bekletme L2 önbelleği nedir" başlıklı makaleye veya Redis ile Hazırda Bekletme'de Önbelleğe Alma ayrıntılı makalesine göz atabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.