新聞中心
Redis緩存拋棄不再曾經(jīng)

隨著互聯(lián)網(wǎng)應(yīng)用訪問量的迅速增長,應(yīng)用的性能成為了重中之重。在應(yīng)對高并發(fā)、大數(shù)據(jù)、突發(fā)流量等需求時,緩存技術(shù)成為了解決方案之一。在Java生態(tài)中,Redis是最受歡迎的緩存技術(shù)之一。但是,如何正確地使用Redis緩存依然是一個值得探討的話題。許多開發(fā)者會因?yàn)椴磺宄彺嫣蕴呗?,而?dǎo)致緩存“拋棄不再曾經(jīng)”。
說到Redis緩存的淘汰策略,首先就要提到Redis的5種淘汰策略:
1. volatile-lru:使用LRU算法來淘汰包含過期時間的key,即只對設(shè)定了過期時間的鍵進(jìn)行刪除操作,刪除最近最少使用的鍵值對;
2. volatile-ttl:淘汰臨近過期的鍵值對;
3. volatile-random:隨機(jī)淘汰過期鍵值對;
4. allkeys-lru:刪除最近最少使用的鍵值對,無論是過期的還是沒有過期的;
5. allkeys-random:隨機(jī)刪除鍵值對。
假設(shè)我們需要對用戶信息進(jìn)行緩存,如下所示:
“`Java
public void addUser(User user){
String key = “user_” + user.getId();
Jedis jedis = RedisUtil.getJedis();
try{
jedis.set(key.getBytes(), SerializeUtil.serialize(user));
}catch(Exception e){
e.printStackTrace();
}finally{
RedisUtil.returnResource(jedis);
}
}
public User getUser(String id){
String key = “user_” + id;
Jedis jedis = RedisUtil.getJedis();
try{
byte[] result = jedis.get(key.getBytes());
if(result != null){
return (User)SerializeUtil.unserialize(result);
}
return null;
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
RedisUtil.returnResource(jedis);
}
}
上述代碼是一個簡單的Redis緩存實(shí)現(xiàn),以存儲用戶信息為例。如果我們使用volatile-lru淘汰策略,Redis會刪除最近最少使用的過期鍵值對。而我們的緩存實(shí)現(xiàn)卻沒有在存儲用戶信息的時候設(shè)置過期時間。這樣,在高并發(fā)的情況下,緩存中的鍵值對就會越來越多,占用越來越多的內(nèi)存。
那么,如何避免Redis緩存“拋棄不再曾經(jīng)”呢?此處推薦使用增量式開發(fā)和AOP編程思想,即在RedisUtil工具類中為存儲Redis數(shù)據(jù)的方法加上過期時間。具體實(shí)現(xiàn)可以采用Spring框架提供的AOP技術(shù),在Redis緩存操作前,為存儲方法動態(tài)添加過期時間。
```Java
@Aspect
@Component
public class RedisExpireAop{
@Value("${redis.expire.time}")
private int expireTime;
@Around("execution(public void redis.RedisUtil.set*(..)) || execution(public void redis.RedisUtil.add*(..))")
public void setWithExpire(ProceedingJoinPoint joinPoint) throws Throwable{
Object[] args = joinPoint.getArgs();
if(args == null || args.length
return;
}
String methodName = joinPoint.getSignature().getName();
if(methodName.startsWith("set") && args.length == 2){
Jedis jedis = RedisUtil.getJedis();
try{
jedis.set((byte[])args[0], (byte[])args[1]);
jedis.expire((byte[])args[0], expireTime);
}catch(Exception e){
e.printStackTrace();
}finally{
RedisUtil.returnResource(jedis);
}
}else if(methodName.startsWith("add") && args.length == 3){
Jedis jedis = RedisUtil.getJedis();
try{
jedis.zadd((byte[])args[0], Double.parseDouble(args[2].toString()), (byte[])args[1]);
jedis.expire((byte[])args[0], expireTime);
}catch(Exception e){
e.printStackTrace();
}finally{
RedisUtil.returnResource(jedis);
}
}else{
joinPoint.proceed();
}
}
}
上述代碼中,我們?yōu)镽edisUtil中的set和add方法添加了過期時間,并使用了Spring提供的AOP技術(shù),正常的業(yè)務(wù)代碼中無需添加過期時間。這樣就省去了手動為每個鍵值對設(shè)置過期時間的麻煩,而又避免了緩存過多、占用過多內(nèi)存的情況。將開發(fā)者從繁瑣的緩存管理中解放出來,使開發(fā)更加高效。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
分享文章:Redis緩存拋棄不再曾經(jīng)(redis緩存不管用了)
鏈接地址:http://m.5511xx.com/article/dpopogp.html


咨詢
建站咨詢
