spring-redis SortedSet型別成員的過期時間處理

sl521100發表於2016-02-24

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);
}

 

相關文章