简体   繁体   English

Spring Data Redis集群管道支持

[英]spring data redis cluster pipeline support

Is there a plan to support "pipelined" operations for the spring data redis library when connecting to redis clustered version. 连接到Redis集群版本时,是否有计划支持Spring数据Redis库的“流水线”操作。 There is considerable performance differences between pipelined & non-pipelined operations. 流水线操作与非流水线操作之间存在相当大的性能差异。 If there is no such plan what are other viable options? 如果没有这样的计划,还有哪些可行的选择?

Spring Data Redis provides several RedisTemplate methods for executing commands in a pipeline. Spring Data Redis提供了几种RedisTemplate方法来执行管道中的命令。 If you don't care about the results of the pipelined operations, you can use the standard execute method, passing true for the pipeline argument. 如果您不关心管道操作的结果,则可以使用标准的execute方法,为管道参数传递true。 The executePipelined methods will execute the provided RedisCallback or SessionCallback in a pipeline and return the results. executePipelined方法将在管道中执行提供的RedisCallback或SessionCallback并返回结果。 For example: 例如:

//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;
  }
});

The example above executes a bulk right pop of items from a queue in a pipeline. 上面的示例从管道中的队列中执行项目的批量右弹出。 The results List contains all of the popped items. 结果列表包含所有弹出项目。 RedisTemplate uses its value, hash key, and hash value serializers to deserialize all results before returning, so the returned items in the above example will be Strings. RedisTemplate使用其值,哈希键和哈希值序列化器在返回之前对所有结果进行反序列化,因此,上面示例中返回的项目将为Strings。 There are additional executePipelined methods that allow you to pass a custom serializer for pipelined results. 还有其他的executePipelined方法,使您可以传递自定义序列化程序以获取管道化结果。

Note that the value returned from the RedisCallback is required to be null, as this value is discarded in favor of returning the results of the pipelined commands. 请注意,从RedisCallback返回的值必须为null,因为为了支持返回管线命令的结果而将其丢弃。

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

Spring data redis does not supports the pipeline on cluster. Spring Data Redis不支持集群上的管道。 So We can do it by our self in our application. 因此,我们可以在应用程序中自行完成。 If you use spring-data-redis and Jedis library. 如果您使用spring-data-redis和Jedis库。

So for that, we have to take Jedis Connection indirectly from Jedis Pool. 因此,我们必须从Jedis Pool间接获取Jedis Connection。 Now if you only know keys of cluster then for that first you need to find out slot associated to key. 现在,如果您仅知道集群的密钥,那么首先需要找出与密钥关联的插槽。 You can get it by following way. 您可以通过以下方式获得它。

int slot = JedisClusterCRC16.getSlot(hKey);

Second, you can get JedisCluster connection by following way 其次,您可以通过以下方式获得JedisCluster连接

JedisClusterConnection jedisClusterConnection = (JedisClusterConnection)stringRedisTemplate.getConnectionFactory().getClusterConnection();
JedisCluster jedisCluster = jedisClusterConnection.getNativeConnection();

Now you have JedisCluster connection but it is not enough to get Jedis connection from Jedis pool. 现在您已经有了JedisCluster连接,但这还不足以从Jedis池获得Jedis连接。 Because JedisCluster not exposing connection handler directly and JedisSlotConnectionHandler classing having method which returns the jedis connection from slot. 因为JedisCluster没有直接公开连接处理程序,并且JedisSlotConnectionHandler具有从插槽返回jedis连接的方法。 so for that we have to copy the BinaryJedisCluster class from package redis.clients.jedis into our application with same class and package name and you have to add following method to expose connection handler. 因此,我们必须使用相同的类和包名称将包redis.clients.jedisBinaryJedisCluster类复制到我们的应用程序中,并且您必须添加以下方法来公开连接处理程序。

public JedisSlotBasedConnectionHandler getConnectionHandler() {
   return (JedisSlotBasedConnectionHandler) this.connectionHandler;
}

Finally, you can able to get Jedis Connection by calling getJedisConnectionFromSlot(slot) method 最后,您可以通过调用getJedisConnectionFromSlot(slot)方法获取Jedis Connection。

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

Reference link 参考链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM