redis預設是隻支援簡單key的過期處理的,像SortedSet型別,也是針對整個set的過期處理,不支援對set的某個成員的過期處理;
為了解決這個問題,做法如下:
1.儲存key及值資訊到redis,並將key存入set裡,設定key的過期時間;
這樣key可以支援過期處理並在過期後移除key及值;但是set裡的key還是存在的;
a、在需要判斷key過期的處理中,如 boolean containsKey(Object key) ,先在set集合拿到對應的key;
用ttl判斷可以是否存在,如不存在說明已過期,從set移除該key;
b、定時任務,有些情況,可以過期了後面也不會再用到,所以需要定時去清理key,checkExpire();
2.程式碼如下
public boolean containsKey(Object key) { final byte[] keyBytes = computeKey(key); return (Boolean) template.execute(new RedisCallback<Boolean>() { public Boolean doInRedis(RedisConnection connection) throws DataAccessException { waitForLock(connection); Set<byte[]> keys =connection.zRange(setName,0,-1); boolean isExist=false; for (byte[] item : keys) { if(Arrays.equals( keyBytes,item)){ Long remain= connection.ttl(item); if(remain==-2){ connection.zRem(setName, item);//從set裡移除; }else { isExist = true; } break; } } return isExist; } }, true); } public void checkExpire() { template.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { waitForLock(connection); //connection.multi(); Set<byte[]> keys =connection.zRange(setName,0,-1); for (byte[] item : keys) { Long remain= connection.ttl(item); if(remain==-2){ //connection.del(item); // remove key from set connection.zRem(setName, item); } } //connection.exec(); return null; } }, true); }