API cache Objek Java Ringan [ditutup]

99

Pertanyaan

Saya mencari API cache objek dalam memori Java. Ada rekomendasi? Solusi apa yang Anda gunakan di masa lalu?

Arus

Saat ini, saya hanya menggunakan Peta:

Map cache = new HashMap<String, Object>();
cache.put("key", value);

Persyaratan

Saya perlu memperluas cache untuk memasukkan fitur-fitur dasar seperti:

  • Ukuran maksimal
  • Waktunya untuk hidup

Namun, saya tidak membutuhkan fitur yang lebih canggih seperti:

  • Akses dari banyak proses (caching server)
  • Persistensi (ke disk)

Saran

Cache dalam Memori:

  • Guava CacheBuilder - pengembangan aktif. Lihat presentasi ini .
  • LRUMap - Konfigurasi melalui API. Tidak ada TTL. Tidak dibuat khusus untuk penyimpanan dalam cache.
  • whirlycache - konfigurasi XML. Milis. Terakhir diperbarui tahun 2006.
  • cache4j - konfigurasi XML. Dokumentasi dalam bahasa Rusia. Terakhir diperbarui tahun 2006.

Caching perusahaan:

  • JCS - Konfigurasi properti. Dokumentasi yang ekstensif.
  • Ehcache - konfigurasi XML. Dokumentasi yang ekstensif. Sejauh ini yang paling populer menurut Google hits.
Chase Seibert
sumber
3
Dapatkah Anda mengedit bagian Saran dalam Cache Memori untuk menyertakan Cache Jambu? Saya sedang mencari mekanisme caching ringan seperti Anda, dan menemukan pertanyaan ini, tetapi tidak menemukan Guava karena cara itu turun. Sekarang saya menggunakan paket cache jambu biji, dan itu LUAR BIASA.
andras
1
Selesai. :-) Sangat senang Anda menyukainya!
Kevin Bourrillion
Mungkin Anda juga ingin mempertimbangkan untuk menambahkan cache2k yang relatif baru . Pada halaman benchmark mereka dikatakan bahwa ini memiliki kinerja yang jauh lebih baik daripada ehcache dan Guava.
pengguna3001

Jawaban:

57

EHCache sangat bagus. Anda dapat membuat cache di memori. Lihat contoh kode mereka untuk contoh pembuatan cache di memori. Anda dapat menentukan ukuran maksimal, dan waktu untuk hidup.

EHCache memang menawarkan beberapa fitur lanjutan, tetapi jika Anda tidak tertarik untuk menggunakannya - jangan. Tapi senang mengetahui mereka ada di sana jika kebutuhan Anda berubah.

Ini adalah cache di memori. Dibuat dalam kode, tanpa file konfigurasi.

CacheManager cacheManager = CacheManager.getInstance();
int oneDay = 24 * 60 * 60;
Cache memoryOnlyCache = new Cache("name", 200, false, false, oneDay, oneDay);
cacheManager.addCache(memoryOnlyCache);

Membuat cache yang akan menampung 200 elemen, dan memiliki ttl 24 jam.

Steve K
sumber
2
Apakah EHCache hanya mengacu pada objek atau serialisasi dan kemudian deserialisasi objek sebagai gantinya?
Phương Nguyễn
2
Apakah EHCache merupakan solusi kelas berat? Kami sedang mencari solusi cache yang ada untuk mengimplementasikan cache API di Android.
Matthias
2
Ini terlalu berat untuk Android. Saya menggunakan cache Kitty dan itu sangat sempurna!
Felipe
@Stevet K, saya terlambat mengetahui teknologi Cache ini, tetapi saya kira getInstance () telah dihapus atau diubah.
Menai Ala Eddine - Aladdin
46

Saya sangat suka MapMakeryang dilengkapi dengan Google Guava ( API )

JavaDoc memiliki contoh yang cukup rapi yang menunjukkan kemudahan penggunaan dan kekuatannya:

ConcurrentMap<Key, Graph> graphs = new MapMaker()
   .concurrencyLevel(32)
   .softKeys()
   .weakValues()
   .expiration(30, TimeUnit.MINUTES)
   .makeComputingMap(
       new Function<Key, Graph>() {
         public Graph apply(Key key) {
           return createExpensiveGraph(key);
         }
       });

Selanjutnya, melepaskan 10,0 Guava memperkenalkan lebih luas com.google.common.cachepaket (ada entri wiki yang bagus tentang cara menggunakannya ).

Joachim Sauer
sumber
@mxttie: terima kasih, saya telah menambahkan tautan, silakan menyarankan pengeditan untuk tambahan seperti ini.
Joachim Sauer
10

Anda juga dapat melihat pustaka cache kecil saya yang disebut KittyCache di:

https://github.com/treeder/kitty-cache

Ada beberapa tolok ukur kinerja vs ehcache.

Ini digunakan dalam proyek SimpleJPA sebagai cache tingkat kedua.

Travis Reeder
sumber
1
Bagus, tapi kalau saja ada TTL.
Rosdi Kasim
Terima kasih! hanya kode yang saya ketikkan sebelum saya berpikir untuk memeriksa apakah seseorang telah membuka sesuatu bersumber :)
jpillora
@RosdiKasim memang memiliki TTL sebenarnya pada panggilan put (), misalnya: cache.put ("mykey", value, 500); 500 adalah TTL.
Travis Reeder
1
@TravisR Yah ..., saat itu tidak ada TTL ..: p
Rosdi Kasim
Ahh, tidak menyadari sudah berapa lama komentar itu.
Travis Reeder
9

Anda dapat memeriksa LinkedHashMap untuk mengimplementasikan cache sederhana tanpa jars pihak ketiga:

    Map <String, Foo> cache = new LinkedHashMap<String, Foo>(MAX_ENTRIES + 1, .75F, true) {

        public boolean removeEldestEntry(Map.Entry<String, Foo> eldest) {
            return size() > MAX_ENTRIES;
        }
    };

maka Anda bisa mendapatkan dari cache seperti

    Foo foo = cache.get(key);
    if (foo == null && !cache.containsKey(key)) {
        try {
            FooDAO fooDAO = DAOFactory.getFooDAO(conn);
            foo = fooDAO.getFooByKey(key);
            cache.put(key, foo);
        } catch (SQLException sqle) {
            logger.error("[getFoo] SQL Exception when accessing Foo", sqle);
        }
    }

istirahat tersisa sebagai latihan untuk pembaca :)

JeeBee
sumber
2
Saya tidak berpikir metode ini memiliki kapasitas TTL. Ini akan menjadi awal yang baik untuk menggulirkan milik Anda sendiri.
Chase Seibert
Ya, saya akan meninggalkan hal-hal TTL sebagai bagian dari latihan pembaca: p - dan tentu saja libs pihak ketiga akan jauh lebih diuji daripada menggulirkan milik Anda sendiri.
JeeBee
5

JCS sudah teruji dan benar. Meskipun ringan sejauh mekanisme caching berjalan, Anda dapat menggali kode yang sebenarnya dan meniru apa yang mereka lakukan dengan HashMap di bawah sampul untuk apa yang Anda butuhkan dan tidak lebih. Anda tampaknya memiliki gagasan yang cukup bagus tentang apa yang Anda cari.

Ichorus
sumber
Saya berasumsi maksud Anda itu tidak ringan sejauh mekanisme caching berjalan? Ini tampaknya menjadi salah satu solusi perusahaan yang paling populer.
Chase Seibert