2016-09-21 63 views
0

我想頁面zrange之前關閉管道或多塊,得到錯誤:調用此方法之前請關閉管道或多塊,如何解決這個(我的集羣。不支持多命令https://github.com/CodisLabs/codis/blob/master/doc/unsupported_cmds.md)?redis.clients.jedis.exceptions.JedisDataException:請調用此方法

runWithPipeline(new JedisPipelinedCallback() { 
    @Override 
    public void execute(Pipeline pipeline) { 
    int offset = 0; 
    boolean finished = false; 

    do { 
     // need to paginate the keys 
     Set<byte[]> rawKeys = pipeline.zrange(rawKnownKeysKey, (offset) * PAGE_SIZE, (offset + 1) * PAGE_SIZE - 1).get(); 
     finished = rawKeys.size() < PAGE_SIZE; 
     offset++; 
     if (!rawKeys.isEmpty()) { 
     List<byte[]> regionedKeys = new ArrayList<byte[]>(); 
     for (byte[] rawKey : rawKeys) { 
      regionedKeys.add(getRegionedKey(rawRegion, rawKey)); 
     } 

     pipeline.del(regionedKeys.toArray(new byte[regionedKeys.size()][])); 
     } 
     pipeline.sync(); 
    } while (!finished); 

    pipeline.del(rawKnownKeysKey); 
    } 
}); 

//創建{@link redis.clients.jedis.JedisPool}實例。

public static JedisPool createJedisPool(Properties props) { 

    String host = props.getProperty(RedisConfig.HOST, "localhost"); 
    Integer port = Integer.decode(props.getProperty(RedisConfig.PORT, String.valueOf(Protocol.DEFAULT_PORT))); 
    Integer timeout = Integer.decode(props.getProperty(RedisConfig.TIMEOUT, String.valueOf(Protocol.DEFAULT_TIMEOUT))); // msec 
    String password = props.getProperty(RedisConfig.PASSWORD, null); 
    Integer database = Integer.decode(props.getProperty(RedisConfig.DATABASE, String.valueOf(Protocol.DEFAULT_DATABASE))); 

    log.info("create JedisPool. host=[{}], port=[{}], timeout=[{}], password=[{}], database=[{}]", 
      host, port, timeout, password, database); 

    return new JedisPool(createJedisPoolConfig(), host, port, timeout, password, database); 
} 

//創建{@link redis.clients.jedis.JedisPoolConfig}實例。

private static JedisPoolConfig createJedisPoolConfig() { 
    JedisPoolConfig poolConfig = new JedisPoolConfig(); 
    poolConfig.setMaxTotal(256); 
    poolConfig.setMinIdle(2); 
    return poolConfig; 
} 


Jedis jedis = jedisPool.getResource(); 


private void runWithPipeline(final JedisPipelinedCallback callback) { 
    final Jedis jedis = jedisPool.getResource(); 
    try { 
    final Pipeline pipeline = jedis.pipelined(); 
    callback.execute(pipeline); 
    // use #sync(), not #exec() 
    pipeline.sync(); 
    } finally { 
    jedisPool.returnResource(jedis); 
    } 
} 
+0

的問題可能是落後於這個方法的調用者。你能分享你如何處理Jedis實例嗎? –

+0

@JungtaekLim現在可以嗎? – Dreampie

+0

對不起,我不清楚這一點。你能分享你的代碼調用execute()嗎?我想看看Pipeline實例如何初始化並處理相關的Jedis實例。 –

回答

1

問題出現在代碼的這一部分,您嘗試使用.get()方法從管道檢索值。

Set<byte[]> rawKeys = pipeline.zrange(rawKnownKeysKey, (offset) * PAGE_SIZE, (offset + 1) * PAGE_SIZE - 1).get(); 

當你在管道發出命令(S),你需要檢索值執行已添加到管道中的所有命令,如果你嘗試發出同步之前得到的值之前發出的sync()命令()它會拋出錯誤,如上所述。

解決方案:

Response<Set<byte[]>> temp = pipeline.zrange(rawKnownKeysKey, (offset) * PAGE_SIZE, (offset + 1) * PAGE_SIZE - 1); 
pipeline.sync(); 
Set<byte[]> rawKeys = temp.get(); 
+0

是的,我想解決這個問題,但忘了評論。 –

相關問題