Spring Data Redis集群管道支持

3

是否有计划支持在连接到Redis集群版本时为Spring Data Redis库提供“流水线”操作。管道化和非管道化操作之间存在相当大的性能差异。如果没有这样的计划,还有哪些可行的选项?

2个回答

0

Spring Data Redis不支持在集群上使用pipeline。因此,我们可以在应用程序中自己实现。如果您使用spring-data-redis和Jedis库。

所以为了实现这一点,我们必须间接地从Jedis池中获取Jedis连接。现在,如果您只知道集群的键,那么首先需要找出与键相关联的槽位。您可以通过以下方式获得它。

int slot = JedisClusterCRC16.getSlot(hKey);

第二,你可以通过以下方式获取JedisCluster连接
JedisClusterConnection jedisClusterConnection = (JedisClusterConnection)stringRedisTemplate.getConnectionFactory().getClusterConnection();
JedisCluster jedisCluster = jedisClusterConnection.getNativeConnection();

现在你有了JedisCluster连接,但是仅此还不足以从Jedis池中获取Jedis连接。因为JedisCluster没有直接暴露连接处理程序,并且JedisSlotConnectionHandler类具有从槽位返回jedis连接的方法。所以为了实现这一点,我们需要将redis.clients.jedis包中的BinaryJedisCluster类复制到我们的应用程序中,使用相同的类和包名,并添加以下方法来暴露连接处理程序。
public JedisSlotBasedConnectionHandler getConnectionHandler() {
   return (JedisSlotBasedConnectionHandler) this.connectionHandler;
}

最后,你可以通过调用getJedisConnectionFromSlot(slot)方法来获取Jedis连接。
JedisSlotBasedConnectionHandler jedisClusterConnectionHandler = jedisCluster.getConnectionHandler();
Jedis connection = jedisClusterConnectionHandler.getConnectionFromSlot(slot);
Pipeline pipeline = connection.pipelined();
pipeline.somecommand....
pipeline.sync();

参考链接


0

Spring Data Redis 提供了几个 RedisTemplate 的方法来执行管道中的命令。如果您不关心管道操作的结果,可以使用标准的 execute 方法,并将 pipeline 参数设置为 true。executePipelined 方法将在管道中执行提供的 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;
  }
});

上面的示例在管道中执行了一个批量右弹出队列中的项目。结果列表包含所有弹出的项目。RedisTemplate使用其值、哈希键和哈希值序列化器在返回之前对所有结果进行反序列化,因此上面示例中返回的项目将是字符串。还有其他的executePipelined方法可以让您传递一个自定义的序列化器来处理管道结果。

请注意,从RedisCallback返回的值必须为null,因为该值会被丢弃,而返回的是管道命令的结果。

参考:http://docs.spring.io/spring-data/redis/docs/current/reference/html/#pipeline


我知道流水线方法;问题是在集群中使用流水线的用法。当在启用集群的Redis上使用流水线操作时,会抛出一个异常,该异常来自JedisClusterConnection。@Override public void openPipeline() { throw new UnsupportedOperationException("Pipeline is currently not supported for JedisClusterConnection."); }我正在使用版本1.7.7。我已经查看了1.8和2.0的代码,似乎都不支持流水线操作。 - undefined
我还尝试通过在集群上列出主节点,然后建立与节点的直接连接,并将其作为回调连接工厂传递给使用流水线执行的rest template。它可以顺利进行并保存了一些"sortedset"条目,但之后抛出了一个异常Redirect: slot 16034 to x.x.x.x:6379.; nested exception is redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 16034 x.x.x.x:6379,这基本上意味着我正在使用一个集群;很奇怪为什么只有少量条目被持久化了?Spring Data Redis专家有任何评论吗? - undefined
你可能会对这个链接感兴趣:http://www.jacarrichan.com/Spring-Data-Redis-Add-Support-For-Redis-Cluster/ - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接