2017-02-27 107 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