1 過期策略
1.0 定期刪除
- 主動刪除
- 定期刪除設置一個時間間隔,每個時間段都會檢測是否有鍵過期,定期隨機抽取鍵檢查和刪除.
1.2 惰性刪除
- 被動刪除
- 惰性刪除不會在鍵過期是立即刪除,而是當外部獲取這個鍵時刪除.
1.3 定時刪除
- 主動刪除
- 創建鍵時設置過期時間,創建一個定時器,當鍵達到過期時間閾值時,立即刪除鍵,刪除該時刻過期的所有鍵,不會考慮此時機器所處狀態.
2 內存淘汰
序號 |
策略 |
描述 |
1 |
noeviction |
當內存不足以存儲新數據寫入時,新寫入操作報錯 |
2 |
allkeys-lru |
當內存不足以存儲新數據寫入時,在鍵空間中移除最近最少使用的key |
3 |
allkeys-random |
當內存不足以存儲新數據寫入時,在鍵空間中隨機移除某個key |
4 |
volatile-lru |
當內存不足以存儲新數據寫入時,在設置了過期時間的鍵中,移除最近最少使用的key |
5 |
volatile-random |
當內存不足以存儲新數據寫入時,在設置了過期時間的鍵中,隨機移除某個key |
6 |
volatile-ttl |
當內存不足以存儲新數據寫入時,在設置了過期時間的鍵中,優先移除有更早過期時間的key |
3 數據過期提醒
3.1 配置過期提醒
sudo vim /etc/redis/redis.conf
notify-keyspace-events Ex
3.2 配置監聽
package com.sb.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.Serializable;
import java.time.Duration;
import java.lang.reflect.Method;
@Configuration
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport{
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public KeyGenerator wiselyKeyGenerator(){
return new KeyGenerator(){
@Override
public Object generate(Object target, Method method, Object... params){
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for(Object obj:params){
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(60));
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean
public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory){
RedisTemplate<String, Serializable> template = new RedisTemplate<>();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory){
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
3.3 配置事件處理
package com.sb.util;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component
public class RedisKeyExpirationListenerUtil extends KeyExpirationEventMessageListener{
static Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListenerUtil.class);
public RedisKeyExpirationListenerUtil(RedisMessageListenerContainer listenerContainer){
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern){
String expiredKey = message.toString();
logger.info("data expired:{}", expiredKey);
}
}
4 小結
序號 |
描述 |
1 |
Redis過期清除策略有三種,定期清除,定時清除,惰性清除,其中惰性清除爲被動清除,定時和定期爲主動清除,定期爲定期隨機清除,定時爲清除所有過期數據 |
2 |
數據過期事件提醒配置Redis提醒,設定監聽容器及監聽事件,監聽事件中執行清除數據時的邏輯,同時可獲取刪除的key,通過key和持久化的數據庫同步數據 |
3 |
緩存過期數據和硬盤數據同步存儲,過期時同步刪除,保證服務宕機數據不丟失 |
【參考文獻】
[1]https://www.cnblogs.com/mengchunchen/p/10039467.html
[2]https://blog.csdn.net/qq_35981283/article/details/70156422
[3]https://www.jianshu.com/p/c37ad337146f
[4]https://www.jianshu.com/p/106f0eae07c8
[5]https://blog.csdn.net/m0_37367413/article/details/84320562