对redis中的field设置过期时间

基于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连接异常,由于我在学生版的阿里云部署的所以可能在性能上有一些问题 当然也有可能是代码问题希望给出指点
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值