分散式快取三雄對比:Memcached、Redis、Ehcache 架構選型指南
快取是高併發系統提升效能、降低資料庫壓力的關鍵層。本文對比 Memcached、Redis、Ehcache 三大主流方案的架構特性、資料模型、持久化、叢集策略與 Spring 整合範例,協助架構師依場景選型。
一、Memcached:純記憶體、高效能、無持久化
核心定位
高效能分散式記憶體快取伺服器,透過快取資料庫查詢結果,減少 DB 存取,提升動態 Web 應用速度與擴展性。
儲存特性
- 資料**僅存在記憶體**,重啟即消失。
- 容量達上限依 LRU 自動淘汰。
- 不支援持久化、備份、複寫,純快取角色。
資料結構
單一 Key-Value(Value 為二進位 Blob),無原生結構化操作。
叢集與一致性雜湊
客戶端以 Key 雜湊決定節點。為解決節點增減導致大量 Key 遷移,採用 一致性雜湊 + 虛擬節點:
- 環狀雜湊空間,Key 與節點映射至環上。
- 新增/移除節點僅影響鄰近 Key,避免全量重新分佈。
- 虛擬節點解決實體節點過少導致負載不均。
Spring 整合範例
<bean name="memcachedClient" class="net.rubyeye.xmemcached.utils.XMemcachedClientFactoryBean"
destroy-method="shutdown">
<property name="servers" value="${VIPCPS_MC_S1_HOST}:${VIPCPS_MC_S1_PORT}..."/>
<property name="connectionPoolSize" value="1"/>
<property name="sessionLocator">
<bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"/>
</property>
</bean>
二、Redis:功能豐富、支援持久化、主從複寫
核心定位
高效能 Key-Value 儲存系統,補償 Memcached 結構單一、無持久化不足,部分場景可補充關聯式資料庫。
資料型別豐富
| 型別 | 特性 | 典型操作 |
| String | 二進位安全字串 | GET/SET/INCR |
| List | 雙向鏈表 | LPUSH/RPOP/LRANGE |
| Set | 無序唯一集合 | SADD/SREM/SINTER |
| ZSet | 有序集合(分數排序) | ZADD/ZRANGE/ZRANK |
| Hash | 欄位-值映射 | HSET/HGET/HGETALL |
所有操作**原子性**,支援交集/並集/差集、排序、Lua 腳本事務。
持久化機制
- RDB 快照:
save seconds changes,定期將記憶體全量寫入磁碟。
- AOF 日誌:
appendonly yes,每條寫指令追加寫入;appendfsync everysec 折中效能與安全。
主從複寫
- 單向非同步複寫,從節點可級聯。
- 支援發布/訂閱同步增量指令。
- 提升讀擴展性與資料冗余。
Spring 整合範例
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="${redis.pool.maxActive}"/>
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<property name="maxWait" value="${redis.pool.maxWait}"/>
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
</bean>
<bean id="jedisConnectionFactory0" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${VIPCPS_REDIS_HOST_0}"/>
<property name="port" value="${VIPCPS_REDIS_PORT_0}"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
<bean id="stringRedisTemplate0" class="org.springframework.data.redis.core.StringRedisTemplate"
p:connection-factory-ref="jedisConnectionFactory0" scope="prototype"/>
<bean id="redisTemplateRouter" class="com.vipshop.unionweb.framework.redis.RedisTemplateRouter">
<constructor-arg>
<list><ref bean="stringRedisTemplate0"/><ref bean="stringRedisTemplate1"/></list>
</constructor-arg>
</bean>
客戶端路由實作
public class RedisTemplateRouter {
private static final CRC32 crc32 = new CRC32();
private static List redisTemplates;
private static int SERVER_COUNT;
public RedisTemplateRouter(List templates) {
redisTemplates = templates; SERVER_COUNT = templates.size();
}
public static StringRedisTemplate getRouteRedis(String key) {
crc32.reset(); crc32.update(key.getBytes());
int idx = Math.abs((int)(crc32.getValue() % SERVER_COUNT));
return redisTemplates.get(idx);
}
}
三、Ehcache:進程內快取、支援分散式、Java 生態首選
核心特性
- 純 Java 進程內快取框架,記憶體 + 磁碟兩級儲存,可擴展至數 GB。
- 支援 LRU、LFU、FIFO 多種淘汰演算法。
- 可快取頁面、物件、資料;支援叢集/分散式快取(Terracotta/RMI/JGroups)。
Spring 物件快取配置
<!-- ehcache.xml 關鍵片段 -->
<cache name="userCache"
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU"
overflowToDisk="true"
maxEntriesLocalDisk="1000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/>
透過 @Cacheable、@CachePut、@CacheEvict 註解無侵入式整合。
四、三雄選型決策矩陣
| 維度 | Memcached | Redis | Ehcache |
| 部署模式 | 獨立叢集 | 獨立叢集 | 進程內 / 分散式 |
| 資料結構 | 單一 Blob | 5 大型別 + 模組 | Java 物件序列化 |
| 持久化 | 無 | RDB + AOF | 磁碟溢寫 |
| 複寫/高可用 | 無(客戶端一致性雜湊) | 主從 + Sentinel/Cluster | Terracotta 叢集 |
| 查詢語言 | 無 | 指令 + Lua | 無(Java API) |
| 適用場景 | 純快取、Session、頁面片段 | 快取 + 計數器 + 排行榜 + 佇列 + 會話 | Java 進程內熱點資料、Hibernate 二級快取 |
| 運維複雜度 | 低 | 中 | 低(嵌入式) |
五、選型建議
- 純快取、極致 QPS、無持久化需求 → Memcached。
- 需要資料結構、持久化、發布訂閱、排行榜、分散式鎖 → Redis。
- Java 應用、進程內低延遲、Hibernate 二級快取、簡單分散式 → Ehcache。
- 混合架構常見**:Redis 做分散式快取/資料結構,Memcached 做大量 Session/頁面片段,Ehcache 做本地熱點(多級快取)。
- 上一篇文章: 布隆過濾器原理、誤判率分析與 Counting Bloom Filter 刪除機制
- 下一篇文章: 生產庫 ASM 磁碟組空間耗盡 (ORA-15041) 緊急處理與根因解決實戰
Copyright ©
程式碼之家 All Rights Reserved