Redis集群批量操作
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集群批量操作的更多相关文章
- C# redis集群批量操作之slot计算出16384个字符串
引入一个大家都用的到的需求来说吧. 需求:要在三主三从的redis集群,存入数据,会对数据进行批量删除操作,数据要求要在redis集群负载均衡. 思路: 1.存入数据好办 1 var connect ...
- Redis集群最佳实践
今天我们来聊一聊Redis集群.先看看集群的特点,我对它的理解是要需要同时满足高可用性以及可扩展性,即任何时候对外的接口都要是基本可用的并具备一定的灾备能力,同时节点的数量能够根据业务量级的大小动态的 ...
- redis 集群配置实战
文章转载自:http://hot66hot.iteye.com/blog/2050676 最近研究Redis-cluster,正好搭建了一个环境,遇到了很多坑,系统的总结下,等到redis3 rele ...
- redis集群讨论
一.生产应用场景 二.存储架构演变 三.应用最佳实践 四.运维经验总结 第1.2节:介绍redis cluster在唯品会的生产应用场景,以及存储架构的演变.第3节:redis cluster的稳定性 ...
- Couchbase集群和Redis集群解析
Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...
- [转载] Redis集群搭建最佳实践
转载自http://blog.csdn.net/sweetvvck/article/details/38315149?utm_source=tuicool 要搭建Redis集群,首先得考虑下面的几个问 ...
- 【原创】那些年用过的Redis集群架构(含面试解析)
引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...
- 深入剖析Redis系列: Redis集群模式搭建与原理详解
前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...
- 那些年用过的Redis集群架构
今天我们来谈谈Redis集群这个话题,需要说明的是本文 适合人群:不知道自己生产redis集群架构,以及对Redis集群不了解的人 不适合群: 对自己生产Redis集群架构非常了解的人 本文预计分两个 ...
随机推荐
- 把myeclipse中的web项目导入eclipse中不能编程web项目的解决办法
title: 把myeclipse中的web项目导入eclipse中不能编程web项目的解决办法 tags: grammar_cjkRuby: true --- 右键单击项目,properties-- ...
- 【转】Pro Android学习笔记(四):了解Android资源(下)
处理任意的XML文件 自定义的xml文件放置在res/xml/下,可以通过R.xml.file_name来获取一个XMLResourceParser对象.下面是xml文件的例子: <rootna ...
- C# 32位程序在64位系统下运行中解决重定向问题
在64位的Windows操作系统中,为了兼容32位程序的运行,64位的Windows操作系统采用重定向机制.目的是为了能让32位程序在64位的操作系统不仅能操作关键文件文夹和关键的注册表并且又要避免与 ...
- 《Java多线程编程核心技术》读后感(十三)
类InheritableThreadLocal的使用 使用类InheritableThreadLocal可以在子线程中取得父线程继承下来的值 值继承 package Third; import jav ...
- 解析Xml文件的三种方式
1.Sax解析(simple api for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用回调函数来实现. clas ...
- pytest框架(五)
代码示例一 # coding=utf-8 import pytest @pytest.fixture() def login(): print("输入账号,密码先登录") def ...
- Centos7中给gitLab汉化
第一步:安装git 下载补西,东西在清华大学开源中心 yum install –y git 第二步:下载 git clone https://gitlab.com/xhang/gitlab.git 第 ...
- jsp学习与提高(三)——JSP Cookie 处理
1.cookie是什么 Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookie的支持. 通常有三个步骤来识别回头客: 服务 ...
- Mac下IDEA不能进行编辑
在安装Idea时,在选择插件的时候,把IDEAVim这个玩意儿选上了. 所以,编辑模式就跟命令行里面的Vim一样.输入时,需要先输入i, 进入insert模式下,然后才可以编辑. 彻底解决办法就是进入 ...
- Mac环境下制作ubantu安装盘
前言:ubantu为Linux发行版之一,此方法亦可制作其他Linux发行版 1.在磁盘工具中将准备好的u盘格式化为Mac OS扩展(日志型),并确保分区的模式是GUID分区 2.官网自行下载uban ...