Kapan dan bagaimana menggunakan cache tingkat kedua hibernasi?

90

Saya kesulitan memahami saat hibernasi mencapai cache tingkat kedua dan kapan hal itu membuat cache tidak valid.

Inilah yang saat ini saya pahami:

  • Cache tingkat kedua menyimpan entitas antar sesi, cakupannya adalah SessionFactory
  • Anda harus memberi tahu entitas mana yang akan disimpan dalam cache, tidak ada entitas yang akan di-cache secara default
  • Cache kueri menyimpan hasil kueri di cache.

Yang tidak saya mengerti adalah

  • Kapan hibernasi mencapai cache ini?
  • Katakanlah saya telah menyiapkan cache tingkat kedua tetapi bukan cache kueri. Saya ingin menyimpan cache pelanggan saya, ada 50000 dari mereka. Dengan cara apa saya bisa mengambil pelanggan dari cache?
  • Saya berasumsi saya bisa mendapatkannya dengan id dari cache. Itu akan mudah tetapi juga tidak layak untuk disimpan dalam cache. Tetapi bagaimana jika saya ingin melakukan perhitungan dengan semua pelanggan saya. Misalkan saya ingin menampilkan daftar pelanggan, lalu bagaimana saya mengaksesnya?
  • Bagaimana cara mendapatkan semua pelanggan saya jika cache kueri dinonaktifkan?
  • Apa yang akan terjadi jika seseorang memperbarui salah satu pelanggan?
    • Akankah pelanggan itu menjadi tidak valid dalam cache atau apakah semua pelanggan akan dibatalkan?

Atau apakah saya berpikir cache salah? Apa penggunaan yang lebih tepat dari cache tingkat kedua dalam kasus itu? Dokumentasi hibernate sama sekali tidak jelas bagaimana cache bekerja pada kenyataannya. Hanya ada instruksi tentang cara menyiapkannya.

Pembaruan: Jadi saya telah memahami bahwa cache tingkat kedua (tanpa cache kueri) akan baik untuk memuat data dengan id. Misalnya saya memiliki objek pengguna yang ingin saya periksa izinnya di setiap permintaan dalam aplikasi web. Apakah ini kasus yang baik untuk mengurangi akses database dengan menyimpan pengguna dalam cache tingkat kedua? Seperti saya akan menyimpan id pengguna dalam sesi atau di mana pun dan ketika saya perlu memeriksa izin, saya akan memuat pengguna dengan id itu dan memeriksa izin.

palto
sumber
kemungkinan duplikat dari Apakah cache tingkat kedua dalam hibernasi?
Don Roby

Jawaban:

101

Pertama-tama, mari kita bicara tentang cache level proses (atau cache level 2 sebagaimana mereka menyebutnya dalam mode Hibernate). Untuk membuatnya berhasil, Anda harus melakukannya

  1. konfigurasikan penyedia cache
  2. beri tahu hibernate entitas apa yang akan disimpan dalam cache (langsung di file hbm.xml jika Anda menggunakan pemetaan semacam ini).

Anda memberi tahu penyedia cache berapa banyak objek yang harus disimpan dan kapan / mengapa objek tersebut harus dibatalkan. Jadi katakanlah Anda memiliki entitas Buku dan Penulis, setiap kali Anda mendapatkannya dari DB, hanya yang tidak ada dalam cache yang akan dipilih dari DB sebenarnya. Ini meningkatkan kinerja secara signifikan. Berguna bila:

  • Anda menulis ke database hanya melalui Hibernate (karena perlu cara untuk mengetahui kapan harus mengubah atau membatalkan entitas di cache)
  • Anda sering membaca objek
  • Anda memiliki satu node, dan Anda tidak memiliki replikasi. Jika tidak, Anda harus mereplikasi cache itu sendiri (gunakan cache terdistribusi seperti JGroups) yang menambahkan lebih banyak kerumitan, dan itu tidak berskala sebaik aplikasi tanpa berbagi.

Jadi kapan cache berfungsi?

  • Saat Anda session.get()atau session.load()objek yang sebelumnya dipilih dan berada di cache. Cache adalah penyimpanan di mana ID adalah kuncinya dan propertinya adalah nilainya. Jadi hanya ketika ada kemungkinan untuk mencari berdasarkan ID Anda bisa menghilangkan memukul DB.
  • Saat pengaitan Anda dimuat dengan lambat (atau dimuat dengan pilihan, bukan gabungan)

