Redis在3.0版正式引入了集群这个特性,扩展变得非常简单。然而当你开心的升级到3.0后,却发现有些很好用的功能现在工作不了了, 比如我们今天要聊的pipeline功能等批量操作。

Redis集群是没法执行批量操作命令的,如mget,pipeline等。这是因为redis将集群划分为16383个哈希槽,不同的key会划分到不同的槽中。但是,Jedis客户端提供了计算key的slot方法,已经slot和节点之间的映射关系,通过这两个数据,就可以计算出每个key所在的节点,然后使用pipeline获取数据。

/**
* 根据key计算slot,
* 再根据slot计算node,
* 获取pipeline
* 进行批量操作
*/
public class BatchUtil {
public static Map<String, String> mget(JedisCluster jc, String... keys){
Map<String, String> resMap = new HashMap<>();
if(keys == null || keys.length == 0){
return resMap;
}
//如果只有一条,直接使用get即可
if(keys.length == 1){
resMap.put(keys[0], jc.get(keys[0]));
return resMap;
} //JedisCluster继承了BinaryJedisCluster
//BinaryJedisCluster的JedisClusterConnectionHandler属性
//里面有JedisClusterInfoCache,根据这一条继承链,可以获取到JedisClusterInfoCache
//从而获取slot和JedisPool直接的映射
MetaObject metaObject = SystemMetaObject.forObject(jc);
JedisClusterInfoCache cache = (JedisClusterInfoCache) metaObject.getValue("connectionHandler.cache");
//保存地址+端口和命令的映射
Map<JedisPool, List<String>> jedisPoolMap = new HashMap<>();
List<String> keyList = null;
JedisPool currentJedisPool = null;
Pipeline currentPipeline = 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);
}
} //保存结果
List<Object> res = new ArrayList<>();
//执行
for(Entry<JedisPool, List<String>> entry : jedisPoolMap.entrySet()){
try {
currentJedisPool = entry.getKey();
keyList = entry.getValue();
//获取pipeline
currentPipeline = currentJedisPool.getResource().pipelined();
for(String key : keyList){
currentPipeline.get(key);
}
//从pipeline中获取结果
res = currentPipeline.syncAndReturnAll();
currentPipeline.close();
for(int i=0; i<keyList.size(); i++){
resMap.put(keyList.get(i), res.get(i)==null ? null : res.get(i).toString());
}
} catch (Exception e) {
e.printStackTrace();
return new HashMap<>();
}
}
return resMap;
}
}

Redis集群批量操作的更多相关文章

  1. C# redis集群批量操作之slot计算出16384个字符串

    引入一个大家都用的到的需求来说吧. 需求:要在三主三从的redis集群,存入数据,会对数据进行批量删除操作,数据要求要在redis集群负载均衡. 思路: 1.存入数据好办 1 var connect ...

  2. Redis集群最佳实践

    今天我们来聊一聊Redis集群.先看看集群的特点,我对它的理解是要需要同时满足高可用性以及可扩展性,即任何时候对外的接口都要是基本可用的并具备一定的灾备能力,同时节点的数量能够根据业务量级的大小动态的 ...

  3. redis 集群配置实战

    文章转载自:http://hot66hot.iteye.com/blog/2050676 最近研究Redis-cluster,正好搭建了一个环境,遇到了很多坑,系统的总结下,等到redis3 rele ...

  4. redis集群讨论

    一.生产应用场景 二.存储架构演变 三.应用最佳实践 四.运维经验总结 第1.2节:介绍redis cluster在唯品会的生产应用场景,以及存储架构的演变.第3节:redis cluster的稳定性 ...

  5. Couchbase集群和Redis集群解析

    Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...

  6. [转载] Redis集群搭建最佳实践

    转载自http://blog.csdn.net/sweetvvck/article/details/38315149?utm_source=tuicool 要搭建Redis集群,首先得考虑下面的几个问 ...

  7. 【原创】那些年用过的Redis集群架构(含面试解析)

    引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...

  8. 深入剖析Redis系列: Redis集群模式搭建与原理详解

    前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...

  9. 那些年用过的Redis集群架构

    今天我们来谈谈Redis集群这个话题,需要说明的是本文 适合人群:不知道自己生产redis集群架构,以及对Redis集群不了解的人 不适合群: 对自己生产Redis集群架构非常了解的人 本文预计分两个 ...

随机推荐

  1. boobmarklet

    bookmarklet ,一般都称呼为小书签.它是一段 JavaScript 脚本,一般网络上的小书签都是一个链接,它的安装非常简单,只需要把链接拖到你的收藏夹里. 利用它,可以实现一些页面优化.性能 ...

  2. "The object cannot be deleted because it was not found in the ObjectStateManager."

    最近优化EF的性能时遇到一个问题, 当在EF生成的Entityes的构造里加上: this.protocolnodes.MergeOption = MergeOption.NoTracking;thi ...

  3. XML常用操作

    C#操作XML非常简单 一是写入: 生明一个xelment 再在它的父节点Add就可以,也可以用生明的节点.SetAttribute("节点名称","节点对应的值&quo ...

  4. [codeforces219D]Choosing Capital for Treeland树形dp

    题意:给出一棵树,带有向边,找出某个点到达所有点需要反转的最少的边. 解题关键:和求树的直径的思路差不多,将求(父树-子树)的最大值改为求特定值.依然是两次dfs,套路解法. 对树形dp的理解:树形d ...

  5. windows7如何打开远程桌面&nbsp;-…

    单位的机器,刚装上了windows7旗舰版(当然不是花银子滴),想打开远程桌面连接,这样从别的机器登录也方便.可是问题来了,windows7对安全的设置比较高,不像windows XP那么随便一点就可 ...

  6. Matcher的replaceAll ()/appendReplacement()/appendTail()详细举例

    直接上例子: package com.dajiangtai.djt_spider.util; import java.util.regex.Matcher;import java.util.regex ...

  7. C# 测试代码#if DEBUG使用

    代码示例: #if DEBUG      Console.WriteLine("DEBUG:11111111111"); #else       Console.WriteLine ...

  8. HighChar

    chart: { type:'bar', borderWidth:2, borderColor: '#CA5100', backgroundColor: '#90ED7D', shadow: { // ...

  9. [开发技巧]·TensorFlow&Keras GPU使用技巧

    [开发技巧]·TensorFlow&Keras GPU使用技巧 ​ 1.问题描述 在使用TensorFlow&Keras通过GPU进行加速训练时,有时在训练一个任务的时候需要去测试结果 ...

  10. poj1088(記憶化搜索)

    題目鏈接:http://poj.org/problem?id=1088 題意:中文題誒- 思路:dfs,不過直接dfs因該會超時,那我們給他加個記錄路徑就好了... 代碼: #include < ...