基于Jedis对hashKey进行过期设置
在redis中通过需要对订单等信息进行存在时间设置对于Key-Value的形式可以直接使用expire函数设置但是对于 Key-Field-Value则没有现成的函数进行设置 以下就是针对这一场景进行的。
方案
-
以多线程的方式进行对需要设置过期时间的hashKey值的进行线程等待删除操作。
-
将需要所有删除的Key-Field-Value 以及存在时间存入同一个 Key-Field 的redis中 ,之后创建一个新的线程死循环判断里面的集合是否达到超时的时间,一但达到删除时间的期限就进行删除操作
-# 分析 -
对于两种方法在我看来针对一个 field域就设置一个线程进行删除操作太过于浪费资源 ,所以我选择了第二个作为我的执行方案,当然我的方法不代表最佳方案如果知道更好的可行性方案的大佬请留言指点一二。
示例
创建一个redis的工具类进行对应的查询删除插入这里面我就写了需要用的几个
package com.farsunset.httpserver.until;
import redis.clients.jedis.Jedis;
public class RedisUntil {
private final static Jedis redis=new Jedis("*********ip地址",6379);
public static void hset(String key ,String field ,String value){
redis.hset(key,field,value);
}
public static String hget(String key ,String field){
String json=redis.hget(key,field);
return json;
}
public static void hdel(String key,String field){
redis.hdel(key,field);
}
}
编写函数
package com.farsunset.httpserver.configuration;
import com.alibaba.fastjson.JSON;
import com.farsunset.httpserver.until.RedisUntil;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class RedisField implements ApplicationContextAware {
//需要删除的集合
private static Set<Cache> WAIT_DEL_SET = Collections.synchronizedSet(new TreeSet<Cache>());
private static final String EXPIRE_REDIS_KEY="expireKey";
private static final String EXPIRE_REDIS_FIELD="expireField";
public static void init(){
/**
* 获得待删除的集合
*/
String json= RedisUntil.hget(EXPIRE_REDIS_KEY,EXPIRE_REDIS_FIELD);
List<Cache> list=(List<Cache>) JSON.parseArray(json,Cache.class);
WAIT_DEL_SET.addAll(list);
}
/**
*
* @param applicationContext
* @throws BeansException
* 通过实现ApplicationContextAware接口将需要开辟的线程加载的spring的初始化函数中去
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.printf("in this ");
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
while (true){
RedisField.init();
if (WAIT_DEL_SET!=null){
synchronized (WAIT_DEL_SET) {
RedisField.flushCache();
}
}
}
}});
thread.start();
//测试能够定时删除field值
RedisField.put("myTest","test005","have a try",5);
RedisField.put("myTest","test006","have a try",5);
}
public static void put(String key,String field,String value,long expireTime){
if (null==key||key.equals("")){
return;
}
if (null==field||field.equals("")){
return;
}
RedisUntil.hset(key,field,value);
String json =RedisUntil.hget(EXPIRE_REDIS_KEY,EXPIRE_REDIS_FIELD);
List<Cache> list=(List<Cache>)JSON.parseArray(json,Cache.class);
WAIT_DEL_SET.add(new Cache(expireTime*1000+System.currentTimeMillis(),key,field));
WAIT_DEL_SET.addAll(list);
RedisUntil.hset(EXPIRE_REDIS_KEY,EXPIRE_REDIS_FIELD,JSON.toJSONString(WAIT_DEL_SET));
}
/**
* 删除field函数
*/
public static void flushCache(){
Iterator<Cache> iterator = WAIT_DEL_SET.iterator();
while (iterator.hasNext()) {
Cache it = iterator.next();
if (it.expireTime <= System.currentTimeMillis()) {
System.out.println("删除键 key" + it.key + "field" + it.field);
RedisUntil.hdel(it.key, it.field);
iterator.remove();
}
}
RedisUntil.hset(EXPIRE_REDIS_KEY, EXPIRE_REDIS_FIELD, JSON.toJSONString(WAIT_DEL_SET));
}
@SuppressWarnings("unused")
/**
* 一个删除对象的类WAIT_DEL_SET就是他的容器
*/
public static class Cache implements Comparable<Cache> {
private long expireTime;
private String key;
private String field;
public Cache() {
}
public Cache(long expireTime, String key, String field) {
this.expireTime = expireTime;
this.key = key;
this.field = field;
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
@Override
public int compareTo(Cache o) {
if (o==null){
return -1;
}
if (o.getExpireTime()==this.getExpireTime()){
return 0;
}
return (o.getExpireTime()>this.getExpireTime()) ? 1 : -1;
}
@Override
public int hashCode(){
final int prime=31;
int result=1;
result=prime*result+((field==null) ? 0 : field.hashCode());
result=prime*result+((key==null) ? 0 : key.hashCode());
return result;
}
@Override
public String toString() {
return "Cache [expiredTime=" + expireTime + ", key=" + key + ", field=" + field + "]";
}
}
}
存在问题
在进程运行过程中有时候会出现redis连接异常,由于我在学生版的阿里云部署的所以可能在性能上有一些问题 当然也有可能是代码问题希望给出指点