2017-02-27 212 views
1

是否有计划在连接到redis集群版本时支持弹簧数据redis库的“流水线”操作。流水线操作的流水线操作有很大的性能差异。如果没有这样的计划,其他可行的选择是什么?spring data redis集群管道支持

回答

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在返回之前使用其值,散列键和散列值序列化程序对所有结果进行反序列化,因此上面示例中返回的项目将是Strings。还有另外的executePipelined方法,允许您为流水线结果传递自定义序列化程序。

请注意,从RedisCallback返回的值必须为空,因为此值将被丢弃,以支持返回流水线命令的结果。

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

+0

我知道流水线方法;问题是对[cluster]使用pipelined(http://docs.spring.io/spring-data/redis/docs/current/reference/html/#cluster)当在启用了redis的集群上使用流水线操作时,它会抛出例外;这来自JedisClusterConnection \t'@覆盖 \t公共无效openPipeline(){ \t \t抛出新UnsupportedOperationException异常( “目前不支持JedisClusterConnection管道。”); \t}'我正在使用1.7.7版本。我已经看了1.8和2的代码。0以及它似乎不被支持。 – punjabicoder

+0

我也尝试了在集群上列出主节点,然后建立到节点的直接连接,并使用流水线执行将该节点作为回调连接工厂传递给其余模板。它通过并保存了很少的条目“sortedset”后抛出一个例外'重定向:插槽16034到x.x.x.x:6379。嵌套异常是redis.clients.jedis.exceptions.JedisMovedDataException:MOVED 16034 x.x.x.x:6379'这基本上意味着我正在使用一个集群;感到惊讶的是有几个条目持续存在?春季数据redis专家有何评论? – punjabicoder

+0

你可能会发现这个http://www.jacarrichan.com/Spring-Data-Redis-Add-Support-For-Redis-Cluster/有趣 – mhshimul

0

春Redis的数据不支持群集的管道。所以我们可以在我们的应用程序中通过我们自己做到。如果你使用spring-data-redis和Jedis库。

因此,我们必须从Jedis Pool间接获取Jedis Connection。现在,如果您只知道群集的密钥,那么首先需要找出与密钥关联的插槽。你可以通过以下方式得到它。

int slot = JedisClusterCRC16.getSlot(hKey); 

其次,您可以通过以下方式

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

得到JedisCluster连接现在你有JedisCluster连接,但它不是足以让Jedis从Jedis池连接。由于JedisCluster不直接暴露连接处理程序和JedisSlotConnectionHandler分类具有从插槽返回jedis连接的方法。所以为此,我们必须将BinaryJedisCluster类中的类从包redis.clients.jedis复制到具有相同类和包名称的应用程序中,并且必须添加以下方法来公开连接处理程序。

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(); 

Reference link