Pertanyaan Kapan dan bagaimana menggunakan cache tingkat kedua hibernate?


Saya kesulitan memahami saat hibernate menyentuh cache level kedua dan kapan itu membatalkan cache.

Inilah yang saya pahami saat ini:

  • Penyimpanan tingkat kedua menyimpan entitas di antara sesi, ruang lingkup adalah SessionFactory
  • Anda harus memberi tahu entitas mana yang harus di-cache, tidak ada entitas yang akan di-cache secara default
  • Query cache menyimpan hasil query di cache.

Yang saya tidak mengerti adalah

  • Kapan hibernate menghantam cache ini?
  • Katakanlah saya telah menyiapkan cache level kedua tetapi bukan cache query. Saya ingin men-cache pelanggan saya, ada 50000 dari mereka. Dengan cara apa saya dapat mengambil pelanggan dari cache?
  • Saya berasumsi saya bisa mendapatkannya dari id dari cache. Itu akan mudah tetapi juga tidak layak untuk di-cache. Tetapi bagaimana jika saya ingin melakukan perhitungan dengan semua pelanggan saya. Katakanlah saya ingin menunjukkan daftar pelanggan lalu bagaimana cara saya mengaksesnya?
  • Bagaimana saya akan mendapatkan semua pelanggan saya jika query caching dinonaktifkan?
  • Apa yang akan terjadi jika seseorang memperbarui salah satu pelanggan?
    • Apakah pelanggan itu akan batal dalam cache atau apakah semua pelanggan menjadi batal?

Atau apakah saya berpikir cache benar-benar salah? Apa gunanya penggunaan cache level kedua dalam kasus itu? Dokumentasi hibernate sama sekali tidak jelas bagaimana cache bekerja dalam kenyataan. Hanya ada instruksi tentang cara menyiapkannya.

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


75
2017-08-14 18:34


asal


Jawaban:


Pertama-tama, mari kita bicara tentang cache level proses (atau cache level 2 saat mereka menyebutnya di Hibernate). Agar berhasil, Anda harus

  1. konfigurasikan penyedia cache
  2. beri tahu hibernate entitas apa yang harus di-cache (tepat di file hbm.xml jika Anda menggunakan pemetaan semacam ini).

Anda memberi tahu penyedia cache berapa banyak objek yang harus disimpan dan kapan / mengapa mereka harus disegarkan. Jadi, katakanlah Anda memiliki entitas Buku dan Pembuat, setiap kali Anda mendapatkannya dari DB, hanya yang tidak dalam cache yang akan dipilih dari DB sebenarnya. Ini meningkatkan kinerja secara signifikan. Ini berguna ketika:

  • Anda menulis ke database hanya melalui Hibernate (karena perlu cara untuk mengetahui kapan harus mengubah atau membatalkan entitas dalam cache)
  • Anda sering membaca objek
  • Anda memiliki satu simpul, 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 menskalakan sebagus aplikasi share-nothing.

Jadi kapan cache bekerja?

  • Ketika kamu session.get() atau session.load() objek yang sebelumnya dipilih dan berada dalam cache. Cache adalah penyimpanan tempat ID adalah kunci dan properti adalah nilainya. Jadi hanya ketika ada kemungkinan untuk mencari berdasarkan ID, Anda dapat menghilangkan klik pada DB.
  • Ketika asosiasi Anda malas dimuat (atau penuh dengan pilihan, bukannya bergabung)

Tetapi tidak berhasil ketika:

  • Jika Anda tidak memilih dengan 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 = :name, maka Anda tidak menekan cache.
  • Ketika Anda menggunakan HQL (bahkan jika Anda menggunakan where id = ?).
  • Jika dalam pemetaan Anda yang Anda tetapkan fetch="join", ini berarti bahwa untuk memuat asosiasi bergabung akan digunakan di mana saja daripada pernyataan pilih terpisah. Cache level proses bekerja pada objek anak-anak hanya jika fetch="select" digunakan.
  • Bahkan jika kamu punya fetch="select" tetapi kemudian di HQL Anda menggunakan gabungan untuk memilih asosiasi - mereka yang bergabung akan dikeluarkan segera dan mereka akan menimpa apa pun yang Anda tentukan di hbm.xml atau anotasi.

