Home  >  Article  >  Database  >  What is the solution for Java to operate redis and set expiration in the early morning of the next day?

What is the solution for Java to operate redis and set expiration in the early morning of the next day?

WBOY
WBOYforward
2023-05-26 15:40:591290browse

Java operation redis setting expires in the early morning of the next day

Scenario

When querying data, I encountered the problem of needing to set the data to expire the next day in redis, but redis has There is no corresponding API, so we have to solve it by ourselves

Ideas

Calculate the time difference between the early morning of the next day and the current time, and set the time difference as the expiration time of redis, we can achieve The desired effect

code

/**
     * 计算第二天凌晨与当前时间的时间差秒数
     * @param
     * @return java.lang.Long
     * @author shy
     * @date 2021/3/12 18:10
     */
    public static Long getNowToNextDaySeconds() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }

gets the time difference, and the rest is basically no problem.

Attached is the Redis tool class:

/**
 * 操作redis
 * @author shy
 * @date 2020/12/10 10:01
 */
@Service
public class RedisService {
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Autowired
    private RedisTemplate<String, Object> redisTemplate;
	
	/**
	 * 判断String类型key是否存在
	 *
	 * @param key
	 * @return 
	 * @author shy
	 * @date 2018年11月13日 下午1:40:37
	 */
	public boolean hasStringKey(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.opsForValue().getOperations().hasKey(key);
	}
	
	/**
	 * 判断String类型key是否存在
	 *
	 * @param key
	 * @return 
	 * @author shy
	 * @date 2018年11月13日 下午1:43:51
	 */
	public boolean nonStringKey(String key) {
		return !hasStringKey(key);
	}
	/**
	 * 设置String类型key,String类型value,过期时间timeout,TimeUnit
	 *
	 * @param key
	 * @param value
	 * @param timeout
	 * @param timeUnit
	 * @author shy
	 * @date 2018年12月10日13:53:38
	 */
	public void setStringKey(String key, String value, Long timeout, TimeUnit timeUnit) {
		if (StringUtils.isBlank(key) || Objects.isNull(timeout)) {
			throw new EmptyParameterException();
		}
		stringRedisTemplate.opsForValue().set(key, value, timeout, timeUnit);
	}
	
	public void setStringKey(String key, String value) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		stringRedisTemplate.opsForValue().set(key, value);
	}
	/**
	 * 获取String类型value
	 *
	 * @param key
	 * @return
	 * @author shy
	 * @date 2018年11月12日 下午7:09:31
	 */
	public String getStringValue(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.opsForValue().get(key);
	}
	
	/**
	 *	获取Key的过期时间
	 *
	 * @param key
	 * @return
	 * @author shy
	 * @date 2019年4月25日17:28:36
	 */
	public Long getExpire(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.getExpire(key);
	}
	
	/**
	 *	设置Key的过期时间
	 *
	 * @param key
	 * @return
	 * @author shy
	 * @date 2019年4月25日17:28:36
	 */
	public Boolean setExpire(String key,Long timeout, TimeUnit timeUnit) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.expire(key, timeout, timeUnit);
	}	
	
	/**
	 * value自增+n
	 * @param key
	 * @return
	 * @author shy
	 * @date 2019年4月8日15:54:30
	 */
	public Long setIncrementValue(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		return stringRedisTemplate.opsForValue().increment(key, 1L);
	}
	/**
	 * 设置String类型key,Object类型value,过期时间timeout
	 *
	 * @param key
	 * @param value
	 * @param timeout
	 * @author shy
	 * @date 2018年12月10日13:54:07
	 */
	public void setObjectKey(String key, Object value, Long timeout,TimeUnit time) {
		if (StringUtils.isBlank(key) || Objects.isNull(timeout)) {
			throw new EmptyParameterException();
		}
		redisTemplate.opsForValue().set(key, value, timeout, time);
	}
	
	public void setObjectKey(String key, Object value) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		redisTemplate.opsForValue().set(key, value);
	}
	
	/**
	 * 获取Object类型value
	 *
	 * @param key
	 * @param clazz
	 * @return 
	 * @author shy
	 * @date 2019年11月6日10:01:30
	 */
	@SuppressWarnings("unchecked")
	public <T> T getObjectValue(String key, Class<T> clazz) {
		if (StringUtils.isBlank(key)) {
			return null;
		}
		return (T) redisTemplate.opsForValue().get(key);
	}
	
	/**
	 * 移除单个String类型key
	 *
	 * @param key 
	 * @author shy
	 * @date 2018年11月13日 上午10:42:01
	 */
	public void removeSingleStringKey(String key) {
		if (StringUtils.isBlank(key)) {
			throw new EmptyParameterException();
		}
		stringRedisTemplate.opsForValue().getOperations().delete(key);
	}
	
	/**
	 * 移除Collection<String>类型keys
	 *
	 * @param keys 
	 * @author shy
	 * @date 2018年11月13日 下午3:15:16
	 */
	public void removeMultiStringKey(Collection<String> keys) {
		if (CollectionUtils.isNotEmpty(keys)) {
			stringRedisTemplate.opsForValue().getOperations().delete(keys);
		}
	}
	
	/**
	 * redis key 模糊查询
	 * @author shy
	 * @date 2021年1月4日 上午11:21:45
	 * @param key
	 * @return
	 */
	public Set<String> queryStringKeys(String key) {
		 return redisTemplate.keys(key + "*");
	}
}

