Java緩存庫對比-以及OHCache總結

堆內緩存:

  1. LinkedHashMap:Java自帶類,內置LRU驅逐策略的實現(access-order);多線程訪問需要自己實現同步。
  2. Guava Cache:Google Guava工具包中的緩存實現,支持LRU驅逐策略;支持多線程併發訪問,支持按時間過期,但只有在訪問時才清除過期數據。
  3. Ehcache:支持多種驅逐策略:LFU、LRU、FIFO,支持持久化和集羣。性能跟Guava Cache比相當。
  4. Caffeine:支持W-TinyLFU驅逐策略,Benchmark測試讀寫性能是Guava Cache的6倍左右。

堆外緩存:

  1. OHCache:支持緩存驅逐和過期(Cassandra使用的緩存庫)
  2. ChronicleMap:支持Hash結構,性能好,不支持緩存驅逐
  3. MapDB:支持Tree結構,可順序掃描,不支持緩存驅逐
  4. Ehcache3:BigMemory收費

當緩存數據量非常大時,GC壓力過大會導致服務響應慢甚至崩潰,在HugeGraph圖數據庫中爲了緩解該問題,需引入堆外緩存,選擇了使用OHCache。

OHCache對外緩存總結

開源:https://github.com/snazy/ohc

特性:

  • 底層有2種實現:linked實現,適用於中大entry場景,默認實現,大部分feature只在該實現中才支持;chunked實現,適用於小entry場景,通過設置chunkSize或者fixedEntrySize啓用。
  • 通過eviction()來設置緩存驅逐策略,支持:LRU, W_TINY_LFU, NONE共3種,後兩種僅在linked實現中支持。
  • 通過capacity()來指定緩存的容量,單位是字節,注意不是條數。
  • 通過hashTableSize()來設置每個hash_table最大存放的entry個數數量(默認是0.75的factor)。
  • 必須指定自定義的keySerializer、valueSerializer系列化器,重載實現系列化serialize()方法與反序列化deserialize()方法;需要注意的是還需要重載serializedSize()方法,且該方法返回值必須和實際寫入的內容大小完全一樣,否則會報錯或數據不對。
  • 支持緩存條目過期機制,通過timeouts()開啓;允許通過defaultTTLmillis()設置一個默認過期時間,也可以在put()的時候單獨設置expireAt過期時間。注意:過期機制僅linked實現才支持,因爲chunked實現是以chunk爲單位進行緩存驅逐的,無法精確到entry粒度;而且並沒有獨立的線程來回收過期條目,只會在get或put操作時進行檢查(見get()或者ensureFreeSpaceForNewEntry()),若過期則刪除,詳細代碼見Timeouts.removeExpired()。
  • 可以通過getWithLoader()來利用線程池異步加載數據。
  • 建議使用jemalloc來減少內存碎片。
  • 實際的內存佔用:daa_capacity + segment_count * hash_table_size * 8,一個cache包括segment_count個hash_table,segment_count默認是2 * CPUs;一個hash_table的存放8字節*表大小個的entry地址信息。每個entry都帶着頭部(linked實現佔64字節,chunked實現若定長KV則佔16字節否則佔24字節),頭部後面是鍵值數據,頭部包括:前/後指針、鍵/值大小、引用數等。

Configures and builds OHC instance:

Field Meaning Default
keySerializer Serializer implementation used for keys Must be configured
valueSerializer Serializer implementation used for values Must be configured
executorService Executor service required for get operations using a cache loader. E.g. OHCache.getWithLoaderAsync(Object, CacheLoader) (Not configured by default meaning get operations with cache loader not supported by default)
segmentCount Number of segments 2 * number of CPUs (java.lang.Runtime.availableProcessors())
hashTableSize Initial size of each segment’s hash table 8192
loadFactor Hash table load factor. I.e. determines when rehashing occurs. .75f
capacity Capacity of the cache in bytes 16 MB * number of CPUs (java.lang.Runtime.availableProcessors()), minimum 64 MB
chunkSize If set and positive, the chunked implementation will be used and each segment will be divided into this amount of chunks. 0 - i.e. linked implementation will be used
fixedEntrySize If set and positive, the chunked implementation with fixed sized entries will be used. The parameter chunkSize must be set for fixed-sized entries. 0 - i.e. linked implementation will be used, if chunkSize is also 0
maxEntrySize Maximum size of a hash entry (including header, serialized key + serialized value) (not set, defaults to capacity divided by number of segments)
throwOOME Throw OutOfMemoryError if off-heap allocation fails false
hashAlgorighm Hash algorithm to use internally. Valid options are: XX for xx-hash, MURMUR3 or CRC32 Note: this setting does may only help to improve throughput in rare situations - i.e. if the key is very long and you’ve proven that it really improves performace MURMUR3
unlocked If set to true, implementations will not perform any locking. The calling code has to take care of synchronized access. In order to create an instance for a thread-per-core implementation, set segmentCount=1, too. false
defaultTTLmillis If set to a value > 0, implementations supporting TTLs will tag all entries with the given TTL in milliseconds. 0
timeoutsSlots The number of timeouts slots for each segment - compare with hashed wheel timer. 64
timeoutsPrecision The amount of time in milliseconds for each timeouts-slot. 128
ticker Indirection for current time - used for unit tests. Default ticker using System.nanoTime() and System.currentTimeMillis()
capacity Expected number of elements in the cache No default value, recommended to provide a default value.
eviction Choose the eviction algorithm to use. Available are:LRU: Plain LRU - least used entry is subject to evictionW-WinyLFU: Enable use of Window Tiny-LFU. The size of the frequency sketch (“admission filter”) is set to the value of hashTableSize. See this article for a description.None: No entries will be evicted - this effectively provides a capacity-bounded off-heap map. LRU
frequencySketchSize Size of the frequency sketch used by W-WinyLFU Defaults to hashTableSize.
edenSize Size of the eden generation used by W-WinyLFU relative to a segment’s size 0.2

文檔地址:https://javadoc.io/static/org.caffinitas.ohc/ohc-core/0.7.0/org/caffinitas/ohc/OHCacheBuilder.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章