一、背景
- 需求:一次性獲取redis緩存中多個(gè)key的value
- 潛在隱患:循環(huán)key,獲取value,可能會(huì)造成連接池的連接數(shù)增多,連接的創(chuàng)建和摧毀,消耗性能
- 解決方法:根據(jù)項(xiàng)目中的緩存數(shù)據(jù)結(jié)構(gòu)的實(shí)際情況,數(shù)據(jù)結(jié)構(gòu)為string類型的,使用RedisTemplate的multiGet方法;數(shù)據(jù)結(jié)構(gòu)為hash,使用Pipeline(管道),組合命令,批量操作redis。
二、操作
-
RedisTemplate的multiGet的操作
針對(duì)數(shù)據(jù)結(jié)構(gòu)為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)方式一 : 基礎(chǔ)方式
使用類: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數(shù)據(jù)結(jié)構(gòu)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()); // 自定義序列化
三、說明
本文簡(jiǎn)單的舉了關(guān)于RedisTemplate的兩個(gè)例子,但大家千萬別以為只是批量取值的時(shí)候會(huì)用到,PipeLine其實(shí)是用來批量發(fā)送命令操作Redis。后來用Jedis也進(jìn)行了實(shí)現(xiàn),見下會(huì)分解。
如有不正確的地方,請(qǐng)大家指點(diǎn)