redis expiration policy function introduction

When we use redis, we usually set an expiration time, of course There are also those that do not set an expiration time, that is, they will never expire.

When we set the expiration time, how does redis determine whether it has expired, and what strategy is used to delete it.

Set expiration time

When we set the key, we can give an expire time, which is the expiration time. For example, specify that this key can only survive for one hour. Suppose you set a batch of keys to survive for one hour. hour, then how does redis delete this batch of keys one hour later?

The answer is: regular deletion and lazy deletion.

The so-called regular deletion means that by default, redis randomly selects some keys with expiration time set every 100ms, checks whether they have expired, and deletes them if they expire. Traversing all keys with expiration times every 100ms will cause a significant performance drop, please note. Redis will actually randomly select some keys to check and delete every 100 milliseconds.

But the problem is that regular deletion may cause many expired keys to not be deleted when the time is up, so you need to delete them lazily. That is to say, when you get a key, redis will check to see if this key is set. Expiration time So has it expired? If it expires, it will be deleted.

By combining the above two methods, it is guaranteed that expired keys will be killed. All expired keys will not be automatically deleted when the expiration time is reached, so the memory usage will not be reduced after expiration.

But in fact this is still a problem. If a lot of expired keys are missed by regular deletion, and then they are not checked in time and lazy deletion is not carried out, it will cause a large number of expired keys to accumulate in the memory and consume redis memory. , how to deal with this situation?

The answer is: use the memory elimination mechanism.

Memory elimination

If redis takes up too much memory, some elimination will be carried out at this time. There are some strategies as follows:

  • noeviction: When the memory is not enough to accommodate the newly written data, the newly written data will report an error. This actual scenario is generally not used.

  • allkeys-lru: When the memory is not enough to accommodate the newly written data, in the key space, remove the least used key (this is the most commonly used )

  • allkeys-random: When the memory is not enough to accommodate the newly written data, a key is randomly removed from the key space. This is generally used. a bit less.

  • volatile-lru: When the memory is insufficient to accommodate newly written data, in the key space with an expiration time set, remove the least recently used key .

  • volatile-random: When the memory is insufficient to accommodate newly written data, a key is randomly removed from the key space with an expiration time set.

  • volatile-ttl: When the memory is not enough to accommodate the newly written data, in the key space with an expiration time set, there are keys with an earlier expiration time. Prioritize removal.

Memory elimination will trigger elimination conditions to delete certain keys. This is also the reason why keys are lost without setting an expiration time.

The above is the detailed content of What is the solution for Java to operate redis and set expiration in the early morning of the next day?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete