Proyek Java sumber terbuka: Sistem Caching Java

Spesialis Java Enterprise Steve Haines bergabung dalam rangkaian proyek Java Open source bulan ini dengan pengenalan Java Caching System (JCS), solusi cache tingkat perusahaan yang tangguh. Steve memulai dengan pengenalan singkat tentang caching, membahas kriteria untuk menentukan apakah objek harus di-cache dan apakah aplikasi Anda akan mendapatkan keuntungan dari cache. Dia kemudian menunjukkan kepada Anda bagaimana mengkonfigurasi JCS dan menggunakannya untuk membangun aplikasi caching.

Java Caching System (JCS) adalah produk caching open source yang kuat yang dirilis melalui subproyek Apache Jakarta. Ini menyediakan fitur standar yang Anda harapkan dari sistem cache, seperti cache dalam memori dan algoritma untuk menghapus objek secara selektif dari cache. Ia juga menawarkan fitur yang lebih canggih, seperti cache disk yang diindeks dan dukungan untuk cache terdistribusi.

Cache JCS memiliki struktur seperti peta di mana data disimpan dalam cache sebagai pasangan nama-dan-nilai. JCS mempartisi cache menjadi beberapa region . Setiap kawasan memiliki konfigurasinya sendiri serta kumpulan pasangan nama-nilai sendiri. Setiap wilayah dapat:

  • Berukuran berbeda
  • Diimplementasikan secara berbeda
  • Berisi data yang berbeda

The kunci (nama-nama dalam pasangan nama-dan-nilai) di satu wilayah bisa sama sebagai kunci di daerah lain. Ini penting karena memungkinkan Anda mempertahankan cache terpisah untuk objek yang berbeda, semuanya dalam JVM yang sama - dan semuanya ditentukan dalam satu file properti.

Lisensi sumber terbuka

Setiap proyek Java open source yang tercakup dalam seri ini tunduk pada lisensi, yang harus Anda pahami sebelum mengintegrasikan proyek dengan proyek Anda sendiri. JCS tunduk pada Lisensi Apache; lihat Sumberdaya untuk mempelajari lebih lanjut.

Artikel ini membahas JCS dengan menunjukkan cara mendapatkan dan menginstal rilis saat ini terlebih dahulu. Saya kemudian akan menjelaskan apa itu cache, mengapa Anda mungkin menggunakannya, dan apakah itu solusi yang tepat untuk aplikasi tertentu atau tidak. Selanjutnya, Anda akan mempelajari file properti JCS, yang merupakan rute terbaik untuk memahami JCS. Terakhir, Anda akan membuat contoh aplikasi cache yang menggunakan JCS.

Mulailah dengan JCS

Anda dapat mengunduh JCS dari halaman unduhan situs proyek JCS. Pada tulisan ini, versi terbaru adalah 1.3. Unduh distribusi biner (baik sebagai file TAR di sistem Unix atau file ZIP di Windows) dan dekompresi ke direktori lokal di komputer Anda.

Akar dari direktori instalasi berisi jcs-1.3.jar, yang harus Anda tambahkan CLASSPATHsebelum mengkompilasi dan menjalankan aplikasi JCS.

Tambang emas dokumentasi kelas

Sepanjang artikel ini, serta dalam studi independen Anda sendiri, Anda akan menemukan bahwa docsdirektori JCS adalah sumber informasi yang sangat berharga untuk informasi tentang JCS, termasuk dokumentasi API. Dokumen Javadoc yang kuat adalah kewenangan Anda untuk memahami cara menggunakan kelas JCS.

Anda membutuhkan dua dependensi:

  • Commons Logging
  • Concurrent

Dari Commons Logging, tambahkan commons-logging.jarke file CLASSPATH.

Primer caching cepat

Cache dirancang untuk menampung objek, biasanya dalam memori, untuk akses langsung oleh aplikasi. Sebuah aplikasi berinteraksi secara berbeda dengan cache dari caranya berinteraksi dengan solusi penyimpanan eksternal. Biasanya, aplikasi mendapatkan koneksi ke database, menjalankan kueri di seluruh jaringan, dan mengurai hasil saat dikembalikan. Cache memelihara kumpulan objek yang tersedia dalam struktur mirip peta yang kokoh yang tidak memerlukan panggilan jaringan. Kinerja aplikasi Enterprise Java meningkat secara eksponensial saat mengakses objek yang dapat digunakan kembali dalam cache setelah memuatnya dari database, daripada melakukan panggilan database jarak jauh.

Jika aplikasi Anda memiliki sejumlah objek yang dapat dikelola yang sering diakses, cache mungkin dapat meningkatkan kinerjanya. Aplikasi Java dibatasi oleh sumber daya yang tersedia di JVM, yang paling berharga adalah memori. Tidak masuk akal untuk mengambil memori dari JVM untuk menyimpan objek yang jarang diakses. Mungkin lebih baik memuat objek yang diakses setiap beberapa jam sekali jika diperlukan dan menyisakan memori kosong yang cukup untuk sumber daya lain. Di sisi lain, lebih baik memuat objek yang diakses beberapa kali dalam satu menit - atau bahkan beberapa kali dalam satu jam - ke dalam cache dan menyajikannya dari memori, daripada membuat panggilan jarak jauh setiap kali objek tersebut dibutuhkan. Jika jumlah objek yang sering diakses aplikasi Anda dapat dikelola dalam memori yang tersedia,maka itu adalah kandidat yang baik untuk penyimpanan ke cache. Tetapi jika mengaksesjutaan objek secara berkala, maka mungkin merupakan kepentingan terbaik aplikasi untuk memuat objek sesuai kebutuhan daripada menggunakan 75 persen dari heap JVM untuk menghosting cache.

Caching versus pooling

Kebingungan tentang perbedaan antara cache dan kumpulan sering muncul dalam diskusi tentang cache. Objek mana yang harus di-cache dan objek apa yang harus dikumpulkan? Jawabannya terletak pada sifat objek itu sendiri. Jika sebuah objek mempertahankan status, itu harus di-cache. Objek tanpa status harus dikumpulkan. Sebagai analogi, pertimbangkan dua aktivitas: membeli makanan di supermarket dan menjemput anak dari sekolah. Kasir mana pun dapat memeriksa pelanggan mana pun di supermarket; tidak masalah kasir mana yang Anda dapatkan, jadi kasir harus dikumpulkan. Ketika Anda menjemput anak Anda dari sekolah, Anda menginginkan anak Anda , bukan milik orang lain, jadi anak-anak harus disimpan dalam cache.

Mengekstrapolasi gagasan ini ke perusahaan Java, sumber daya seperti koneksi database dan biji pemrosesan bisnis harus dikumpulkan, sedangkan objek seperti karyawan, dokumen, dan widget harus di-cache. Tidak masalah koneksi database mana yang diperoleh aplikasi Anda dari kumpulan koneksi - semuanya melakukan hal yang sama - tetapi jika Anda ingin menaikkan gaji Anda sendiri, penting bagi Anda untuk mendapatkan objek karyawan Anda .

Memahami wilayah JCS

Menggunakan JCS sebenarnya cukup sederhana, tetapi Anda memerlukan pengetahuan dasar tentang bagaimana JCS mendefinisikan wilayah cache dan bagaimana mereka dapat dikonfigurasi. File properti JCS adalah tempat logis untuk mulai memahami JCS. Kode 1 menunjukkan contoh file properti JCS.

Daftar 1. File properti JCS (cache.ccf)

