香港云主机最佳企业级服务商!

ADSL拨号VPS包含了中国大陆(联通,移动,电信,)

中国香港,国外拨号VPS。

当前位置:云主机 > Redis >

电信ADSL拨号VPS
联通ADSL拨号VPS
移动ADSL拨号VPS

在Redis集群中使用pipeline批量插入的实现方法


时间:2020-11-14 13:50 作者:admin610456


由于项目中需要使用批量插入功能, 所以在网上查找到了Redis 批量插入可以使用pipeline来高效的插入, 示例代码如下:

String key = "key";Jedis jedis = new Jedis("xx.xx.xx.xx");Pipeline p = jedis.pipelined();List<String> myData = .... //要插入的数据列表for(String data: myData){  p.hset(key, data);}p.sync();jedis.close();

但实际上遇到的问题是,项目上所用到的Redis是集群,初始化的时候使用的类是JedisCluster而不是Jedis. 去查了JedisCluster的文档, 并没有发现提供有像Jedis一样的获取Pipeline对象的 pipelined()方法.

Google了一下, 发现了解决方案.

Redis集群规范有说: Redis 集群的键空间被分割为 16384 个槽(slot), 集群的最大节点数量也是 16384 个。每个主节点都负责处理 16384 个哈希槽的其中一部分。当我们说一个集群处于“稳定”(stable)状态时, 指的是集群没有在执行重配置(reconfiguration)操作, 每个哈希槽都只由一个节点进行处理。

所以我们可以根据要插入的key知道这个key所对应的槽的号码, 再通过这个槽的号码从集群中找到对应Jedis. 具体实现如下

//初始化得到了jedis cluster, 如何获取HostAndPort集合代码就不写了Set<HostAndPort> nodes = .....JedisCluster jedisCluster = new JedisCluster(nodes);Map<String, JedisPool> nodeMap = jedisCluster.getClusterNodes();String anyHost = nodeMap.keySet().iterator().next();//getSlotHostMap方法在下面有TreeMap<Long, String> slotHostMap = getSlotHostMap(anyHost); 
  private static TreeMap<Long, String> getSlotHostMap(String anyHostAndPortStr) {    TreeMap<Long, String> tree = new TreeMap<Long, String>();    String parts[] = anyHostAndPortStr.split(":");    HostAndPort anyHostAndPort = new HostAndPort(parts[0], Integer.parseInt(parts[1]));    try{      Jedis jedis = new Jedis(anyHostAndPort.getHost(), anyHostAndPort.getPort());      List<Object> list = jedis.clusterSlots();      for (Object object : list) {        List<Object> list1 = (List<Object>) object;        List<Object> master = (List<Object>) list1.get(2);        String hostAndPort = new String((byte[]) master.get(0)) + ":" + master.get(1);        tree.put((Long) list1.get(0), hostAndPort);        tree.put((Long) list1.get(1), hostAndPort);      }      jedis.close();    }catch(Exception e){          }    return tree;  }

上面这几步可以在初始化的时候就完成. 不需要每次都调用, 把nodeMap和slotHostMap都定义为静态变量.

//获取槽号int slot = JedisClusterCRC16.getSlot(key); //获取到对应的Jedis对象Map.Entry<Long, String> entry = slotHostMap.lowerEntry(Long.valueOf(slot));Jedis jedis = nodeMap.get(entry.getValue()).getResource();

建议上面这步操作可以封装成一个静态方法, 比如命名为public static Jedis getJedisByKey(String key) 之类的. 意思就是在集群中, 通过key获取到这个key所对应的Jedis对象.

这样再通过上面的jedis.pipelined();来就可以进行批量插入了.

注:这个方法是从Google上搜来的, 直到目前我使用起来还没发现什么问题. 如果哪位大神发现有什么不对的地方欢迎提出来.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

(责任编辑:admin)






帮助中心
会员注册
找回密码
新闻中心
快捷通道
域名登录面板
虚机登录面板
云主机登录面板
关于我们
关于我们
联系我们
联系方式

售前咨询:17830004266(重庆移动)

企业QQ:383546523

《中华人民共和国工业和信息化部》 编号:ICP备00012341号

Copyright © 2002 -2018 香港云主机 版权所有
声明:香港云主机品牌标志、品牌吉祥物均已注册商标,版权所有,窃用必究

云官方微信

在线客服

  • 企业QQ: 点击这里给我发消息
  • 技术支持:383546523

  • 公司总台电话:17830004266(重庆移动)
  • 售前咨询热线:17830004266(重庆移动)