一、背景
- 需求:一次性获取redis缓存中多个key的value
- 潜在隐患:循环key,获取value,可能会造成连接池的连接数增多,连接的创建和摧毁,消耗性能
- 解决方法:根据项目中的缓存数据结构的实际情况,数据结构为string类型的,使用RedisTemplate的multiGet方法;数据结构为hash,使用Pipeline(管道),组合命令,批量操作redis。
二、操作
-
RedisTemplate的multiGet的操作
针对数据结构为String类型
-
示例代码
List<String> keys = new ArrayList<>(); for (Book e : booklist) { String key = generateKey.getKey(e); keys.add(key); } List<Serializable> resultStr = template.opsForValue().multiGet(keys);
此方法还是比较好用,使用者注意封装。
-
RedisTemplate的Pipeline使用
1)方式一 : 基础方式
使用类:StringRedisTemplate
-
使用方法
public executePipelined(RedisCallback<?> action) {...}
-
示例代码:批量获取value
List<Object> redisResult = redisTemplate.executePipelined(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection redisConnection) throws DataAccessException { for (BooK e : booklist) { StringRedisConnection stringRedisConnection =(StringRedisConnection)redisConnection; stringRedisConnection.get(e.getId()); } return null; } });
- 方法二 : 使用自定义序列化方法
使用类:RedisTemplate
-
使用方法
public List<Object> executePipelined(final RedisCallback<?> action, final RedisSerializer<?> resultSerializer) {...}
-
示例代码:批量获取hash数据结构value
List<Object> redisResult = redisTemplate.executePipelined( new RedisCallback<String>() { // 自定义序列化 RedisSerializer keyS = redisTemplate.getKeySerializer(); @Override public String doInRedis(RedisConnection redisConnection) throws DataAccessException { for (BooK e : booklist) { redisConnection.hGet(keyS.serialize(e.getName()), keyS.serialize(e.getAuthor())); } return null; } }, redisTemplate.getValueSerializer()); // 自定义序列化
三、说明
本文简单的举了关于RedisTemplate的两个例子,但大家千万别以为只是批量取值的时候会用到,PipeLine其实是用来批量发送命令操作Redis。后来用Jedis也进行了实现,见下会分解。
如有不正确的地方,请大家指点