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