Tapi itu tidak berhasil jika:

  • Jika Anda tidak memilih berdasarkan ID. Sekali lagi - cache tingkat 2 menyimpan peta ID entitas ke properti lain (sebenarnya tidak menyimpan objek, tetapi datanya sendiri), jadi jika pencarian Anda terlihat seperti ini:, from Authors where name = :namemaka Anda tidak menekan cache.
  • Saat Anda menggunakan HQL (bahkan jika Anda menggunakan where id = ?).
  • Jika dalam pemetaan yang Anda tetapkan fetch="join", ini berarti bahwa untuk memuat asosiasi, gabungan akan digunakan di mana saja, bukan pernyataan pilih yang terpisah. Cache tingkat proses bekerja pada objek anak-anak hanya jika fetch="select"digunakan.
  • Bahkan jika Anda memiliki fetch="select"tetapi kemudian di HQL Anda menggunakan gabungan untuk memilih asosiasi - gabungan tersebut akan segera dikeluarkan dan mereka akan menimpa apa pun yang Anda tentukan di hbm.xml atau penjelasan.

Sekarang, tentang Query Cache. Anda harus mencatat bahwa ini bukan cache terpisah, ini adalah tambahan untuk cache tingkat proses. Misalkan Anda memiliki entitas Negara. Ini statis, jadi Anda tahu bahwa setiap kali akan ada hasil yang sama yang ditetapkan saat Anda mengatakannya from Country. Ini adalah kandidat yang tepat untuk cache kueri, ini akan menyimpan daftar ID itu sendiri dan ketika Anda memilih semua negara di lain waktu, ini akan mengembalikan daftar ini ke cache tingkat proses dan yang terakhir, pada gilirannya, akan mengembalikan objek untuk setiap ID karena objek ini sudah disimpan di cache tingkat ke-2. Cache kueri tidak valid setiap kali apa pun yang terkait dengan entitas berubah. Jadi katakanlah Anda mengonfigurasi from Authorsuntuk ditempatkan ke dalam Cache Kueri. Ini tidak akan efektif karena Penulis sering berubah.

Stanislav Bashkyrtsev
sumber
Apakah kueri "dari Penulis a fetch bergabung dengan a.books" memerlukan cache Kueri untuk mengambil penulis dari cache?
Palto
1
Tidak, cache kueri hanya untuk data statis dan hanya menyimpan ID. Penulis akan diambil dari cache tingkat 2.
Stanislav Bashkyrtsev
@ctapobep: tidak benar apa yang kamu katakan! "dari Penulis, ambil ambil, gabung a.books" berfungsi dengan baik jika buku lapangan entitas Penulis dianotasi (ambil EAGER) ... sudah terlambat menurut saya
Bilal BBB
Jawaban yang sangat bagus! Saya akan mengingatnya sepanjang waktu! : d
Mohammadreza Khatami
setelah mengaktifkan 'query cache', apakah itu mengambil data dari cache jika Anda memilih dengan properti selain id?
Arun Raaj
42
  • cache tingkat ke-2 adalah penyimpanan nilai kunci. Ini hanya berfungsi jika Anda mendapatkan entitas Anda dengan id
  • cache tingkat 2 tidak valid / diperbarui per entitas saat entitas diperbarui / dihapus melalui hibernasi. Itu tidak valid jika database diperbarui dengan cara yang berbeda.
  • untuk kueri (mis. daftar pelanggan) gunakan cache kueri.

Pada kenyataannya, memiliki cache terdistribusi nilai-kunci sangatlah berguna - itulah yang dimaksud dengan memcache, dan ini mendukung facebook, twitter, dan banyak lagi. Tetapi jika Anda tidak memiliki pencarian berdasarkan id, maka itu tidak akan berguna.

Bozho
sumber
12

Terlambat ke pesta tetapi ingin menjawab secara sistematis pertanyaan ini yang banyak ditanyakan oleh pengembang.

Mengajukan pertanyaan Anda satu per satu di sini adalah jawaban saya.

Q. Kapan hibernate mencapai cache ini?

A. Cache Tingkat Pertama dikaitkan dengan objek Sesi . The Second Level Cache dikaitkan dengan objek Session Factory . Jika objek tidak ditemukan di tingkat pertama, maka tingkat kedua diperiksa.

P. Katakanlah saya telah menyiapkan cache tingkat kedua tetapi bukan cache kueri. Saya ingin menyimpan cache pelanggan saya, ada 50000 dari mereka. Dengan cara apa saya bisa mengambil pelanggan dari cache?

A. Jawabannya ada di update Anda. Juga cache kueri menyimpan hanya daftar ID dari objek dan Objek tersebut dengan ID mereka disimpan dalam cache tingkat kedua yang sama . Jadi, jika Anda mengaktifkan cache kueri, Anda akan menggunakan sumber daya yang sama. Benar kan?

P. Saya berasumsi bahwa saya bisa mendapatkannya dengan id dari cache. Itu akan mudah tetapi juga tidak layak untuk disimpan dalam cache. Tetapi bagaimana jika saya ingin melakukan perhitungan dengan semua pelanggan saya. Misalkan saya ingin menampilkan daftar pelanggan, lalu bagaimana saya mengaksesnya?

A. Dijawab di atas.

T. Bagaimana cara mendapatkan semua pelanggan saya jika cache kueri dinonaktifkan?

A. Dijawab di atas.

T. Apa yang akan terjadi jika seseorang memperbarui salah satu pelanggan? Akankah pelanggan itu menjadi tidak valid dalam cache atau apakah semua pelanggan akan dibatalkan?

A. Hibernate tidak tahu apa-apa tetapi Anda dapat menggunakan cache IMDG / terdistribusi pihak ketiga lainnya untuk diimplementasikan sebagai cache tingkat kedua hibernasi dan membuatnya tidak valid. misalnya TayzGrid adalah salah satu produk tersebut dan saya kira masih ada lagi.

Basit Anwer
sumber
0

Cache tingkat kedua Hibernate agak rumit untuk dipahami dan diterapkan. Inilah yang dapat kami katakan berdasarkan pertanyaan Anda:

Kapan Hibernate mencapai cache ini?

Seperti yang Anda sarankan, cache Hibernate L2 (jika diaktifkan; tidak diaktifkan secara default) hanya ditanyakan setelah cache L1. Ini adalah cache nilai kunci yang datanya disimpan di beberapa sesi.

Katakanlah saya telah menyiapkan cache tingkat kedua tetapi bukan cache kueri. Saya ingin menyimpan cache pelanggan saya, ada 50000 dari mereka. Dengan cara apa saya bisa mengambil pelanggan dari cache?

Cache kueri akan menjadi pilihan terbaik untuk kasus penggunaan ini, karena data pelanggan bersifat statis dan diambil dari database relasional.

Apa yang akan terjadi jika seseorang memperbarui salah satu pelanggan? Akankah pelanggan itu menjadi tidak valid dalam cache atau apakah semua pelanggan akan dibatalkan?

Itu tergantung pada strategi cache Hibernate spesifik yang Anda gunakan. Hibernate sebenarnya memiliki empat strategi cache yang berbeda:

READ_ONLY : Objek tidak berubah sekali di dalam cache.

NONSTRICT_READ_WRITE : Objek berubah (akhirnya) setelah entri database yang sesuai diperbarui; ini menjamin konsistensi akhirnya.

READ_WRITE : Objek berubah (segera) setelah entri database yang sesuai diperbarui; ini menjamin konsistensi yang kuat dengan menggunakan kunci "lunak".

TRANSAKSI : Objek berubah menggunakan transaksi XA terdistribusi, memastikan integritas data; ini menjamin kesuksesan total atau mengembalikan semua perubahan. Namun, dalam keempat kasus ini, memperbarui satu entri database tidak akan membatalkan seluruh daftar pelanggan di cache. Hibernate sedikit lebih pintar dari itu :)

Untuk mempelajari lebih lanjut tentang cara kerja cache L2 dalam Hibernate, Anda dapat melihat artikel "Apa itu cache Hibernate L2," atau artikel mendalam Caching dalam Hibernate dengan Redis

Nikita Koksharov
sumber