shardedJedis沒法設置DB的問題

        本人一直從事java研發,java版本的redis客戶端一般使用的是jedis。在以前生產開發過程當中,redis主要以單機形式或者主備讀寫分離形式使用,並未涉及到分片等高級功能。最近,因爲業務量激增,單機redis的性能出現了瓶頸,主要是redis消耗cpu太高。因而,想採用數據分片的方式,將請求路由到其餘redis實例上去,下降單機redis的壓力,該方案具體的實現方式是使用客戶端的ShardedJedis對象來實現數據分片。java

  因爲系統以前的緩存設計使用了redis多個db分區存儲數據,在使用ShardedJedis分片存取的過程當中發現,ShardedJedis不支持動態選擇DB,該對象沒有select功能。爲何呢?ShardedJedis其實是一個虛擬鏈接,一個ShardJedis對應了多個物理鏈接,經過一致性哈希算法計算key的哈希值,而後得到相應的物理鏈接,再發送存儲命令,實現存儲操做。ShardJedis中對應的物理鏈接必須保持一致,才能保證分片存儲數據的一致性,所以,ShardJedis不支持select操做。redis

  若是必定要實現選擇DB,怎麼辦呢?也不是沒有辦法的,只要把ShardJedis對應的全部物理鏈接客戶端都設置爲同一個db便可,下面是代碼示例:算法

public class RedisShardPoolTest {
    private static ShardedJedisPool shardedJedisPool;
    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(100);
        poolConfig.setMaxIdle(50);
        poolConfig.setMinIdle(10);
        poolConfig.setMaxWaitMillis(1000 * 60);
        poolConfig.setTestOnBorrow(true);

        String host = "127.0.0.1";
        int portA = 6379;
        int portB = 6378;

        List<JedisShardInfo> jdsInfoList = new ArrayList<JedisShardInfo>(2);
        JedisShardInfo infoA = new JedisShardInfo(host, portA);
        JedisShardInfo infoB = new JedisShardInfo(host, portB);
        jdsInfoList.add(infoA);
        jdsInfoList.add(infoB);
        shardedJedisPool = new ShardedJedisPool(poolConfig, jdsInfoList);
    }

    public static void main(String[] args) {
        ShardedJedis jds = shardedJedisPool.getResource();
        Collection<Jedis> collection=jds.getAllShards();
        Iterator<Jedis> jedis = collection.iterator();
        while(jedis.hasNext()){
            jedis.next().select(1);
        }

        ShardedJedisPipeline pipeline = jds.pipelined();

        for(int i=0; i<100; i++) {
            String key = generateKey();
            System.out.println(key + ":" + jds.getShard(key).getClient().getPort());
            System.out.println(pipeline.set(key,Math.random() + ""));
        }

        pipeline.sync();
    }

    private static int index = 1;
    public static String generateKey(){
         return String.valueOf(Thread.currentThread().getId())+"_"+(index++);
    }
}
相關文章
相關標籤/搜索