主流緩存框架調研 - Guava/Caffeine/EhCache/JetCache...


Spring Cache
Spring Cache 是 Spring 提供的一整套的緩存解決方案。雖然它本身並沒有提供緩存的實現,但是它提供了一整套的接口和代碼規范、配置、注解等,這樣它就可以整合各種緩存方案了,比如 Redis、Ehcache,我們也就不用關心操作緩存的細節。
https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache

特性

  1. 基於AOP與方法級注解實現自動緩存操作, 不需要手動進行緩存的寫入與清除操作
  2. 官方提供了多種開箱即用的緩存實現(EhCache / Redis / Caffeine / Map 等), 也支持自定義緩存實現

解讀

SpringCache是 spring-context 中的一個緩存抽象, 它主要封裝一套注解: @Cacheable, @CacheEvict, @CachePut, @Caching, @CacheConfig, 配合Spring的AOP能力, 對接口層面的緩存提供了統一的規范, 並實現了切面中的復雜邏輯, 但是它底層並沒有實現具體的緩存邏輯, 需要集成其他緩存框架來使用, 底層只需要實現他的 Cache 接口即可.
總的來說, Spring Cache並非是一個緩存框架, 但卻是一個比較好的緩存框架擴展. 可以配合其他緩存框架來使用, 使得緩存框架無需自己去實現AOP與自定義注解這塊功能
 

Guava Cache

GuavaCache是 Google 開源的一級緩存框架, 可以理解為 ConcurrentHashMap 的增強版, 使其適合用來作為一個緩存集合
https://github.com/google/guava/wiki/CachesExplained

特性

  1. 基於ConcurrentHashMap, 支持高並發下的線程安全, 性能也做了優化
  2. 提供CacheBuilder, 簡化緩存操作對象的創建, 支持設置自定義的CacheLoader用來加載數據至緩存
  3. 使用軟引用與弱引用機制, 保障GC安全
  4. 支持key移除監聽, 支持同步監聽與異步監聽, 在key移除后執行一些邏輯
  5. 支持多個緩存清除策略: 存活時間 / 最大容量 / 主動清除 / 軟弱引用
  6. 支持獲取指定緩存集合的命中率等指標

解讀

GuavaCache的出現其實是簡化了日常的本地緩存使用方式, 在這之前, 我們想要做本地緩存一般都是基於HashMap等方式自行封裝緩存操作工具, 自己維護 緩存策略 / 淘汰策略, 性能不沒有保障, 內存泄漏的風險也很高, 而 GuavaCache 幫大家將這些封裝打包起來了, 還支持了許多額外的擴展功能, 最終提供一個開箱即用的緩存工具包, 用戶不需要再去關心里面的實現細節, 內存/性能問題也得到了保障
總的來說, GuavaCache是一個十分優秀的輕量級的本地緩存框架, 可以直接使用
 

Caffeine

Caffeine 是以 GuavaCache 為原型而開發的一個本地緩存框架, 相對GuavaCache, 它有更高的性能與命中率, 更強大的功能, 更靈活的配置方式

特性

  1. 具備GuavaCache幾乎所有特性, 並提供了適配器, 方便Guava用戶遷移至Caffeine, 兩者差異見: https://github.com/ben-manes/caffeine/wiki/Guava-zh-CN
  2. 通過異步維護/異步通知/異步刷新等方式, 達到了極致的讀寫性能
  3. 實現了JSR-107 JCache接口API

解讀

我們可以將Caffeine看做是GuavaCache的升級版, 它主要在性能和命中率上碾壓了Guava, 這有兩方面造成, 一是Caffeine將所有阻塞讀寫的操作全部通過ForkJoinPool實現異步處理, 二是Caffeine優化了緩存淘汰算法(Window LRU), 除此之外, 在一些細節的實現邏輯上, Caffeine也做了一定的調整, 比如: 替換通知 / null值處理 / 統計方式.
總的來說, 如果說你想使用GuavaCache, 那你可以先考慮下Caffeine
 

J2Cache

J2Cache是 OSChina 開源的一個兩級緩存框架, 采用固定的 一級 + 二級緩存 的模式, 從一開始就是為了解決兩級緩存一致性的問題
https://gitee.com/ld/J2Cache

特性

  1. 當二級緩存更改或失效時, 自動通知節點清除一級緩存 (支持RedisPubsub/MQ/JGroup等方式)
  2. 支持集成多種一二級緩存, 如: Caffeine/EhCache/Redis/Memcache等, 或自定義緩存實現
  3. 實現了 SpringCache 的擴展, 以及 mybatis/hibernate/session/springboot 的適配

解讀

J2Cache與其說是一個緩存框架, 不如說它是一個緩存紐帶, 它自己是沒有實現任何緩存能力的, 它最主要的作用就是通過 JGroup/MQ 等方式實現了各個實例間本地緩存的一致性問題, 所以具體一級緩存用什么實現, 二級緩存用什么實現, 都需要額外集成. 其次需要注意的是, 這個開源項目已經3年多沒有維護了, 並且其中的依賴項也長期未更新, 想要拿來投入生產使用還是有一些困難的
總的來說, J2Cache的初衷與我們目前的需求相同, 是為了實現實例間緩存數據一致性而產生, 不過該項目已經長期不維護, 如果需要拿來使用, 必然需要進行一番二開與優化
 

EhCache

EhCache是一個輕量級開源的緩存框架, Hibernate使用的默認緩存框架就是EhCache, 它支持多種緩存模型, 將緩存管理在 堆內 / 堆外 / 磁盤 / 遠程 多地.
https://github.com/ehcache/ehcache3

特性

  1. 實現了JSR107的規范, 並支持無縫集成 SpringCache/Hibernate/Tomcat等
  2. 輕量級核心, 除slf4j外無其他依賴
  3. 支持 堆內內存 / 堆外內存 / 磁盤 / 遠程緩存服務 三層存儲
  4. 支持多種緩存模型: 獨立緩存 / 分布式緩存 / 復制式緩存 , 具體描述如下:
    1. 獨立緩存: 每個應用實例在本地維護緩存, 意味着在其中一個實例中修改了緩存, 會導致與其他實例的緩存信息不一致
    2. 分布式緩存: 每個應用實例本地維護少量熱點緩存, 並有一個遠程緩存服務端來管理更多的緩存信息, 本地緩存未命中時則請求遠程服務獲取緩存信息, 這解決了緩存空間的問題, 但也無法保證實例間的本地緩存一致性
  1. 復制式緩存: 通過引入第三方事件通知機制(rmi/jgroup/jms等), 來同步各個實例間的本地緩存(包含內存/硬盤), 這意味着每個實例都需要維護一份完整的緩存數據在內存/硬盤中, 開銷不小, 並且大數據量下的頻繁變更也容易導致各實例間的數據不致性

解讀

EhCache是一個非常老牌的緩存框架了, 它可以說是緩存全家桶, 從本地內存緩存到硬盤緩存到遠程緩存服務一整套全部自己實現, 與其說他是一個框架, 他更像是一個企業級應用緩存解決方案以及實現, 但是查看其官方網站, 便被EhCache的龐大體系所震驚.
總的來說, 雖然EhCache核心包極度輕量, 但過於復雜的配置與使用方式項使得在項目開發中難以靈活運用, 況且其大部分功能在實際開發場景中難有用武之地, 如緩存落盤等
 

JetCache

JetCache 是阿里開源的通用緩存訪問框架, 它統一了多級緩存的訪問方式, 封裝了類似於SpringCache的注解, 以及GuavaCache類似的Builder, 來簡化項目中使用緩存的難度
https://github.com/alibaba/jetcache/blob/master/introduce_CN.md

特性

  1. 提供統一的, 類似jsr-107風格的API訪問Cache, 並可通過注解創建並配置Cache實例
  2. 提供類似SpringCache風格的注解, 實現聲明式的方法緩存, 並支持TTL和兩級緩存
  3. 支持緩存自動刷新與家在保護, 防止高並發下緩存未命中時打爆數據庫
  4. 支持緩存的統計指標

解讀

我認為JetCache的定位與SpringCache類似, 它沒有去實現具體的緩存實現, 而是對現有的緩存框架進行抽象, 並提供統一的訪問入口, 而且JetCache提供了比SpringCache更強大的接口緩存注解, 除此之外, 還提供了CacheBuilder / 緩存對象注解, 可以說將開發過程中所有使用緩存的場景都覆蓋到了, 屬於開發效率型框架
總的來說, JetCache不是緩存實現, 而是可以用來在現有緩存框架基礎上簡化使用的工具, 甚至可以與SpringCache一起使用, 是一個值得嘗試的框架


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM