redis集群批量操作工具RedisBatchUtil

redis集群批量操作工具

package com.luo.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.*;
import redis.clients.util.JedisClusterCRC16;

import java.util.*;

/**
* @author luowuhui
* @描述 redis集群 批量工具
* @date 2018-09-19 10:29 */ @Slf4j public class RedisBatchUtil { /** * author: luowuhui * 功能描述 批量HgetAll * * @param jc JedisCluster对象 * @param keys key * @name mHgetAll awifi_ * @return: java.util.Map */ public static Map> mHgetAll(JedisCluster jc, List keys) { log.debug("{}",keys.size()); long startTime = System.currentTimeMillis(); if (keys == null || keys.size() == 0) { return new HashMap<>(0); } Map> resMap = new HashMap<>(); //如果只有一条,直接使用get即可 if (keys.size() == 1) { resMap.put(keys.get(0), jc.hgetAll(keys.get(0))); return resMap; } Map> jedisPoolMap = getJedisPoolMap(jc, keys); //保存结果 List res; //执行 for (Map.Entry> entry : jedisPoolMap.entrySet()) { Jedis jedis = null; try { JedisPool currentJedisPool = entry.getKey(); List keyList = entry.getValue(); jedis = currentJedisPool.getResource(); // 获取pipeline Pipeline currentPipeline = jedis.pipelined(); for (String key : keyList) { currentPipeline.hgetAll(key); } // 从pipeline中获取结果 res = currentPipeline.syncAndReturnAll(); currentPipeline.close(); for (int i = 0; i < keyList.size(); i++) { resMap.put(keyList.get(i), res.get(i) == null ? new HashMap<>(0) : (Map) res.get(i)); } } catch (Exception e) { e.printStackTrace(); return new HashMap<>(0); } finally { returnResource(jedis); } } long entTime = System.currentTimeMillis(); log.debug("RedisBatch_HgetAll time:{}", entTime - startTime); return resMap; } /** * author: luowuhui * 功能描述 批量Hget * * @param jc JedisCluster对象 * @param keys key * @name mHgetAll * @return: java.util.Map */ public static Map mHget(JedisCluster jc, List keys, String field) { long startTime = System.currentTimeMillis(); if (keys == null || keys.size() == 0) { log.debug("批量Hget参数keys为空"); return new HashMap<>(0); } Map resMap = new HashMap<>(); //如果只有一条,直接使用get即可 if (keys.size() == 1) { log.debug("批量Hget参数keys为1"); resMap.put(keys.get(0), jc.hget(keys.get(0), field)); return resMap; } Map> jedisPoolMap = getJedisPoolMap(jc, keys); //保存结果 List res; //执行 for (Map.Entry> entry : jedisPoolMap.entrySet()) { Jedis jedis = null; try { JedisPool currentJedisPool = entry.getKey(); List keyList = entry.getValue(); jedis = currentJedisPool.getResource(); // 获取pipeline Pipeline currentPipeline = jedis.pipelined(); for (String key : keyList) { currentPipeline.hget(key, field); } // 从pipeline中获取结果 res = currentPipeline.syncAndReturnAll(); currentPipeline.close(); for (int i = 0; i < keyList.size(); i++) { resMap.put(keyList.get(i), res.get(i) == null ? null : (String) res.get(i)); } } catch (Exception e) { e.printStackTrace(); return new HashMap<>(0); } finally { returnResource(jedis); } } long entTime = System.currentTimeMillis(); log.debug("RedisBatch_Hget time:{}", entTime - startTime); return resMap; } /** *批量更新数据 * @param jc * @param hash * @return */ public static long hmset(JedisCluster jc, Map> hash) { log.info("hash大小:{}",hash.size()); if (hash == null || hash.size() == 0) { return 0L; } if (hash.size() == 1) { long count = hash.entrySet().stream().filter(map -> { if (map.getValue() != null && map.getKey() != null && map.getValue().size() > 0) { String hmset = jc.hmset(map.getKey(), map.getValue()); return true; } return false; }).count(); return count; } //获取key, 获取地址+端口和命令的映射 Map> jedisPoolMap = getJedisPoolMap(jc, new ArrayList(hash.keySet())); long count = 0L; //执行 for (Map.Entry> entry : jedisPoolMap.entrySet()) { Jedis jedis = null; try { JedisPool currentJedisPool = entry.getKey(); List keyList = entry.getValue(); jedis = currentJedisPool.getResource(); // 获取pipeline Pipeline currentPipeline = jedis.pipelined(); for (String key : keyList) { Map mapHash = hash.get(key); if (mapHash != null && mapHash.size() > 0) { currentPipeline.hmset(key, hash.get(key)); count++; }else{ log.warn("key:{}的值为Null",key); } } // 从pipeline中获取结果 currentPipeline.syncAndReturnAll(); currentPipeline.close(); } catch (Exception e) { e.printStackTrace(); } finally { returnResource(jedis); } } log.info("redis批量更新数量:{}",count); return count; } /** * 获取地址+端口和命令的映射 * * @param jc * @param keys * @return */ private static Map> getJedisPoolMap(JedisCluster jc, List keys) { //JedisCluster继承了BinaryJedisCluster //BinaryJedisCluster的JedisClusterConnectionHandler属性 //里面有JedisClusterInfoCache,根据这一条e继承链,可以获取到JedisClusterInfoCache //从而获取slot和JedisPool直接的映射 MetaObject metaObject = SystemMetaObject.forObject(jc); JedisClusterInfoCache cache = (JedisClusterInfoCache) metaObject.getValue("connectionHandler.cache"); //保存地址+端口和命令的映射 Map> jedisPoolMap = new HashMap<>(); List keyList = null; JedisPool currentJedisPool = null; for (String key : keys) { //计算哈希槽 int crc = JedisClusterCRC16.getSlot(key); //通过哈希槽获取节点的连接 currentJedisPool = cache.getSlotPool(crc); //由于JedisPool作为value保存在JedisClusterInfoCache中的一个map对象中,每个节点的 //JedisPool在map的初始化阶段就是确定的和唯一的,所以获取到的每个节点的JedisPool都是一样 //的,可以作为map的key if (jedisPoolMap.containsKey(currentJedisPool)) { jedisPoolMap.get(currentJedisPool).add(key); } else { keyList = new ArrayList<>(); keyList.add(key); jedisPoolMap.put(currentJedisPool, keyList); } } return jedisPoolMap; } /** * 返还到连接池 * * @param jedis */ public static void returnResource(Jedis jedis) { if (jedis != null) { log.debug("jedis返还到连接池"); jedis.close(); } } /** * redis 的keys功能 * * @param jedisCluster * @param pattern 匹配字段 * @return */ public static TreeSet keys(JedisCluster jedisCluster, String pattern) { log.debug("Start getting keys..."); TreeSet keys = new TreeSet<>(); Map clusterNodes = jedisCluster.getClusterNodes(); for (Map.Entry entry : clusterNodes.entrySet()) { log.debug("Getting keys from: {}", entry.getKey()); JedisPool jp = clusterNodes.get(entry.getKey()); Jedis connection=null; try { connection = jp.getResource(); keys.addAll(connection.keys(pattern)); } catch (Exception e) { log.error("Getting keys error: {}", e); } finally { log.debug("Connection closed."); returnResource(connection); //用完一定要close这个链接!!! } } log.debug("Keys gotten!"); return keys; } }

你可能感兴趣的:(redis)