在Redis集群中使用pipeline批量插入的实现方法
由于项目中需要使用批量插入功能,所以在网上查找到了Redis批量插入可以使用pipeline来高效的插入,示例代码如下:
Stringkey="key"; Jedisjedis=newJedis("xx.xx.xx.xx"); Pipelinep=jedis.pipelined(); ListmyData=....//要插入的数据列表 for(Stringdata: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.具体实现如下
//初始化得到了jediscluster,如何获取HostAndPort集合代码就不写了 Setnodes=..... JedisClusterjedisCluster=newJedisCluster(nodes); Map nodeMap=jedisCluster.getClusterNodes(); StringanyHost=nodeMap.keySet().iterator().next(); //getSlotHostMap方法在下面有 TreeMap slotHostMap=getSlotHostMap(anyHost);
privatestaticTreeMapgetSlotHostMap(StringanyHostAndPortStr){ TreeMap tree=newTreeMap (); Stringparts[]=anyHostAndPortStr.split(":"); HostAndPortanyHostAndPort=newHostAndPort(parts[0],Integer.parseInt(parts[1])); try{ Jedisjedis=newJedis(anyHostAndPort.getHost(),anyHostAndPort.getPort()); List
上面这几步可以在初始化的时候就完成.不需要每次都调用,把nodeMap和slotHostMap都定义为静态变量.
//获取槽号 intslot=JedisClusterCRC16.getSlot(key); //获取到对应的Jedis对象 Map.Entryentry=slotHostMap.lowerEntry(Long.valueOf(slot)); Jedisjedis=nodeMap.get(entry.getValue()).getResource();
建议上面这步操作可以封装成一个静态方法,比如命名为publicstaticJedisgetJedisByKey(Stringkey)之类的.意思就是在集群中,通过key获取到这个key所对应的Jedis对象.
这样再通过上面的jedis.pipelined();来就可以进行批量插入了.
注:这个方法是从Google上搜来的,直到目前我使用起来还没发现什么问题.如果哪位大神发现有什么不对的地方欢迎提出来.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。