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集群架构非常了解的人 本文预计分两个 ...
随机推荐
- sublime插件insertDate显示ISO时间
1 下载insertDate插件以及安装完毕 2 把光标放在想插入ISO时间的地方 3 按住:alt+f5,之后,在sublime下面的Date format string输入:iso.之后按ente ...
- 使用EA完成数据库设计
开始重构之后对于EA的了解也逐渐增多,今天就总结一下如何使用EA完成对数据库的设计.下边的图分别是截自机房收费系统和牛腩新闻开发的数据库,因为我第一遍写的时候是在机房合作的时候,而后建立牛腩新闻发布系 ...
- C++ std::pair
pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存.另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair. ...
- Python之文件输入输出,
文件输入与输出 • 打开文件返回文件对象 – file_object=open(file_name,access_mode='r') • 关闭文件对象 – file_object.close() ...
- 如何解决WAMP Server 与IIS端口冲突问题
PHP也是一门开发网页的语言,WAMP Server 是它的一个较好的集成开发环境,今日,小编发现好多Wamp Server 安装后启动local host 出现的却是IIS页面!为什么会这样呢? 出 ...
- C#生成满足特定要求的密码
代码1 Random m_rnd = new Random(); public char getRandomChar() { ); || (ret > && ret < ) ...
- 超级实用的Chrome插件
1.JSON-handle:浏览器前台访问后台,后台返回json,它帮你格式化 2.Page Ruler:帮你测量页面上任何位置的长宽高 3. Momentum:打开新的tab页就像打开了一个新的世界 ...
- 网站特效离不开脚本,javascript是最常用的脚本语言,我们归纳一下常用的基础函数和语法:
转载自网络,非原创 1.输出语句:document.write(""); 2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head ...
- C++11之lambda表达式解析
什么是Lanmbda? 简短函数,就地书写.常用于向函数(算法)传递函数参数. 语法 Lambda 表达式,[capture](paras)mutable->return type{statem ...
- pandas基础(2)_多重索引
1:多重索引的构造 >>> #下面显示构造pd.MultiIndex >>> df1=DataFrame(np.random.randint(0,150,size= ...