鄭州做網(wǎng)站的專業(yè)公司騰訊廣告聯(lián)盟
項(xiàng)目中如果有使用大量的本地緩存場(chǎng)景,可以使用redis+ehcache組合緩存,優(yōu)先使用ehcache本地緩存,本地緩存沒(méi)有查詢到再使用redis緩存
可看前文中如何集成
本地緩存使用存在的問(wèn)題
1、本地緩存如何保證緩存的是最新值
可定義版本號(hào)、自增id或者時(shí)間戳,進(jìn)行判斷比對(duì)是否是最新值
2、各個(gè)節(jié)點(diǎn)保證本地緩存一致性
保證各個(gè)節(jié)點(diǎn)的一致性,且不影響性能,常使用消息進(jìn)行發(fā)布訂閱或者是廣播模式進(jìn)行同步
public class CustomerCache implements org.springframework.cache.Cache {void evict(Object key);void put(Object key, @Nullable Object value);<T> T get(Object key, Callable<T> valueLoader);
}
針對(duì)以上3個(gè)主要方法,
PUT
void put(Object key, @Nullable Object value){// 數(shù)據(jù)都得保存一份到redisboolean success = redis.put(key, expire, value);// 存入版本號(hào) redis.put(newKey, expire, remoteVersion);// 以上2步驟應(yīng)開(kāi)啟redis事務(wù),或可存入hset格式Long remoteVersion = getRemoteVersion(key);if (success) {// 存入本地緩存ehCacheClient.put(cacheName, prefix + key, remoteVersion);ehCacheClient.put(cacheName, key, value);// 發(fā)出消息,message需包含key remoteVersion,操作類型,put或deletemessageService.send(topic, message);// 注冊(cè)消息監(jiān)聽(tīng)messageService.registerMessageListener(message -> {//刪除緩存if (operate == delete) {ehCacheClient.remove(cacheName, key);ehCacheClient.remove(cacheName, prefix + key);return;}// 更新緩存Long localVersion = ehCacheClient.get(cacheName, prefix + key);if (remoteVersion > localVersion) {ehCacheClient.put(cacheName, key, remoteValue);ehCacheClient.put(cacheName, prefix + key, remoteVersion);}});}}
GET
<T> T get(Object key, Callable<T> valueLoader){value = (T) ehCacheClient.get(cacheName, key)if (value == null) {value = redis.get(key);// 重新增加本地緩存ehCacheClient.put(cacheName, key, value);ehCacheClient.put(cacheName, prefix + key, value);}}
EVICT
void evict(Object key){ehCacheClient.remove(cacheName, key);ehCacheClient.remove(cacheName, prefix + key);redis.remote(key);// 同步到其他節(jié)點(diǎn) messageService.send(topic, message);}