Sekarang, tentang Query Cache. Anda harus mencatat bahwa itu bukan cache terpisah, ini merupakan tambahan untuk cache level proses. Katakanlah Anda memiliki entitas Negara. Ini statis, jadi Anda tahu bahwa setiap kali akan ada hasil yang sama ketika Anda katakan from Country. Ini adalah kandidat sempurna untuk cache query, itu akan menyimpan daftar ID sendiri dan ketika Anda lain waktu pilih semua negara, itu akan mengembalikan daftar ini ke cache level proses dan yang terakhir, pada gilirannya, akan mengembalikan objek untuk setiap ID karena objek-objek ini sudah disimpan dalam cache tingkat ke-2. Cache query tidak berlaku setiap kali ada sesuatu yang terkait dengan perubahan entitas. Jadi katakanlah Anda dikonfigurasi from Authors untuk ditempatkan ke dalam Query Cache. Ini tidak akan efektif karena Penulis sering berubah. Jadi Anda harus menggunakan Query Cache hanya untuk lebih atau kurang data statis.


80
2017-08-14 21:23



  • cache level 2 adalah penyimpanan kunci-nilai. Ini hanya berfungsi jika Anda mendapatkan entitas Anda berdasarkan id
  • cache level 2 tidak valid / diperbarui per entitas ketika entitas diperbarui / dihapus melalui hibernate. Ini tidak batal jika database diperbarui dengan cara yang berbeda.
  • untuk kueri (mis. daftar pelanggan) menggunakan cache kueri.

Kenyataannya adalah berguna untuk memiliki cache terdistribusi nilai kunci - itulah yang memcache, dan itu memperkuat facebook, twitter dan banyak lagi. Tetapi jika Anda tidak memiliki pencarian berdasarkan id, maka itu tidak akan sangat berguna.


32
2017-08-14 18:52



Terlambat ke pesta tetapi ingin secara sistematis menjawab pertanyaan yang banyak diminta oleh para pengembang.

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

Q. Kapan hibernate menghantam cache ini?

SEBUAH. Cache Tingkat Pertama dikaitkan dengan Objek sesi. Itu Cache Tingkat Kedua dikaitkan dengan Objek Pabrik Sesi. Jika objek tidak ditemukan di tempat pertama, maka tingkat kedua dicentang.

Q. Katakanlah saya telah mengatur cache level kedua tetapi bukan cache query. Saya ingin men-cache pelanggan saya, ada 50000 dari mereka. Dengan cara apa saya dapat mengambil pelanggan dari cache?

A. Anda mendapat jawabannya dalam pembaruan Anda. Juga cache query hanya menyimpan daftar ID objek dan Objek-objek tersebut dengan ID mereka disimpan di sama cache tingkat kedua. Jadi jika Anda mengaktifkan cache query, Anda akan menggunakan sumber daya yang sama. Rapi benar?

P. Saya berasumsi saya bisa mendapatkannya dari cache. Itu akan mudah tetapi juga tidak layak untuk di-cache. Tetapi bagaimana jika saya ingin melakukan perhitungan dengan semua pelanggan saya. Katakanlah saya ingin menunjukkan daftar pelanggan lalu bagaimana cara saya mengaksesnya?

A. Dijawab di atas.

Q. Bagaimana saya akan mendapatkan semua pelanggan saya jika query caching dinonaktifkan?

A. Dijawab di atas.

Q. Apa yang akan terjadi jika seseorang memperbarui salah satu pelanggan? Apakah pelanggan itu akan batal dalam cache atau apakah semua pelanggan menjadi batal?

A. Hibernate tidak memiliki ide tetapi Anda bisa menggunakan cache pihak ketiga IMDG / didistribusikan lain untuk diimplementasikan sebagai hibernate cache tingkat kedua dan membuat mereka batal. misalnya TayzGrid adalah salah satu produk tersebut dan ada lebih banyak yang saya kira.


10
2017-12-17 09:59