SpringDataRedis集群管道支持

SpringDataRedis集群管道支持,spring,redis,cluster-computing,Spring,Redis,Cluster Computing,在连接到redis群集版本时,是否有计划支持spring data redis库的“流水线”操作。流水线操作和非流水线操作之间存在相当大的性能差异。如果没有这样的计划,还有什么其他可行的选择?Spring Data Redis提供了几种RedisTemplate方法,用于在管道中执行命令。如果您不关心流水线操作的结果,那么可以使用标准的execute方法,为管道参数传递true。ExecutePielined方法将在管道中执行提供的RedisCallback或SessionCallback,并返

在连接到redis群集版本时,是否有计划支持spring data redis库的“流水线”操作。流水线操作和非流水线操作之间存在相当大的性能差异。如果没有这样的计划,还有什么其他可行的选择?

Spring Data Redis提供了几种RedisTemplate方法,用于在管道中执行命令。如果您不关心流水线操作的结果,那么可以使用标准的execute方法,为管道参数传递true。ExecutePielined方法将在管道中执行提供的RedisCallback或SessionCallback,并返回结果。例如:

//pop a specified number of items from a queue
List<Object> results = stringRedisTemplate.executePipelined(
  new RedisCallback<Object>() {
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
      StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
      for(int i=0; i< batchSize; i++) {
        stringRedisConn.rPop("myqueue");
      }
    return null;
  }
});
//从队列中弹出指定数量的项
列表结果=stringRedisTemplate.ExecutePilined(
新的回调函数(){
公共对象doInRedis(重新连接)引发DataAccessException{
StringRedisConnection stringRedisConn=(StringRedisConnection)连接;
对于(int i=0;i
上面的示例执行管道中队列中项目的大容量右pop。结果列表包含所有弹出的项目。RedisTemplate使用其值、散列键和散列值序列化程序在返回之前对所有结果进行反序列化,因此上述示例中返回的项将是字符串。还有其他ExecutePiline方法,允许您为流水线结果传递自定义序列化程序

请注意,RedisCallback返回的值必须为null,因为为了返回流水线命令的结果,该值被丢弃


参考资料:

Spring data redis不支持集群上的管道。因此,我们可以在应用程序中自行完成。如果您使用spring数据redis和Jedis库

因此,我们必须从绝地池中间接获取绝地连接。现在若你们只知道集群的密钥,那个么首先你们需要找出和密钥相关的插槽。你可以通过下面的方法得到它

int slot = JedisClusterCRC16.getSlot(hKey);
其次,您可以通过以下方式获得JedisCluster连接

JedisClusterConnection jedisClusterConnection = (JedisClusterConnection)stringRedisTemplate.getConnectionFactory().getClusterConnection();
JedisCluster jedisCluster = jedisClusterConnection.getNativeConnection();
现在你有了绝地群连接,但仅仅从绝地池获得绝地连接是不够的。因为JedisCluster不直接公开连接处理程序,而且具有从插槽返回jedis连接的方法。因此,我们必须使用相同的类和包名将
BinaryJedisCluster
类从package
redis.clients.jedis
复制到我们的应用程序中,并且您必须添加以下方法来公开连接处理程序

public JedisSlotBasedConnectionHandler getConnectionHandler() {
   return (JedisSlotBasedConnectionHandler) this.connectionHandler;
}
最后,您可以通过调用
getJedisConnectionFromSlot(slot)
方法获得绝地连接

JedisSlotBasedConnectionHandler jedisClusterConnectionHandler = jedisCluster.getConnectionHandler();
Jedis connection = jedisClusterConnectionHandler.getConnectionFromSlot(slot);
Pipeline pipeline = connection.pipelined();
pipeline.somecommand....
pipeline.sync();

我知道流水线方法;问题是流水线的使用,当流水线操作在支持集群的redis上使用时,它会引发异常;来自JedisClusterConnection
@Override public void openPipeline(){抛出新的UnsupportedOperationException(“管道当前不支持JedisClusterConnection”);}
我使用的是1.7.7版。我查看了1.8和2.0的代码,但它似乎不受支持。我还尝试列出集群上的主节点,然后建立与节点的直接连接,并使用流水线执行将其作为回调连接工厂传递给rest模板。在抛出异常
重定向:插槽16034到x.x.x.x:6379之后,它将通过并保存几个条目“sortedset”。;嵌套异常是redis.clients.jedis.exceptions.JedisMovedDataException:MOVED 16034 x.x.x:6379
,这基本上意味着我正在使用集群;惊讶地发现只有很少的条目被保留?spring data redis专家有何评论?您可能会发现这很有趣