Proyek ini tidak lagi dipertahankan !!!
OHC harus memberikan kinerja yang baik pada perangkat keras komoditas dan sistem besar menggunakan arsitektur-memori-seragam.
Belum ada hasil tes kinerja - Anda dapat mencoba alat OHC -Benchmark. Lihat instruksi di bawah ini. Kesan yang sangat mendasar pada kecepatan ada di bagian _benchmarking_.
Java 8 VM yang mendukung 64bit dan memiliki sun.misc.Unsafe
(Oracle JVMS di X64 Intel CPU).
OHC ditargetkan untuk Linux dan OSX. Ini harus bekerja pada Windows dan UNIX OSS lainnya.
OHC menyediakan dua implementasi untuk karakteristik entri cache yang berbeda: - _linked_ implementasi mengalokasikan memori off -heap untuk setiap entri secara individual dan bekerja paling baik untuk entri menengah dan besar. - Implementasi _Chunked_ mengalokasikan memori off-heap untuk setiap segmen hash secara keseluruhan dan dimaksudkan untuk entri kecil.
Jumlah segmen dikonfigurasi melalui org.caffinitas.ohc.OHCacheBuilder
, default ke # of cpus * 2
dan harus menjadi kekuatan 2. Entri distribusikan di atas segmen menggunakan bit paling signifikan dari kode hash 64 bit. Akses pada setiap segmen disinkronkan.
Setiap entri peta hash dialokasikan secara individual. Entri bebas (deallocated), ketika mereka tidak lagi direferensikan oleh peta off-heap itu sendiri atau referensi eksternal seperti org.caffinitas.ohc.DirectValueAccess
atau org.caffinitas.ohc.CacheSerializer
.
Desain implementasi ini mengurangi waktu terkunci dari segmen menjadi waktu yang sangat singkat. Masukkan/ganti operasi mengalokasikan memori terlebih dahulu, hubungi org.caffinitas.ohc.CacheSerializer
untuk membuat serial kunci dan nilai dan kemudian memasukkan entri yang sepenuhnya disiapkan ke dalam segmen.
Penggusuran dilakukan dengan menggunakan algoritma LRU. Daftar tertaut melalui semua elemen yang di -cache per segmen digunakan untuk melacak entri tertua.
Alokasi memori yang dipotong implementasi off-heap.
Tujuan dari implementasi ini adalah untuk mengurangi overhead untuk entri cache yang relatif kecil dibandingkan dengan implementasi terkait karena memori untuk seluruh segmen sebelumnya dialokasikan. Implementasi ini cocok untuk entri kecil dengan implementasi serialisasi cepat (DE) dari org.caffinitas.ohc.CacheSerializer
.
Segmentasi sama seperti dalam implementasi terkait. Jumlah segmen dikonfigurasi melalui org.caffinitas.ohc.OHCacheBuilder
, default ke # of cpus * 2
dan harus menjadi kekuatan 2. Entri distribusikan di atas segmen menggunakan bit paling signifikan dari kode hash 64 bit. Akses pada setiap segmen disinkronkan.
Setiap segmen dibagi menjadi beberapa potongan. Setiap segmen bertanggung jawab atas sebagian dari total kapasitas (capacity / segmentCount)
. Jumlah memori ini dialokasikan sekali di muka selama inisialisasi dan secara logis dibagi menjadi sejumlah potongan yang dapat dikonfigurasi. Ukuran setiap chunk dikonfigurasi menggunakan opsi chunkSize
di org.caffinitas.ohc.OHCacheBuilder
.
Seperti implementasi terkait, entri hash diserialisasi menjadi buffer sementara terlebih dahulu, sebelum dimasukkan ke dalam segmen yang sebenarnya terjadi (operasi segement disinkronkan).
Entri baru ditempatkan ke potongan tulis saat ini. Ketika potongan itu penuh, potongan kosong berikutnya akan menjadi potongan tulis yang baru. Ketika semua potongan penuh, potongan yang paling baru digunakan, termasuk semua entri yang dikandungnya, diusir.
Menentukan sifat -sifat pembangun fixedKeyLength
dan fixedValueLength
mengurangi jejak memori sebesar 8 byte per entri.
Serialisasi, akses langsung, dan fungsi-fungsi Get-With-Loader tidak didukung dalam implementasi ini.
Untuk mengaktifkan implementasi yang dipotong, tentukan chunkSize
di org.caffinitas.ohc.OHCacheBuilder
.
Catatan: Implementasi yang dipotong masih harus dianggap eksperimental.
OHC mendukung tiga algoritma penggusuran:
Gunakan kelas OHCacheBuilder
untuk mengonfigurasi semua parameter yang diperlukan seperti
Umumnya Anda harus bekerja dengan meja hash besar. Semakin besar tabel hash, semakin pendek daftar-daftar yang ditautkan di setiap partisi hash-itu berarti jalan-jalan yang kurang terhubung dan peningkatan kinerja.
Jumlah total memori Off Heap yang diperlukan adalah tabel hash total plus tabel . Setiap ember hash (saat ini) membutuhkan 8 byte - sehingga rumusnya adalah capacity + segment_count * hash_table_size * 8
.
OHC mengalokasikan memori off-heap secara langsung melewati batasan memori Java yang tidak ada. Ini berarti, bahwa semua memori yang dialokasikan oleh OHC tidak dihitung ke -XX:maxDirectMemorySize
.
Karena khususnya implementasi terkait melakukan operasi alloc/gratis untuk setiap entri individu, pertimbangkan bahwa fragmentasi memori dapat terjadi.
Juga tinggalkan beberapa ruang kepala karena beberapa alokasi mungkin masih dalam penerbangan dan juga "hal -hal lain" (sistem operasi, JVM, dll) membutuhkan memori. Itu tergantung pada pola penggunaan berapa banyak ruang kepala diperlukan. Perhatikan bahwa implementasi tertaut mengalokasikan memori selama operasi penulisan _Before_ itu dihitung terhadap segmen, yang akan mengusir entri yang lebih lama. Ini berarti: Jangan mendedikasikan semua memori yang tersedia untuk OHC.
Kami merekomendasikan menggunakan Jemalloc untuk menjaga fragmentasi tetap rendah. Pada sistem operasi UNIX, Preload Jemalloc.
OSX biasanya tidak memerlukan Jemalloc untuk alasan kinerja. Pastikan juga bahwa Anda menggunakan versi terbaru Jemalloc - beberapa distribusi Linux masih memberikan versi yang cukup lama.
Untuk preload jemalloc di linux, gunakan export LD_PRELOAD=<path-to-libjemalloc.so
, untuk preload jemalloc pada osx, gunakan export DYLD_INSERT_LIBRARIES=<path-to-libjemalloc.so
. Template skrip untuk preloading dapat ditemukan di proyek Apache Cassandra.
QuickStart:
Ohcache ohcache = ohcachebuilder.newbuilder () .keyserializer (yourkeyserializer) .Valueserializer (YourValueserializer) .membangun();
QuickStart ini menggunakan konfigurasi default paling tidak:
Lihat Javadoc dari CacheBuilder
untuk daftar lengkap opsi.
Serializer kunci dan nilai perlu mengimplementasikan antarmuka CacheSerializer
. Antarmuka ini memiliki tiga metode:
int serializedSize(T t)
untuk mengembalikan ukuran serial dari objek yang diberikanvoid serialize(Object obj, DataOutput out)
untuk membuat serialisasi objek yang diberikan ke output dataT deserialize(DataInput in)
untuk deserialize objek dari input data Klone git repo ke mesin lokal Anda. Baik menggunakan cabang master yang stabil atau tag rilis.
git clone https://github.com/snazy/ohc.git
Anda memerlukan OpenJDK 11 atau lebih baru untuk dibangun dari sumber. Hanya mengeksekusi
mvn clean install
Anda perlu membangun OHC dari sumber karena artefak patokan besar tidak diunggah ke Maven Central.
Jalankan java -jar ohc-benchmark/target/ohc-benchmark-0.7.1-SNAPSHOT.jar -h
(saat membangun dari sumber) untuk mendapatkan beberapa informasi bantuan.
Secara umum alat benchmark memulai banyak utas dan melakukan operasi _get_ dan _put_ secara bersamaan menggunakan distribusi kunci yang dapat dikonfigurasi untuk operasi _get_ dan _put_. Distribusi ukuran nilai juga perlu dikonfigurasi.
Opsi baris perintah yang tersedia:
-Cap <Arg> Ukuran cache -D <Arg> Durasi Benchmark Dalam Detik -h Bantuan, cetak perintah ini -lf <burs> faktor beban tabel hash -r <ger arg> ration baca-tulis (sebagai ganda 0..1 mewakili kesempatan untuk dibaca) -RKD <Arg> Kunci Panas Penggunaan Distribusi - Default: Seragam (1..10000) -sc <ger arg> Jumlah segmen (jumlah individu off-heap-maps) -t <Arg> utas untuk eksekusi -VS <Arg> Ukuran Nilai - Default: Tetap (512) -WKD <Arg> Kunci Panas Penggunaan Distribusi - Default: Seragam (1..10000) -wu <bur> pemanasan-<work-secs>, <sleep-secs> -Z <BRIG> UKURAN TABEL HASH -CS <Arg> Ukuran Chunk - Jika ditentukan akan menggunakan implementasi "chunked" -FKS <Arg> Ukuran kunci tetap dalam byte -FVS <Arg> Ukuran nilai tetap dalam byte -Mes <Arg> Ukuran entri maks dalam byte -unl Jangan gunakan penguncian -hanya persetujuan untuk mode utamanya satu -Hm <Arg> algoritma hash untuk digunakan - murmur3, xx, crc32 -Bh menunjukkan bucket horpergram di statistik -kl <Arg> Aktifkan histogram bucket. Default: Salah
Distribusi untuk tombol baca, tombol tulis dan ukuran nilai dapat dikonfigurasi menggunakan fungsi berikut:
Exp (min..max) distribusi eksponensial di atas kisaran [min..max] Ekstrim (min..max, bentuk) nilai ekstrem (weibull) di atas kisaran [min..max] Qextreme (min..max, bentuk, quantas) nilai ekstrem, dibagi menjadi quantas, di mana peluang seleksi seragam Gaussian (min..max, stdvrng) distribusi gaussian/normal, di mana rata-rata = (min+max)/2, dan stdev adalah (rata-rata-min)/stdvrng Gaussian (Min..Max, Mean, Stdev) Distribusi Gaussian/Normal, dengan rata -rata yang didefinisikan secara eksplisit dan STDEV Seragam (min..max) distribusi seragam di atas kisaran [min, maks] Tetap (val) distribusi tetap, selalu mengembalikan nilai yang sama Mendahului nama dengan ~ akan membalikkan distribusi, misalnya ~ exp (1..10) akan menghasilkan 10 paling banyak, bukan paling tidak, sering kali Alias: Extr, Qextr, Gauss, Normal, Norm, Weibull
(Catatan: Ini mirip dengan alat stres Apache Cassandra - jika Anda tahu satu, Anda tahu keduanya;)
Contoh cepat dengan rasio baca/tulis .9
, kapasitas maks sekitar 1.5GB, 16 utas yang berjalan selama 30 detik:
java -jar ohc-benchmark/target/ohc-benchmark-0.5.1-snapshot.jar
(Perhatikan bahwa versi dalam nama file jar mungkin berbeda.)
Pada sistem 2.6GHz Core i7 (OSX) angka -angka berikut adalah tipikal menjalankan tolok ukur di atas (.9 Rasio Baca/Tulis):
Saat menggunakan sejumlah besar objek dalam tumpukan yang sangat besar, mesin virtual akan menderita peningkatan tekanan GC karena pada dasarnya harus memeriksa setiap objek apakah dapat dikumpulkan dan harus mengakses semua halaman memori. Cache harus menjaga set panas objek yang dapat diakses untuk akses cepat (mis. Disk Omit atau Trip Round Network). Satu -satunya solusi adalah menggunakan memori asli - dan di sana Anda akan berakhir dengan pilihan baik untuk menggunakan beberapa kode asli (C/C ++) melalui JNI atau menggunakan akses memori langsung.
Kode asli menggunakan C/C ++ melalui JNI memiliki kelemahan yang harus Anda tulis secara alami kode C/C ++ untuk setiap platform. Meskipun sebagian besar OS UNIX (Linux, OSX, BSD, Solaris) sangat mirip ketika berhadapan dengan hal-hal seperti perpustakaan perbandingan-dan-swap atau POSIX, Anda biasanya juga ingin mendukung platform lain (Windows).
Baik kode asli dan akses memori langsung memiliki kelemahan bahwa mereka harus "meninggalkan" konteks "JVM" - ingin mengatakan bahwa akses ke memori heap lebih lambat daripada akses ke data di tumpukan Java dan bahwa setiap panggilan JNI memiliki beberapa " melarikan diri dari konteks JVM "biaya.
Tetapi memori heap sangat bagus ketika Anda harus berurusan dengan sejumlah besar/banyak GB memori cache karena DOS itu tidak memberi tekanan pada kolektor sampah Java. Biarkan Java GC melakukan tugasnya untuk aplikasi di mana perpustakaan ini melakukan tugasnya untuk data yang di -cache.
Tl; dr yang mengalokasikan memori di luar-heap secara langsung dan melewati ByteBuffer.allocateDirect
Allocatedirect sangat lembut untuk GC dan kami memiliki kontrol eksplisit atas alokasi memori dan, yang lebih penting, gratis. The stock implementation in Java frees off-heap memory during a garbage collection - also: if no more off-heap memory is available, it likely triggers a Full-GC, which is problematic if multiple threads run into that situation concurrently since it means lots GCS penuh secara berurutan. Selanjutnya, implementasi stok menggunakan daftar tertaut global yang disinkronkan untuk melacak alokasi memori off-heap.
Inilah sebabnya mengapa OHC mengalokasikan memori off-heap secara langsung dan merekomendasikan untuk Preload Jemalloc pada sistem Linux untuk meningkatkan kinerja manajemen memori.
OHC dikembangkan pada 2014/15 untuk Apache Cassandra 2.2 dan 3.0 untuk digunakan sebagai backend baris-cache baru.
Karena tidak ada implementasi cache yang benar -benar cocok dengan HEAP yang tersedia, telah diputuskan untuk membangun yang sama sekali baru - dan itu OHC. Tapi ternyata OHC saja mungkin juga dapat digunakan untuk proyek lain - itulah sebabnya OHC adalah perpustakaan yang terpisah.
'Terima kasih' yang besar harus pergi ke Benedict Elliott Smith dan Ariel Weisberg dari DataStax atas masukan mereka yang sangat berguna untuk OHC!
Ben Manes, penulis Caffeine, cache on-heap yang sangat dapat dikonfigurasi menggunakan W-Tiny LFU.
Pengembang: Robert Stupp
Hak Cipta (C) 2014 Robert Stupp, Koeln, Jerman, Robert-Stupp.de
Berlisensi di bawah lisensi Apache, versi 2.0 ("lisensi"); Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. Anda dapat memperoleh salinan lisensi di
http://www.apache.org/licenses/license-2.0
Kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak yang didistribusikan di bawah lisensi didistribusikan berdasarkan "sebagaimana adanya", tanpa jaminan atau ketentuan dalam bentuk apa pun, baik tersurat maupun tersirat. Lihat lisensi untuk bahasa spesifik yang mengatur izin dan batasan di bawah lisensi.