写在前面:
最近redis用的多,今天总结一下遇到的几个技巧和问题
最近redis用的多,今天总结一下遇到的几个技巧和问题
getAndDel
在win系统上的redis是没有getAndDel这个命令的,所以是不能使用stringtemplate操作。
需要使用get之后在del
批量getAndDel
这个是手动封装一个工具
public List<String> getAndDelBatch(final Collection<String> keys) {
List<String> list = template.opsForValue().multiGet(keys);
template.delete(keys);
return list;
}
scan通配
这个是通配key。由于keys会影响高并发下的效率,一般用scan来进行。
下面案例在于匹配对应的key获取并删除。
List<byte[]> list = template.execute((RedisCallback<List<byte[]>>) connection -> {
Set<byte[]> keysTmp = new HashSet<>();
//count 是最大的匹配数量
Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(RedisConstants.SMS_RECORD_CODE + "*").count(1000).build());
while (cursor.hasNext()) {
keysTmp.add(cursor.next());
}
if (keysTmp.isEmpty()) {
return null;
}
byte[][] keys = keysTmp.toArray(new byte[0][]);
List<byte[]> bytes = connection.mGet(keys);
connection.del(keys);
return bytes;
});
}
redis自动连接。
// 设置端口最大连接时间,-1超时连接设置为不断连接
shutdown-timeout: -1
如果redis宕机的解决方案。
redis如果连接不上,springboot执行报错,从而导致正常业务造成错误。
所以我们需要重写异常处理的方法
重写继承CachingConfigurer的errorHandler方法,直接打印就可以了。
/**
* 配置当redis连接不上时被缓存注解标注的方法绕过Redis
*/
@Bean
@Override
public CacheErrorHandler errorHandler() {
return new CacheErrorHandler() {
@Override
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
log.error("redis异常:key=[{}]", key, exception);
}
@Override
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
log.error("redis异常:key=[{}]", key, exception);
}
@Override
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
log.error("redis异常:key=[{}]", key, exception);
}
@Override
public void handleCacheClearError(RuntimeException exception, Cache cache) {
log.error("redis异常:", exception);
}
};
}
问题:很久才有响应结果。
缩小redis的读取超时timeout时间。
但是我发现需要2个timeout时间才会执行正常的逻辑,所以我选择700ms
redis:
database: 5
host: localhost
port: 6379
timeout: 700ms