大型系統面臨數據庫讀寫瓶頸時,分布式緩存是破局關鍵。本文深度剖析 Ehcache、Cacheonix、ASimpleCache、JBoss Cache、Voldemort 五大框架的架構特點、核心功能、適用場景與選型建議,助力架構師做出最優決策。
| 框架 | 定位 | 分布式支持 | 存儲模型 | 典型場景 | 學習曲線 |
|---|---|---|---|---|---|
| Ehcache | 通用緩存標準 | 支持 (Terracotta 集群) | Key-Value (堆/磁盤/分布式) | 單體/集群應用、Hibernate 二級緩存 | 低 |
| Cacheonix | 高性能分布式集群 | 原生分區/復制集群 | Key-Value (分區/本地/遠程) | 中大型高併發系統、計算密集型 | 中 |
| ASimpleCache | Android 輕量級緩存 | 不支持 (單機) | Key-Value (內存/文件) | Android 客戶端數據緩存 | 極低 |
| JBoss Cache | 事務型樹狀緩存 | 支持 (JGroups 集群) | 樹狀結構 | 事務型集群應用、狀態複製 | 高 |
| Voldemort | 分布式 Key-Value 存儲 | 原生分區/復制/多區域 | Key-Value (BDB/內存/緩存) | 大規模分布式存儲、高可用緩存層 | 高 |
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
中小型應用、Hibernate 二級緩存、Spring Cache 抽象實現、需要堆外/磁盤緩存的系統。分布式模式需搭配 Terracotta Server Array,運維成本較高。
Cache<K,V> 接口分區緩存:數據按 Key 哈希分布到多節點,線性擴展讀寫吞吐。復制緩存:全量同步,低延遲讀取,適合配置/元數據。
<cacheonix>
<server>
<listener><tcp port="8879" buffer="128k"/></listener>
<broadcast><multicast multicastAddress="225.0.1.2" multicastPort="9998"/></broadcast>
<partitionedCache name="customer.cache">
<store><lru maxElements="10000" maxBytes="10mb"/><expiration idleTime="120s"/></store>
</partitionedCache>
</server>
</cacheonix>
Cacheonix cacheonix = Cacheonix.getInstance();
Cache<String, String> cache = cacheonix.getCache("my.cache");
cache.put("key", "value");
String value = cache.get("key");
cache.remove("key");
ACache.java),無依賴,~200 行核心代碼ACache mCache = ACache.get(context);
// 存儲
mCache.put("key1", "value");
mCache.put("key2", "value", 10); // 10秒過期
mCache.put("key3", "value", 2 * ACache.TIME_DAY); // 2天過期
// 讀取
String value = mCache.getAsString("key1");
User user = mCache.getAsObject("user_key");
純 Android 客戶端緩存,不支持分布式。適合 App 本地數據緩存(用戶信息、列表數據、圖片元數據)。服務端勿用。
數據組織為 樹狀結構 (/level1/level2/node),每個節點存儲 Key-Value 屬性。支持 事務 (JTA/本地),集群通信基於 JGroups (UDP/TCP 多播/單播)。
TreeCache tree = new TreeCache();
PropertyConfigurator config = new PropertyConfigurator();
config.configure("jboss-cache.xml"); // 配置文件
tree.startService();
// 存儲
tree.put("/com/manager/jimmy", "en-name", "Jimmy Zhang");
tree.put("/com/developer/hanson", "myarray", new String[]{"1","2","3"});
// 讀取
String name = (String) tree.get("/com/manager/jimmy", "en-name");
String[] arr = (String[]) tree.get("/com/developer/hanson", "myarray");
tree.stopService();
配置 FileCacheLoader 將緩存節點持久化到文件系統,支持事務恢復。適用於需要持久化狀態的集群應用。
JBoss Cache 已進入維護模式,紅帽推薦遷移至 Infinispan (其繼任者,功能更強、API 更現代、JCache 兼容)。新項目建議直接選 Infinispan。
源自 LinkedIn,對標 Amazon Dynamo:高可用、最終一致性、分區容錯。純 Java 實現,無單點故障。
<cluster>
<server><id>0</id><host>node1</host><partitions>0,1,2,3</partitions><zone-id>0</zone-id></server>
<server><id>1</id><host>node2</host><partitions>4,5,6,7</partitions><zone-id>1</zone-id></server>
</cluster>
<stores>
<store>
<name>test</name><replication-factor>2</replication-factor>
<persistence>bdb</persistence><routing>client</routing>
<key-serializer><type>string</type></key-serializer>
<value-serializer><type>json</type><compression><type>gzip</type></compression></value-serializer>
</store>
</stores>
StoreClient client = SocketStoreClientFactory.getStoreClient("tcp://host:port", "storeName");
client.put("key", "value");
String value = client.get("key");
client.delete("key");
| 需求場景 | 首選方案 | 備選方案 | 關鍵理由 |
|---|---|---|---|
| Spring/Hibernate 整合、中小型集群、需堆外/磁盤緩存 | Ehcache | Caffeine (單機) + Redis (分布式) | 生態最完善、配置最簡單、標準兼容 |
| 高性能分布式計算、需分區擴展、原生集群無依賴 | Cacheonix | Hazelcast / Infinispan | 分區架構線性擴展、非多播友好 |
| Android 客戶端本地緩存 | ASimpleCache / MMKV / DataStore | Room (結構化) | 極簡輕量、無依賴、文件持久化 |
| 事務型集群狀態複製、樹狀數據模型 | Infinispan (替代 JBoss Cache) | Hazelcast | JBoss Cache 停維,Infinispan 繼承並增強 |
| 超大規模分布式存儲、高可用優於強一致、多數據中心 | Voldemort / Cassandra / Redis Cluster | DynamoDB (托管) | Dynamo 血統、最終一致性、線性擴展 |
| 通用高性能分布式緩存、微服務架構 | Redis Cluster / Redis Sentinel | Hazelcast / Infinispan | 生態最豐富、性能極致、運維工具完善、業界標配 |
2024+ 新項目首選 Redis (Cluster/Sentinel) 或雲托管緩存服務。上述框架多為 2010-2015 年代產物,Redis 以單線程高性能、豐富數據結構、Lua 腳本、流/模塊擴展、成熟運維生態成為事實標準。僅在以下場景考慮傳統框架:
分布式緩存選型無銀彈,需基於數據模型、一致性要求、擴展性目標、運維能力、技術棧兼容性綜合權衡。理解各框架底層架構(分區/復制、一致性協議、存儲引擎)比記憶 API 更重要。現代架構中,Redis 為主、本地緩存 (Caffeine) 為輔、多級緩存分層是主流最佳實踐。