# DEFAULT CACHE REGION jcs.default=DC jcs.default.cacheattributes= org.apache.jcs.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects=1000 jcs.default.cacheattributes.MemoryCacheName= org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.default.cacheattributes.UseMemoryShrinker=true jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=3600 jcs.default.cacheattributes.ShrinkerIntervalSeconds=60 jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes jcs.default.elementattributes.IsEternal=false jcs.default.elementattributes.MaxLifeSeconds=21600 jcs.default.elementattributes.IdleTime=1800 jcs.default.elementattributes.IsSpool=true jcs.default.elementattributes.IsRemote=true jcs.default.elementattributes.IsLateral=true # PREDEFINED CACHE REGIONS jcs.region.musicCache=DC jcs.region.musicCache.cacheattributes= org.apache.jcs.engine.CompositeCacheAttributes jcs.region.musicCache.cacheattributes.MaxObjects=1000 jcs.region.musicCache.cacheattributes.MemoryCacheName= org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.region.musicCache.cacheattributes.UseMemoryShrinker=true jcs.region.musicCache.cacheattributes.MaxMemoryIdleTimeSeconds=3600 jcs.region.musicCache.cacheattributes.ShrinkerIntervalSeconds=60 jcs.region.musicCache.cacheattributes.MaxSpoolPerRun=500 jcs.region.musicCache.elementattributes= org.apache.jcs.engine.ElementAttributes jcs.region.musicCache.elementattributes.IsEternal=false # AVAILABLE AUXILIARY CACHES jcs.auxiliary.DC= org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory jcs.auxiliary.DC.attributes= org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes jcs.auxiliary.DC.attributes.DiskPath=c:/temp jcs.auxiliary.DC.attributes.MaxPurgatorySize=10000000 jcs.auxiliary.DC.attributes.MaxKeySize=1000000 jcs.auxiliary.DC.attributes.MaxRecycleBinSize=5000 jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount=300000 jcs.auxiliary.DC.attributes.ShutdownSpoolTimeLimit=60

Daftar 1 berisi tiga bagian:

  • Region default menentukan konfigurasi default untuk semua region kecuali jika diganti secara eksplisit oleh salah satu region lain.
  • Berikutnya adalah daftar wilayah cache yang telah ditentukan sebelumnya (yaitu, ditentukan pengguna), yang dalam hal ini mencakup musicCacheyang akan saya gunakan dalam contoh yang akan datang.
  • Cache bantu menentukan alat bantu yang dapat dicolokkan ke wilayah cache. Meskipun setiap wilayah cache harus memiliki satu (dan hanya satu) tambahan memori, ia dapat memiliki sejumlah tambahan lain yang dapat menyimpan data yang disimpan dalam cache. Dalam contoh ini saya membuat cache disk yang diindeks, tetapi Anda juga dapat menentukan bantu lateral dan jarak jauh . Tambahan lateral dapat mereplikasi data cache Anda ke cache lain melalui soket TCP atau tumpukan protokol JGroups. Alat bantu jarak jauh dapat mereplikasi data ke cache lain melalui Remote Method Invocation (RMI).

Setiap wilayah dapat menentukan atribut cache serta atribut elemen . Atribut cache mendefinisikan opsi konfigurasi untuk cache, sedangkan atribut elemen mendefinisikan opsi konfigurasi untuk elemen dalam cache. Berikut ringkasan opsi atribut cache:

  • MaxObjects: Ini adalah jumlah maksimum objek yang diperbolehkan dalam memori.
  • MemoryCacheName: Properti ini memungkinkan Anda untuk menentukan pengelola memori yang akan digunakan sebagai milik Anda MemoryCache. Manajer memori default mengimplementasikan strategi LRU.
  • UseMemoryShrinker: Opsi ini memungkinkan JCS untuk mengulangi cache secara berkala, mencari objek yang dapat dihapus (item yang telah kedaluwarsa atau telah melebihi waktu idle memori maksimumnya). Nilai defaultnya adalah false.
  • MaxMemoryIdleTimeSeconds: Jika penyingkat memori diaktifkan, properti ini memberi tahu JCS berapa lama sebuah objek dapat tetap menganggur sebelum shrinker menghapusnya (dan menggulung ke disk jika cache disk yang diindeks telah dibuat). Nilai defaultnya adalah -1, yang menonaktifkan opsi ini.
  • ShrinkerIntervalSeconds: Jika penyingkat memori diaktifkan, properti ini memberi tahu JCS seberapa sering menjalankan penyingkat. Nilai defaultnya adalah 60 detik.
  • DiskUsagePattern: Jika cache disk diaktifkan, properti ini memberi tahu JCS cara menyimpan data saat cache memori penuh. Nilai defaultnya adalah SWAP, yang menggulung item ke disk hanya jika cache memori penuh. Opsi lainnya adalah UPDATE, yang menyimpan semua data ke disk, tetapi hanya jika data diperbarui. Jika alat bantu JDBC telah ditetapkan sebagai cache disk, semua objek tetap berada di memori (hingga memori penuh) dan juga disimpan ke database, yang menyediakan kinerja dan keandalan yang baik.

Dan berikut adalah opsi atribut elemen:

  • IsEternal: Jika suatu elemen bersifat kekal maka tidak dapat dihapus dari cache karena melebihi umur maksimumnya. Opsi ini secara default true.
  • MaxLifeSeconds: Jika elemen tidak abadi, opsi ini menentukan umur maksimum setiap objek sebelum dihapus. Jika penyingkat memori sedang berjalan, objek akan dihapus oleh penyingkat; jika tidak, mereka akan dihapus saat diakses. Opsi ini ditetapkan secara default -1, yang menonaktifkan opsi.
  • IsSpool: Opsi ini menentukan apakah sebuah elemen dapat di-spooling ke disk atau tidak. Ini defaultnya true.
  • IsLateral: Opsi ini menentukan apakah suatu elemen dapat dikirim ke cache lateral atau tidak. Ini defaultnya true.
  • IsRemote: Opsi ini menentukan apakah suatu elemen dapat dikirim ke cache jarak jauh atau tidak. Default-nya adalah true.

In Listing 1, I created a region named musicCache that holds up to 1,000 items in memory. Its memory manager uses a LRU algorithm: when the cache is full and JCS needs to make room for new items, it will remove items that have not been recently accessed. It has the memory shrinker enabled, and the shrinker will run every 60 seconds. It will evict items that sit idle for more than 60 minutes (3,600 seconds.) Its items are not eternal, and they can be written out to disk, to a lateral cache, or to a remote cache.

Note that the IsSpool, IsLateral, and IsRemote settings are inherited from the default settings. Because the jcs.region.musicCache element is set to DC, it is defined not only to maintain an in-memory cache, but also to use the indexed disk cache as an auxiliary. (The property can be set to a comma-separated list of multiple auxiliaries.) The disk cache is configured to store items in the c:/temp directory. (JCS prefers forward slashes to backslashes.) The remaining attributes configure the disk cache using an IndexedDiskCacheAttribute object; you can read about these attributes in the JCS Javadoc.

Building a sample caching application

Once you understand how to configure JCS, building a caching application is straightforward. The application needs to be able to:

  • Initialize the cache from its configuration file
  • Access a region in the cache
  • Muat objek ke dalam cache
  • Ambil objek dari cache
  • Hapus objek dari cache

Cache dapat diinisialisasi secara otomatis atau manual. Jika Anda memberi nama file konfigurasi Anda cache.ccfdan meletakkannya langsung di CLASSPATH(seperti direktori root build Anda), maka pertama kali JCS dipanggil, ia menemukan file tersebut dan menginisialisasi dengan tepat. Jika Anda perlu menyimpan file konfigurasi Anda di tempat lain atau menamainya berbeda, Anda dapat menggunakan org.apache.jcs.utils.props.PropertyLoader's loadProperties()metode untuk memuat properti JCS dari file properti apa pun.