zoukankan      html  css  js  c++  java
  • jedis处理redis cluster集群的密码问题

    环境介绍:jedis:2.8.0

    redis版本:3.2

    首先说一下redis集群的方式,一种是cluster的 一种是sentinel的,cluster的是redis 3.0之后出来新的集群方式

    本身redis3.2的cluster集群是支持密码的 ,具体怎么搭建,可以查找相关的文档,这里只介绍应用层面的操作

    jedis2.8.0的版本没有实现对redis cluster集群的密码操作

    在jedis中创建redis cluster的对象时,一般是采用

    JedisCluster jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig);

    我们在项目中直接写了一个类专门来负责操作redis的

    public class RedisClusterUtil {
        private static final Logger LOGGER = Logger.getLogger(RedisClusterUtil.class);
        private int timeout = 10000;
        private JedisCluster jedisCluster;
        private Set<HostAndPort> clusterNodes ;
    
        public RedisClusterUtil(String redisUris, JedisPoolConfig jedisPoolConfig) throws  Exception{
            init(redisUris);
            checkHostAndPost();
            jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig);
        }
        
        /**
         * reids 链接节点地址
         */
        public void init(String redisUris) {
            LOGGER.info("redisUris:" + redisUris);
            // ## 注册redis连接节点
            clusterNodes = Sets.newHashSet();
            if(StringUtils.isNotBlank(redisUris)){
                // 以“;”分割成"ip:post"
                String [] ipAndPostes = redisUris.split(";");
                // 以“:”分割成 “ip”,“post”
                if(ipAndPostes != null){
                    for (String ipAndPost : ipAndPostes){
                        //ipAndPost 值:(ip:端口)
                        String [] ipAndPostArray = ipAndPost.split(":");
                        clusterNodes.add(new HostAndPort(ipAndPostArray[0], Integer.parseInt(ipAndPostArray[1])));
                    }
                }
            }
            LOGGER.info("redis链接节点个数(clusterNodes):" + clusterNodes.size());
        }
    

      

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
           ">
    
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="${redis.maxTotal}"/>
            <property name="maxIdle" value="${redis.maxIdle}"/>
            <property name="minIdle" value="${redis.minIdle}"/>
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
            <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        </bean>
        <bean id="redisClusterUtil" class="*.*.utils.RedisClusterUtil">
            <constructor-arg index="0" value="${redisUris}"></constructor-arg>
            <constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg>
        </bean>
    </beans>
    

      我们创建好jedisCluster之后,看了一下jedisCluster里面有一个jedisCluster.auth("密码")方法,可惜,这个方法里面什么都没有实现,仅仅抛一个异常

      @Deprecated

      @Override

      public String auth(String password) {

        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");

      }

    所以想通过这个来设置密码是没戏啦,只能去修改jedis的源码啦,我们先直接启动一下看下报错信息,会发现整个jedis在操作cluster集群涉及到的主要的类

    这里我们会发现cluster集群最终会调用redis.clients.jedis.JedisClusterConnectionHandler.initializeSlotsCache(Set<HostAndPort>, GenericObjectPoolConfig)方法,而这个方法里面的代码是

      private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig) {
        for (HostAndPort hostAndPort : startNodes) {
          Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
          try {
            cache.discoverClusterNodesAndSlots(jedis);
            break;
          } catch (JedisConnectionException e) {
            // try next nodes
          } finally {
            if (jedis != null) {
              jedis.close();
            }
          }
        }
    
        for (HostAndPort node : startNodes) {
          cache.setNodeIfNotExist(node);
        }
      }
    

      这里我们可以看到代码中有jedis的创建,而jedis本身是可以支持password配置的,这样我们就可以直接写一个方法去给这个类中塞一个密码进去啦

    以下是我自己添加的一个方法,主要是添加了密码  
    private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig,String password) { for (HostAndPort hostAndPort : startNodes) { Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort()); jedis.auth(password); try { cache.discoverClusterNodesAndSlots(jedis); break; } catch (JedisConnectionException e) { // try next nodes } finally { if (jedis != null) { jedis.close(); } } } for (HostAndPort node : startNodes) { cache.setNodeIfNotExist(node); } }

    这样我们就让JedisClusterConnectionHandler支持了密码,再根据上面的异常信息中的信息,分别去新增方法去传递password到JedisClusterConnectionHandler;这里就部再详细介绍每段代码啦,从异常信息中就知道要修改哪些方法啦

    package redis.clients.jedis;
    
    import redis.clients.jedis.BinaryClient.LIST_POSITION;
    import redis.clients.jedis.params.sortedset.ZAddParams;
    import redis.clients.jedis.params.sortedset.ZIncrByParams;
    import redis.clients.util.KeyMergeUtil;
    import redis.clients.jedis.params.geo.GeoRadiusParam;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    
    public class JedisCluster extends BinaryJedisCluster implements JedisCommands,
        MultiKeyJedisClusterCommands, JedisClusterScriptingCommands {
    
      public static enum Reset {
        SOFT, HARD
      }
    
      public JedisCluster(Set<HostAndPort> nodes) {
        this(nodes, DEFAULT_TIMEOUT);
      }
    
      public JedisCluster(Set<HostAndPort> nodes, int timeout) {
        this(nodes, timeout, DEFAULT_MAX_REDIRECTIONS);
      }
    
      public JedisCluster(Set<HostAndPort> nodes, int timeout, int maxRedirections) {
        this(nodes, timeout, maxRedirections, new GenericObjectPoolConfig());
      }
    
      public JedisCluster(Set<HostAndPort> nodes, final GenericObjectPoolConfig poolConfig) {
        this(nodes, DEFAULT_TIMEOUT, DEFAULT_MAX_REDIRECTIONS, poolConfig);
      }
    
      public JedisCluster(Set<HostAndPort> nodes, int timeout, final GenericObjectPoolConfig poolConfig) {
        this(nodes, timeout, DEFAULT_MAX_REDIRECTIONS, poolConfig);
      }
      
      public JedisCluster(Set<HostAndPort> nodes, int timeout, final GenericObjectPoolConfig poolConfig,String password) {
            this(nodes, timeout, DEFAULT_MAX_REDIRECTIONS, poolConfig,password);
          }
    
      public JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
          final GenericObjectPoolConfig poolConfig) {
        super(jedisClusterNode, timeout, maxRedirections, poolConfig);
      }
      
      public JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
              final GenericObjectPoolConfig poolConfig,String password) {
            super(jedisClusterNode, timeout, maxRedirections, poolConfig,password);
          }
    
      public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
          int maxRedirections, final GenericObjectPoolConfig poolConfig) {
        super(jedisClusterNode, connectionTimeout, soTimeout, maxRedirections, poolConfig);
      }
    
      @Override
      public String set(final String key, final String value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.set(key, value);
          }
        }.run(key);
      }
    
      @Override
      public String set(final String key, final String value, final String nxxx, final String expx,
          final long time) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.set(key, value, nxxx, expx, time);
          }
        }.run(key);
      }
    
      @Override
      public String get(final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.get(key);
          }
        }.run(key);
      }
    
      @Override
      public Boolean exists(final String key) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.exists(key);
          }
        }.run(key);
      }
    
      @Override
      public Long exists(final String... keys) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.exists(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public Long persist(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.persist(key);
          }
        }.run(key);
      }
    
      @Override
      public String type(final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.type(key);
          }
        }.run(key);
      }
    
      @Override
      public Long expire(final String key, final int seconds) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.expire(key, seconds);
          }
        }.run(key);
      }
    
      @Override
      public Long pexpire(final String key, final long milliseconds) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pexpire(key, milliseconds);
          }
        }.run(key);
      }
    
      @Override
      public Long expireAt(final String key, final long unixTime) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.expireAt(key, unixTime);
          }
        }.run(key);
      }
    
      @Override
      public Long pexpireAt(final String key, final long millisecondsTimestamp) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pexpireAt(key, millisecondsTimestamp);
          }
        }.run(key);
      }
    
      @Override
      public Long ttl(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.ttl(key);
          }
        }.run(key);
      }
    
      @Override
      public Long pttl(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pttl(key);
          }
        }.run(key);
      }
    
      @Override
      public Boolean setbit(final String key, final long offset, final boolean value) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.setbit(key, offset, value);
          }
        }.run(key);
      }
    
      @Override
      public Boolean setbit(final String key, final long offset, final String value) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.setbit(key, offset, value);
          }
        }.run(key);
      }
    
      @Override
      public Boolean getbit(final String key, final long offset) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.getbit(key, offset);
          }
        }.run(key);
      }
    
      @Override
      public Long setrange(final String key, final long offset, final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.setrange(key, offset, value);
          }
        }.run(key);
      }
    
      @Override
      public String getrange(final String key, final long startOffset, final long endOffset) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.getrange(key, startOffset, endOffset);
          }
        }.run(key);
      }
    
      @Override
      public String getSet(final String key, final String value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.getSet(key, value);
          }
        }.run(key);
      }
    
      @Override
      public Long setnx(final String key, final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.setnx(key, value);
          }
        }.run(key);
      }
    
      @Override
      public String setex(final String key, final int seconds, final String value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.setex(key, seconds, value);
          }
        }.run(key);
      }
    
      @Override
      public String psetex(final String key, final long milliseconds, final String value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.psetex(key, milliseconds, value);
          }
        }.run(key);
      }
    
      @Override
      public Long decrBy(final String key, final long integer) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.decrBy(key, integer);
          }
        }.run(key);
      }
    
      @Override
      public Long decr(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.decr(key);
          }
        }.run(key);
      }
    
      @Override
      public Long incrBy(final String key, final long integer) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.incrBy(key, integer);
          }
        }.run(key);
      }
    
      @Override
      public Double incrByFloat(final String key, final double value) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.incrByFloat(key, value);
          }
        }.run(key);
      }
    
      @Override
      public Long incr(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.incr(key);
          }
        }.run(key);
      }
    
      @Override
      public Long append(final String key, final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.append(key, value);
          }
        }.run(key);
      }
    
      @Override
      public String substr(final String key, final int start, final int end) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.substr(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long hset(final String key, final String field, final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hset(key, field, value);
          }
        }.run(key);
      }
    
      @Override
      public String hget(final String key, final String field) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.hget(key, field);
          }
        }.run(key);
      }
    
      @Override
      public Long hsetnx(final String key, final String field, final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hsetnx(key, field, value);
          }
        }.run(key);
      }
    
      @Override
      public String hmset(final String key, final Map<String, String> hash) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.hmset(key, hash);
          }
        }.run(key);
      }
    
      @Override
      public List<String> hmget(final String key, final String... fields) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.hmget(key, fields);
          }
        }.run(key);
      }
    
      @Override
      public Long hincrBy(final String key, final String field, final long value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hincrBy(key, field, value);
          }
        }.run(key);
      }
    
      @Override
      public Double hincrByFloat(final String key, final String field, final double value) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.hincrByFloat(key, field, value);
          }
        }.run(key);
      }
    
      @Override
      public Boolean hexists(final String key, final String field) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.hexists(key, field);
          }
        }.run(key);
      }
    
      @Override
      public Long hdel(final String key, final String... field) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hdel(key, field);
          }
        }.run(key);
      }
    
      @Override
      public Long hlen(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hlen(key);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> hkeys(final String key) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.hkeys(key);
          }
        }.run(key);
      }
    
      @Override
      public List<String> hvals(final String key) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.hvals(key);
          }
        }.run(key);
      }
    
      @Override
      public Map<String, String> hgetAll(final String key) {
        return new JedisClusterCommand<Map<String, String>>(connectionHandler, maxRedirections) {
          @Override
          public Map<String, String> execute(Jedis connection) {
            return connection.hgetAll(key);
          }
        }.run(key);
      }
    
      @Override
      public Long rpush(final String key, final String... string) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.rpush(key, string);
          }
        }.run(key);
      }
    
      @Override
      public Long lpush(final String key, final String... string) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.lpush(key, string);
          }
        }.run(key);
      }
    
      @Override
      public Long llen(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.llen(key);
          }
        }.run(key);
      }
    
      @Override
      public List<String> lrange(final String key, final long start, final long end) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.lrange(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public String ltrim(final String key, final long start, final long end) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.ltrim(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public String lindex(final String key, final long index) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.lindex(key, index);
          }
        }.run(key);
      }
    
      @Override
      public String lset(final String key, final long index, final String value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.lset(key, index, value);
          }
        }.run(key);
      }
    
      @Override
      public Long lrem(final String key, final long count, final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.lrem(key, count, value);
          }
        }.run(key);
      }
    
      @Override
      public String lpop(final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.lpop(key);
          }
        }.run(key);
      }
    
      @Override
      public String rpop(final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.rpop(key);
          }
        }.run(key);
      }
    
      @Override
      public Long sadd(final String key, final String... member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sadd(key, member);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> smembers(final String key) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.smembers(key);
          }
        }.run(key);
      }
    
      @Override
      public Long srem(final String key, final String... member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.srem(key, member);
          }
        }.run(key);
      }
    
      @Override
      public String spop(final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.spop(key);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> spop(final String key, final long count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.spop(key, count);
          }
        }.run(key);
      }
    
      @Override
      public Long scard(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.scard(key);
          }
        }.run(key);
      }
    
      @Override
      public Boolean sismember(final String key, final String member) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.sismember(key, member);
          }
        }.run(key);
      }
    
      @Override
      public String srandmember(final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.srandmember(key);
          }
        }.run(key);
      }
    
      @Override
      public List<String> srandmember(final String key, final int count) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.srandmember(key, count);
          }
        }.run(key);
      }
    
      @Override
      public Long strlen(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.strlen(key);
          }
        }.run(key);
      }
    
      @Override
      public Long zadd(final String key, final double score, final String member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, score, member);
          }
        }.run(key);
      }
    
      @Override
      public Long zadd(final String key, final double score, final String member, final ZAddParams params) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, score, member, params);
          }
        }.run(key);
      }
    
      @Override
      public Long zadd(final String key, final Map<String, Double> scoreMembers) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, scoreMembers);
          }
        }.run(key);
      }
    
      @Override
      public Long zadd(final String key, final Map<String, Double> scoreMembers, final ZAddParams params) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, scoreMembers, params);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrange(final String key, final long start, final long end) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrange(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long zrem(final String key, final String... member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zrem(key, member);
          }
        }.run(key);
      }
    
      @Override
      public Double zincrby(final String key, final double score, final String member) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.zincrby(key, score, member);
          }
        }.run(key);
      }
    
      @Override
      public Double zincrby(final String key, final double score, final String member, final ZIncrByParams params) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.zincrby(key, score, member, params);
          }
        }.run(key);
      }
    
      @Override
      public Long zrank(final String key, final String member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zrank(key, member);
          }
        }.run(key);
      }
    
      @Override
      public Long zrevrank(final String key, final String member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zrevrank(key, member);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrange(final String key, final long start, final long end) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrange(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrangeWithScores(final String key, final long start, final long end) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeWithScores(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeWithScores(final String key, final long start, final long end) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeWithScores(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long zcard(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zcard(key);
          }
        }.run(key);
      }
    
      @Override
      public Double zscore(final String key, final String member) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.zscore(key, member);
          }
        }.run(key);
      }
    
      @Override
      public List<String> sort(final String key) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.sort(key);
          }
        }.run(key);
      }
    
      @Override
      public List<String> sort(final String key, final SortingParams sortingParameters) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.sort(key, sortingParameters);
          }
        }.run(key);
      }
    
      @Override
      public Long zcount(final String key, final double min, final double max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zcount(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Long zcount(final String key, final String min, final String max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zcount(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrangeByScore(final String key, final double min, final double max) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrangeByScore(final String key, final String min, final String max) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrangeByScore(final String key, final double min, final double max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrangeByScore(final String key, final String max, final String min) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrangeByScore(final String key, final String min, final String max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrangeByScore(final String key, final double max, final double min,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrangeByScore(final String key, final String max, final String min,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final String key, final String min, final String max) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final String key, final String max, final String min) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final String key, final String min, final String max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max,
          final double min, final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final String key, final String max,
          final String min, final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Long zremrangeByRank(final String key, final long start, final long end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByRank(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long zremrangeByScore(final String key, final double start, final double end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByScore(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long zremrangeByScore(final String key, final String start, final String end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByScore(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long zlexcount(final String key, final String min, final String max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zlexcount(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrangeByLex(final String key, final String min, final String max) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrangeByLex(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrangeByLex(final String key, final String min, final String max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrangeByLex(key, min, max, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrangeByLex(final String key, final String max, final String min) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrangeByLex(key, max, min);
          }
        }.run(key);
      }
    
      @Override
      public Set<String> zrevrangeByLex(final String key, final String max, final String min,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.zrevrangeByLex(key, max, min, offset, count);
          }
        }.run(key);
      }
    
      @Override
      public Long zremrangeByLex(final String key, final String min, final String max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByLex(key, min, max);
          }
        }.run(key);
      }
    
      @Override
      public Long linsert(final String key, final LIST_POSITION where, final String pivot,
          final String value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.linsert(key, where, pivot, value);
          }
        }.run(key);
      }
    
      @Override
      public Long lpushx(final String key, final String... string) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.lpushx(key, string);
          }
        }.run(key);
      }
    
      @Override
      public Long rpushx(final String key, final String... string) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.rpushx(key, string);
          }
        }.run(key);
      }
    
      @Override
      public Long del(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.del(key);
          }
        }.run(key);
      }
    
      @Override
      public String echo(final String string) {
        // note that it'll be run from arbitary node
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.echo(string);
          }
        }.run(string);
      }
    
      @Override
      public Long bitcount(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitcount(key);
          }
        }.run(key);
      }
    
      @Override
      public Long bitcount(final String key, final long start, final long end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitcount(key, start, end);
          }
        }.run(key);
      }
    
      @Override
      public Long bitpos(final String key, final boolean value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitpos(key, value);
          }
        }.run(key);
      }
    
      @Override
      public Long bitpos(final String key, final boolean value, final BitPosParams params) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitpos(key, value, params);
          }
        }.run(key);
      }
    
      @Override
      public ScanResult<Entry<String, String>> hscan(final String key, final String cursor) {
        return new JedisClusterCommand<ScanResult<Entry<String, String>>>(connectionHandler,
            maxRedirections) {
          @Override
          public ScanResult<Entry<String, String>> execute(Jedis connection) {
            return connection.hscan(key, cursor);
          }
        }.run(key);
      }
    
      @Override
      public ScanResult<Entry<String, String>> hscan(final String key, final String cursor, final ScanParams params) {
        return new JedisClusterCommand<ScanResult<Entry<String, String>>>(connectionHandler,
            maxRedirections) {
          @Override
          public ScanResult<Entry<String, String>> execute(Jedis connection) {
            return connection.hscan(key, cursor, params);
          }
        }.run(key);
      }
    
      @Override
      public ScanResult<String> sscan(final String key, final String cursor) {
        return new JedisClusterCommand<ScanResult<String>>(connectionHandler, maxRedirections) {
          @Override
          public ScanResult<String> execute(Jedis connection) {
            return connection.sscan(key, cursor);
          }
        }.run(key);
      }
    
      @Override
      public ScanResult<String> sscan(final String key, final String cursor, final ScanParams params) {
        return new JedisClusterCommand<ScanResult<String>>(connectionHandler, maxRedirections) {
          @Override
          public ScanResult<String> execute(Jedis connection) {
            return connection.sscan(key, cursor, params);
          }
        }.run(key);
      }
    
      @Override
      public ScanResult<Tuple> zscan(final String key, final String cursor) {
        return new JedisClusterCommand<ScanResult<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public ScanResult<Tuple> execute(Jedis connection) {
            return connection.zscan(key, cursor);
          }
        }.run(key);
      }
    
      @Override
      public ScanResult<Tuple> zscan(final String key, final String cursor, final ScanParams params) {
        return new JedisClusterCommand<ScanResult<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public ScanResult<Tuple> execute(Jedis connection) {
            return connection.zscan(key, cursor, params);
          }
        }.run(key);
      }
    
      @Override
      public Long pfadd(final String key, final String... elements) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pfadd(key, elements);
          }
        }.run(key);
      }
    
      @Override
      public long pfcount(final String key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pfcount(key);
          }
        }.run(key);
      }
    
      @Override
      public List<String> blpop(final int timeout, final String key) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.blpop(timeout, key);
          }
        }.run(key);
      }
    
      @Override
      public List<String> brpop(final int timeout, final String key) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.brpop(timeout, key);
          }
        }.run(key);
      }
    
      @Override
      public Long del(final String... keys) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.del(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public List<String> blpop(final int timeout, final String... keys) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.blpop(timeout, keys);
          }
        }.run(keys.length, keys);
    
      }
    
      @Override
      public List<String> brpop(final int timeout, final String... keys) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.brpop(timeout, keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public List<String> mget(final String... keys) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.mget(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public String mset(final String... keysvalues) {
        String[] keys = new String[keysvalues.length / 2];
    
        for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
          keys[keyIdx] = keysvalues[keyIdx * 2];
        }
    
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.mset(keysvalues);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public Long msetnx(final String... keysvalues) {
        String[] keys = new String[keysvalues.length / 2];
    
        for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
          keys[keyIdx] = keysvalues[keyIdx * 2];
        }
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.msetnx(keysvalues);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public String rename(final String oldkey, final String newkey) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.rename(oldkey, newkey);
          }
        }.run(2, oldkey, newkey);
      }
    
      @Override
      public Long renamenx(final String oldkey, final String newkey) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.renamenx(oldkey, newkey);
          }
        }.run(2, oldkey, newkey);
      }
    
      @Override
      public String rpoplpush(final String srckey, final String dstkey) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.rpoplpush(srckey, dstkey);
          }
        }.run(2, srckey, dstkey);
      }
    
      @Override
      public Set<String> sdiff(final String... keys) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.sdiff(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public Long sdiffstore(final String dstkey, final String... keys) {
        String[] mergedKeys = KeyMergeUtil.merge(dstkey, keys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sdiffstore(dstkey, keys);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public Set<String> sinter(final String... keys) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.sinter(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public Long sinterstore(final String dstkey, final String... keys) {
        String[] mergedKeys = KeyMergeUtil.merge(dstkey, keys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sinterstore(dstkey, keys);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public Long smove(final String srckey, final String dstkey, final String member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.smove(srckey, dstkey, member);
          }
        }.run(2, srckey, dstkey);
      }
    
      @Override
      public Long sort(final String key, final SortingParams sortingParameters, final String dstkey) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sort(key, sortingParameters, dstkey);
          }
        }.run(2, key, dstkey);
      }
    
      @Override
      public Long sort(final String key, final String dstkey) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sort(key, dstkey);
          }
        }.run(2, key, dstkey);
      }
    
      @Override
      public Set<String> sunion(final String... keys) {
        return new JedisClusterCommand<Set<String>>(connectionHandler, maxRedirections) {
          @Override
          public Set<String> execute(Jedis connection) {
            return connection.sunion(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public Long sunionstore(final String dstkey, final String... keys) {
        String[] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sunionstore(dstkey, keys);
          }
        }.run(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long zinterstore(final String dstkey, final String... sets) {
        String[] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zinterstore(dstkey, sets);
          }
        }.run(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long zinterstore(final String dstkey, final ZParams params, final String... sets) {
        String[] mergedKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zinterstore(dstkey, params, sets);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public Long zunionstore(final String dstkey, final String... sets) {
        String[] mergedKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zunionstore(dstkey, sets);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public Long zunionstore(final String dstkey, final ZParams params, final String... sets) {
        String[] mergedKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zunionstore(dstkey, params, sets);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public String brpoplpush(final String source, final String destination, final int timeout) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.brpoplpush(source, destination, timeout);
          }
        }.run(2, source, destination);
      }
    
      @Override
      public Long publish(final String channel, final String message) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.publish(channel, message);
          }
        }.runWithAnyNode();
      }
    
      @Override
      public void subscribe(final JedisPubSub jedisPubSub, final String... channels) {
        new JedisClusterCommand<Integer>(connectionHandler, maxRedirections) {
          @Override
          public Integer execute(Jedis connection) {
            connection.subscribe(jedisPubSub, channels);
            return 0;
          }
        }.runWithAnyNode();
      }
    
      @Override
      public void psubscribe(final JedisPubSub jedisPubSub, final String... patterns) {
        new JedisClusterCommand<Integer>(connectionHandler, maxRedirections) {
          @Override
          public Integer execute(Jedis connection) {
            connection.subscribe(jedisPubSub, patterns);
            return 0;
          }
        }.runWithAnyNode();
      }
    
      @Override
      public Long bitop(final BitOP op, final String destKey, final String... srcKeys) {
        String[] mergedKeys = KeyMergeUtil.merge(destKey, srcKeys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitop(op, destKey, srcKeys);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public String pfmerge(final String destkey, final String... sourcekeys) {
        String[] mergedKeys = KeyMergeUtil.merge(destkey, sourcekeys);
    
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.pfmerge(destkey, sourcekeys);
          }
        }.run(mergedKeys.length, mergedKeys);
      }
    
      @Override
      public long pfcount(final String... keys) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pfcount(keys);
          }
        }.run(keys.length, keys);
      }
    
      @Override
      public Object eval(final String script, final int keyCount, final String... params) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script, keyCount, params);
          }
        }.run(keyCount, params);
      }
    
      @Override
      public Object eval(final String script, final String key) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script);
          }
        }.run(key);
      }
    
      @Override
      public Object eval(final String script, final List<String> keys, final List<String> args) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script, keys, args);
          }
        }.run(keys.size(), keys.toArray(new String[keys.size()]));
      }
    
      @Override
      public Object evalsha(final String sha1, final int keyCount, final String... params) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.evalsha(sha1, keyCount, params);
          }
        }.run(keyCount, params);
      }
    
      @Override
      public Object evalsha(final String sha1, final List<String> keys, final List<String> args) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.evalsha(sha1, keys, args);
          }
        }.run(keys.size(), keys.toArray(new String[keys.size()]));
      }
    
      @Override
      public Object evalsha(final String script, final String key) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.evalsha(script);
          }
        }.run(key);
      }
    
      @Override
      public Boolean scriptExists(final String sha1, final String key) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.scriptExists(sha1);
          }
        }.run(key);
      }
    
      @Override
      public List<Boolean> scriptExists(final String key, final String... sha1) {
        return new JedisClusterCommand<List<Boolean>>(connectionHandler, maxRedirections) {
          @Override
          public List<Boolean> execute(Jedis connection) {
            return connection.scriptExists(sha1);
          }
        }.run(key);
      }
    
      @Override
      public String scriptLoad(final String script, final String key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.scriptLoad(script);
          }
        }.run(key);
      }
    
      /*
       * below methods will be removed at 3.0
       */
    
      /**
       * @deprecated SetParams is scheduled to be introduced at next major release Please use setnx
       *             instead for now
       * @see <a href="https://github.com/xetorthio/jedis/pull/878">issue#878</a>
       */
      @Deprecated
      @Override
      public String set(String key, String value, String nxxx) {
        return setnx(key, value) == 1 ? "OK" : null;
      }
    
      /**
       * @deprecated unusable command, this will be removed at next major release.
       */
      @Deprecated
      @Override
      public List<String> blpop(final String arg) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.blpop(arg);
          }
        }.run(arg);
      }
    
      /**
       * @deprecated unusable command, this will be removed at next major release.
       */
      @Deprecated
      @Override
      public List<String> brpop(final String arg) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.brpop(arg);
          }
        }.run(arg);
      }
    
      /**
       * @deprecated Redis Cluster uses only db index 0, so it doesn't make sense. scheduled to be
       *             removed on next major release
       */
      @Deprecated
      @Override
      public Long move(final String key, final int dbIndex) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.move(key, dbIndex);
          }
        }.run(key);
      }
    
      /**
       * This method is deprecated due to bug (scan cursor should be unsigned long) And will be removed
       * on next major release
       * @see <a href="https://github.com/xetorthio/jedis/issues/531">issue#531</a>
       */
      @Deprecated
      @Override
      public ScanResult<Entry<String, String>> hscan(final String key, final int cursor) {
        return new JedisClusterCommand<ScanResult<Entry<String, String>>>(connectionHandler,
            maxRedirections) {
          @Override
          public ScanResult<Entry<String, String>> execute(Jedis connection) {
            return connection.hscan(key, cursor);
          }
        }.run(key);
      }
    
      /**
       * This method is deprecated due to bug (scan cursor should be unsigned long) And will be removed
       * on next major release
       * @see <a href="https://github.com/xetorthio/jedis/issues/531">issue#531</a>
       */
      @Deprecated
      @Override
      public ScanResult<String> sscan(final String key, final int cursor) {
        return new JedisClusterCommand<ScanResult<String>>(connectionHandler, maxRedirections) {
          @Override
          public ScanResult<String> execute(Jedis connection) {
            return connection.sscan(key, cursor);
          }
        }.run(key);
      }
    
      /**
       * This method is deprecated due to bug (scan cursor should be unsigned long) And will be removed
       * on next major release
       * @see <a href="https://github.com/xetorthio/jedis/issues/531">issue#531</a>
       */
      @Deprecated
      @Override
      public ScanResult<Tuple> zscan(final String key, final int cursor) {
        return new JedisClusterCommand<ScanResult<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public ScanResult<Tuple> execute(Jedis connection) {
            return connection.zscan(key, cursor);
          }
        }.run(key);
      }
    
      @Override
      public Long geoadd(final String key, final double longitude, final double latitude, final String member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.geoadd(key, longitude, latitude, member);
          }
        }.run(key);
      }
    
      @Override
      public Long geoadd(final String key, final Map<String, GeoCoordinate> memberCoordinateMap) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.geoadd(key, memberCoordinateMap);
          }
        }.run(key);
      }
    
      @Override
      public Double geodist(final String key, final String member1, final String member2) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.geodist(key, member1, member2);
          }
        }.run(key);
      }
    
      @Override
      public Double geodist(final String key, final String member1, final String member2, final GeoUnit unit) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.geodist(key, member1, member2, unit);
          }
        }.run(key);
      }
    
      @Override
      public List<String> geohash(final String key, final String... members) {
        return new JedisClusterCommand<List<String>>(connectionHandler, maxRedirections) {
          @Override
          public List<String> execute(Jedis connection) {
            return connection.geohash(key, members);
          }
        }.run(key);
      }
    
      @Override
      public List<GeoCoordinate> geopos(final String key, final String... members) {
        return new JedisClusterCommand<List<GeoCoordinate>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoCoordinate> execute(Jedis connection) {
            return connection.geopos(key, members);
          }
        }.run(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadius(final String key, final double longitude, final double latitude,
          final double radius, final GeoUnit unit) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadius(key, longitude, latitude, radius, unit);
          }
        }.run(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadius(final String key, final double longitude, final double latitude,
          final double radius, final GeoUnit unit, final GeoRadiusParam param) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadius(key, longitude, latitude, radius, unit, param);
          }
        }.run(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadiusByMember(final String key, final String member,
          final double radius, final GeoUnit unit) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadiusByMember(key, member, radius, unit);
          }
        }.run(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadiusByMember(final String key, final String member,
          final double radius, final GeoUnit unit, final GeoRadiusParam param) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadiusByMember(key, member, radius, unit, param);
          }
        }.run(key);
      }
    }
    redis.clients.jedis.JedisCluster
    package redis.clients.jedis;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    import redis.clients.jedis.exceptions.JedisClusterException;
    import redis.clients.jedis.params.geo.GeoRadiusParam;
    import redis.clients.jedis.params.sortedset.ZAddParams;
    import redis.clients.jedis.params.sortedset.ZIncrByParams;
    import redis.clients.util.KeyMergeUtil;
    import redis.clients.util.SafeEncoder;
    
    import java.io.Closeable;
    import java.io.IOException;
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class BinaryJedisCluster implements BasicCommands, BinaryJedisClusterCommands,
        MultiKeyBinaryJedisClusterCommands, JedisClusterBinaryScriptingCommands, Closeable {
    
      public static final short HASHSLOTS = 16384;
      protected static final int DEFAULT_TIMEOUT = 2000;
      protected static final int DEFAULT_MAX_REDIRECTIONS = 5;
    
      protected int maxRedirections;
    
      protected JedisClusterConnectionHandler connectionHandler;
    
      public BinaryJedisCluster(Set<HostAndPort> nodes, int timeout) {
        this(nodes, timeout, DEFAULT_MAX_REDIRECTIONS, new GenericObjectPoolConfig());
      }
    
      public BinaryJedisCluster(Set<HostAndPort> nodes) {
        this(nodes, DEFAULT_TIMEOUT);
      }
    
      public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
          final GenericObjectPoolConfig poolConfig) {
        this.connectionHandler = new JedisSlotBasedConnectionHandler(jedisClusterNode, poolConfig,
            timeout);
        this.maxRedirections = maxRedirections;
      }
      
      public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
              final GenericObjectPoolConfig poolConfig,String password) {
            this.connectionHandler = new JedisSlotBasedConnectionHandler(jedisClusterNode, poolConfig,
                timeout,password);
            this.maxRedirections = maxRedirections;
          }
    
      public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout,
          int soTimeout, int maxRedirections, final GenericObjectPoolConfig poolConfig) {
        this.connectionHandler = new JedisSlotBasedConnectionHandler(jedisClusterNode, poolConfig,
            connectionTimeout, soTimeout);
        this.maxRedirections = maxRedirections;
      }
    
      @Override
      public void close() throws IOException {
        if (connectionHandler != null) {
          for (JedisPool pool : connectionHandler.getNodes().values()) {
            try {
              if (pool != null) {
                pool.destroy();
              }
            } catch (Exception e) {
              // pass
            }
          }
        }
      }
    
      public Map<String, JedisPool> getClusterNodes() {
        return connectionHandler.getNodes();
      }
    
      @Override
      public String set(final byte[] key, final byte[] value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.set(key, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public String set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx,
          final long time) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.set(key, value, nxxx, expx, time);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] get(final byte[] key) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.get(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Boolean exists(final byte[] key) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.exists(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long exists(final byte[]... keys) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.exists(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public Long persist(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.persist(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public String type(final byte[] key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.type(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long expire(final byte[] key, final int seconds) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.expire(key, seconds);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long pexpire(final byte[] key, final long milliseconds) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pexpire(key, milliseconds);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long expireAt(final byte[] key, final long unixTime) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.expireAt(key, unixTime);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long pexpireAt(final byte[] key, final long millisecondsTimestamp) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pexpire(key, millisecondsTimestamp);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long ttl(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.ttl(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Boolean setbit(final byte[] key, final long offset, final boolean value) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.setbit(key, offset, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Boolean setbit(final byte[] key, final long offset, final byte[] value) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.setbit(key, offset, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Boolean getbit(final byte[] key, final long offset) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.getbit(key, offset);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long setrange(final byte[] key, final long offset, final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.setrange(key, offset, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] getrange(final byte[] key, final long startOffset, final long endOffset) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.getrange(key, startOffset, endOffset);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] getSet(final byte[] key, final byte[] value) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.getSet(key, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long setnx(final byte[] key, final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.setnx(key, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public String setex(final byte[] key, final int seconds, final byte[] value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.setex(key, seconds, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long decrBy(final byte[] key, final long integer) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.decrBy(key, integer);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long decr(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.decr(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long incrBy(final byte[] key, final long integer) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.incrBy(key, integer);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double incrByFloat(final byte[] key, final double value) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.incrByFloat(key, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long incr(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.incr(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long append(final byte[] key, final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.append(key, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] substr(final byte[] key, final int start, final int end) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.substr(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long hset(final byte[] key, final byte[] field, final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hset(key, field, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] hget(final byte[] key, final byte[] field) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.hget(key, field);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long hsetnx(final byte[] key, final byte[] field, final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hsetnx(key, field, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public String hmset(final byte[] key, final Map<byte[], byte[]> hash) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.hmset(key, hash);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<byte[]> hmget(final byte[] key, final byte[]... fields) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.hmget(key, fields);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long hincrBy(final byte[] key, final byte[] field, final long value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hincrBy(key, field, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double hincrByFloat(final byte[] key, final byte[] field, final double value) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.hincrByFloat(key, field, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Boolean hexists(final byte[] key, final byte[] field) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.hexists(key, field);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long hdel(final byte[] key, final byte[]... field) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hdel(key, field);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long hlen(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.hlen(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> hkeys(final byte[] key) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.hkeys(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Collection<byte[]> hvals(final byte[] key) {
        return new JedisClusterCommand<Collection<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Collection<byte[]> execute(Jedis connection) {
            return connection.hvals(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Map<byte[], byte[]> hgetAll(final byte[] key) {
        return new JedisClusterCommand<Map<byte[], byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Map<byte[], byte[]> execute(Jedis connection) {
            return connection.hgetAll(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long rpush(final byte[] key, final byte[]... args) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.rpush(key, args);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long lpush(final byte[] key, final byte[]... args) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.lpush(key, args);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long llen(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.llen(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<byte[]> lrange(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.lrange(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public String ltrim(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.ltrim(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] lindex(final byte[] key, final long index) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.lindex(key, index);
          }
        }.runBinary(key);
      }
    
      @Override
      public String lset(final byte[] key, final long index, final byte[] value) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.lset(key, index, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long lrem(final byte[] key, final long count, final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.lrem(key, count, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] lpop(final byte[] key) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.lpop(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] rpop(final byte[] key) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.rpop(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long sadd(final byte[] key, final byte[]... member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sadd(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> smembers(final byte[] key) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.smembers(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long srem(final byte[] key, final byte[]... member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.srem(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] spop(final byte[] key) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.spop(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> spop(final byte[] key, final long count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.spop(key, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long scard(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.scard(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Boolean sismember(final byte[] key, final byte[] member) {
        return new JedisClusterCommand<Boolean>(connectionHandler, maxRedirections) {
          @Override
          public Boolean execute(Jedis connection) {
            return connection.sismember(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] srandmember(final byte[] key) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.srandmember(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long strlen(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.strlen(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zadd(final byte[] key, final double score, final byte[] member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, score, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zadd(final byte[] key, final Map<byte[], Double> scoreMembers) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, scoreMembers);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zadd(final byte[] key, final double score, final byte[] member, final ZAddParams params) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, score, member, params);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zadd(final byte[] key, final Map<byte[], Double> scoreMembers, final ZAddParams params) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zadd(key, scoreMembers, params);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrange(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrange(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zrem(final byte[] key, final byte[]... member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zrem(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double zincrby(final byte[] key, final double score, final byte[] member) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.zincrby(key, score, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double zincrby(final byte[] key, final double score, final byte[] member, final ZIncrByParams params) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.zincrby(key, score, member, params);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zrank(final byte[] key, final byte[] member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zrank(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zrevrank(final byte[] key, final byte[] member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zrevrank(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrange(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrevrange(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrangeWithScores(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeWithScores(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeWithScores(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeWithScores(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zcard(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zcard(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double zscore(final byte[] key, final byte[] member) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.zscore(key, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<byte[]> sort(final byte[] key) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.sort(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<byte[]> sort(final byte[] key, final SortingParams sortingParameters) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.sort(key, sortingParameters);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zcount(final byte[] key, final double min, final double max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zcount(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zcount(final byte[] key, final byte[] min, final byte[] max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zcount(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrangeByScore(final byte[] key, final double min, final double max) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, final byte[] max) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrangeByScore(final byte[] key, final double max, final double min) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrangeByScore(final byte[] key, final double min, final double max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max, final byte[] min) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, final byte[] max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByScore(key, min, max, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrangeByScore(final byte[] key, final double max, final double min,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final double min, final double max) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final double max, final double min) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final double min, final double max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max, final byte[] min,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrevrangeByScore(key, max, min, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final byte[] min, final byte[] max) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final byte[] max, final byte[] min) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrangeByScoreWithScores(final byte[] key, final byte[] min, final byte[] max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrangeByScoreWithScores(key, min, max, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final double max,
          final double min, final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, final byte[] max,
          final byte[] min, final int offset, final int count) {
        return new JedisClusterCommand<Set<Tuple>>(connectionHandler, maxRedirections) {
          @Override
          public Set<Tuple> execute(Jedis connection) {
            return connection.zrevrangeByScoreWithScores(key, max, min, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zremrangeByRank(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByRank(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zremrangeByScore(final byte[] key, final double start, final double end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByScore(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zremrangeByScore(final byte[] key, final byte[] start, final byte[] end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByScore(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long linsert(final byte[] key, final Client.LIST_POSITION where, final byte[] pivot,
          final byte[] value) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.linsert(key, where, pivot, value);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long lpushx(final byte[] key, final byte[]... arg) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.lpushx(key, arg);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long rpushx(final byte[] key, final byte[]... arg) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.rpushx(key, arg);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long del(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.del(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] echo(final byte[] arg) {
        // note that it'll be run from arbitary node
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.echo(arg);
          }
        }.runBinary(arg);
      }
    
      @Override
      public Long bitcount(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitcount(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long bitcount(final byte[] key, final long start, final long end) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitcount(key, start, end);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long pfadd(final byte[] key, final byte[]... elements) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pfadd(key, elements);
          }
        }.runBinary(key);
      }
    
      @Override
      public long pfcount(final byte[] key) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pfcount(key);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<byte[]> srandmember(final byte[] key, final int count) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.srandmember(key, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zlexcount(final byte[] key, final byte[] min, final byte[] max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zlexcount(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByLex(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrangeByLex(final byte[] key, final byte[] min, final byte[] max,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByLex(key, min, max, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrangeByLex(key, max, min);
          }
        }.runBinary(key);
      }
    
      @Override
      public Set<byte[]> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min,
          final int offset, final int count) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.zrevrangeByLex(key, max, min, offset, count);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zremrangeByLex(key, min, max);
          }
        }.runBinary(key);
      }
    
      @Override
      public Object eval(final byte[] script, final byte[] keyCount, final byte[]... params) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script, keyCount, params);
          }
        }.runBinary(Integer.parseInt(SafeEncoder.encode(keyCount)), params);
      }
    
      @Override
      public Object eval(final byte[] script, final int keyCount, final byte[]... params) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script, keyCount, params);
          }
        }.runBinary(keyCount, params);
      }
    
      @Override
      public Object eval(final byte[] script, final List<byte[]> keys, final List<byte[]> args) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script, keys, args);
          }
        }.runBinary(keys.size(), keys.toArray(new byte[keys.size()][]));
      }
    
      @Override
      public Object eval(final byte[] script, byte[] key) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.eval(script);
          }
        }.runBinary(key);
      }
    
      @Override
      public Object evalsha(final byte[] script, byte[] key) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.evalsha(script);
          }
        }.runBinary(key);
      }
    
      @Override
      public Object evalsha(final byte[] sha1, final List<byte[]> keys, final List<byte[]> args) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.evalsha(sha1, keys, args);
          }
        }.runBinary(keys.size(), keys.toArray(new byte[keys.size()][]));
      }
    
      @Override
      public Object evalsha(final byte[] sha1, final int keyCount, final byte[]... params) {
        return new JedisClusterCommand<Object>(connectionHandler, maxRedirections) {
          @Override
          public Object execute(Jedis connection) {
            return connection.evalsha(sha1, keyCount, params);
          }
        }.runBinary(keyCount, params);
      }
    
      @Override
      public List<Long> scriptExists(final byte[] key, final byte[][] sha1) {
        return new JedisClusterCommand<List<Long>>(connectionHandler, maxRedirections) {
          @Override
          public List<Long> execute(Jedis connection) {
            return connection.scriptExists(sha1);
          }
        }.runBinary(key);
      }
    
      @Override
      public byte[] scriptLoad(final byte[] script, final byte[] key) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.scriptLoad(script);
          }
        }.runBinary(key);
      }
    
      @Override
      public String scriptFlush(final byte[] key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.scriptFlush();
          }
        }.runBinary(key);
      }
    
      @Override
      public String scriptKill(byte[] key) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.scriptKill();
          }
        }.runBinary(key);
      }
    
      @Override
      public Long del(final byte[]... keys) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.del(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public List<byte[]> blpop(final int timeout, final byte[]... keys) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.blpop(timeout, keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public List<byte[]> brpop(final int timeout, final byte[]... keys) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.brpop(timeout, keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public List<byte[]> mget(final byte[]... keys) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.mget(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public String mset(final byte[]... keysvalues) {
        byte[][] keys = new byte[keysvalues.length / 2][];
    
        for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
          keys[keyIdx] = keysvalues[keyIdx * 2];
        }
    
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.mset(keysvalues);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public Long msetnx(final byte[]... keysvalues) {
        byte[][] keys = new byte[keysvalues.length / 2][];
    
        for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
          keys[keyIdx] = keysvalues[keyIdx * 2];
        }
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.msetnx(keysvalues);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public String rename(final byte[] oldkey, final byte[] newkey) {
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.rename(oldkey, newkey);
          }
        }.runBinary(2, oldkey, newkey);
      }
    
      @Override
      public Long renamenx(final byte[] oldkey, final byte[] newkey) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.renamenx(oldkey, newkey);
          }
        }.runBinary(2, oldkey, newkey);
      }
    
      @Override
      public byte[] rpoplpush(final byte[] srckey, final byte[] dstkey) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.rpoplpush(srckey, dstkey);
          }
        }.runBinary(2, srckey, dstkey);
      }
    
      @Override
      public Set<byte[]> sdiff(final byte[]... keys) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.sdiff(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public Long sdiffstore(final byte[] dstkey, final byte[]... keys) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sdiffstore(dstkey, keys);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Set<byte[]> sinter(final byte[]... keys) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.sinter(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public Long sinterstore(final byte[] dstkey, final byte[]... keys) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sinterstore(dstkey, keys);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long smove(final byte[] srckey, final byte[] dstkey, final byte[] member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.smove(srckey, dstkey, member);
          }
        }.runBinary(2, srckey, dstkey);
      }
    
      @Override
      public Long sort(final byte[] key, final SortingParams sortingParameters, final byte[] dstkey) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sort(key, sortingParameters, dstkey);
          }
        }.runBinary(2, key, dstkey);
      }
    
      @Override
      public Long sort(final byte[] key, final byte[] dstkey) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sort(key, dstkey);
          }
        }.runBinary(2, key, dstkey);
      }
    
      @Override
      public Set<byte[]> sunion(final byte[]... keys) {
        return new JedisClusterCommand<Set<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public Set<byte[]> execute(Jedis connection) {
            return connection.sunion(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      @Override
      public Long sunionstore(final byte[] dstkey, final byte[]... keys) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.sunionstore(dstkey, keys);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long zinterstore(final byte[] dstkey, final byte[]... sets) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zinterstore(dstkey, sets);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long zinterstore(final byte[] dstkey, final ZParams params, final byte[]... sets) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zinterstore(dstkey, params, sets);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long zunionstore(final byte[] dstkey, final byte[]... sets) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zunionstore(dstkey, sets);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long zunionstore(final byte[] dstkey, final ZParams params, final byte[]... sets) {
        byte[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.zunionstore(dstkey, params, sets);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public byte[] brpoplpush(final byte[] source, final byte[] destination, final int timeout) {
        return new JedisClusterCommand<byte[]>(connectionHandler, maxRedirections) {
          @Override
          public byte[] execute(Jedis connection) {
            return connection.brpoplpush(source, destination, timeout);
          }
        }.runBinary(2, source, destination);
      }
    
      @Override
      public Long publish(final byte[] channel, final byte[] message) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.publish(channel, message);
          }
        }.runWithAnyNode();
      }
    
      @Override
      public void subscribe(final BinaryJedisPubSub jedisPubSub, final byte[]... channels) {
        new JedisClusterCommand<Integer>(connectionHandler, maxRedirections) {
          @Override
          public Integer execute(Jedis connection) {
            connection.subscribe(jedisPubSub, channels);
            return 0;
          }
        }.runWithAnyNode();
      }
    
      @Override
      public void psubscribe(final BinaryJedisPubSub jedisPubSub, final byte[]... patterns) {
        new JedisClusterCommand<Integer>(connectionHandler, maxRedirections) {
          @Override
          public Integer execute(Jedis connection) {
            connection.subscribe(jedisPubSub, patterns);
            return 0;
          }
        }.runWithAnyNode();
      }
    
      @Override
      public Long bitop(final BitOP op, final byte[] destKey, final byte[]... srcKeys) {
        byte[][] wholeKeys = KeyMergeUtil.merge(destKey, srcKeys);
    
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.bitop(op, destKey, srcKeys);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public String pfmerge(final byte[] destkey, final byte[]... sourcekeys) {
        byte[][] wholeKeys = KeyMergeUtil.merge(destkey, sourcekeys);
    
        return new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
          @Override
          public String execute(Jedis connection) {
            return connection.pfmerge(destkey, sourcekeys);
          }
        }.runBinary(wholeKeys.length, wholeKeys);
      }
    
      @Override
      public Long pfcount(final byte[]... keys) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.pfcount(keys);
          }
        }.runBinary(keys.length, keys);
      }
    
      /*
       * below methods will be removed at 3.0
       */
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String ping() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String quit() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String flushDB() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster and Redis Cluster only uses
       *             db index 0 scheduled to be removed on next major release
       */
      @Deprecated
      @Override
      public Long dbSize() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster and Redis Cluster only uses
       *             db index 0 scheduled to be removed on next major release
       */
      @Deprecated
      @Override
      public String select(int index) {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String flushAll() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster and Redis Cluster doesn't
       *             support authorization scheduled to be removed on next major release
       */
      @Deprecated
      @Override
      public String auth(String password) {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String save() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String bgsave() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String bgrewriteaof() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public Long lastsave() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String shutdown() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String info() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String info(String section) {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String slaveof(String host, int port) {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String slaveofNoOne() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster and Redis Cluster only uses
       *             db index 0 scheduled to be removed on next major release
       */
      @Deprecated
      @Override
      public Long getDB() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String debug(DebugParams params) {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public String configResetStat() {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      /**
       * @deprecated No key operation doesn't make sense for Redis Cluster scheduled to be removed on
       *             next major release
       */
      @Deprecated
      @Override
      public Long waitReplicas(int replicas, long timeout) {
        throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
      }
    
      @Override
      public Long geoadd(final byte[] key, final double longitude, final double latitude, final byte[] member) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.geoadd(key, longitude, latitude, member);
          }
        }.runBinary(key);
      }
    
      @Override
      public Long geoadd(final byte[] key, final Map<byte[], GeoCoordinate> memberCoordinateMap) {
        return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
          @Override
          public Long execute(Jedis connection) {
            return connection.geoadd(key, memberCoordinateMap);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double geodist(final byte[] key, final byte[] member1, final byte[] member2) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.geodist(key, member1, member2);
          }
        }.runBinary(key);
      }
    
      @Override
      public Double geodist(final byte[] key, final byte[] member1, final byte[] member2, final GeoUnit unit) {
        return new JedisClusterCommand<Double>(connectionHandler, maxRedirections) {
          @Override
          public Double execute(Jedis connection) {
            return connection.geodist(key, member1, member2, unit);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<byte[]> geohash(final byte[] key, final byte[]... members) {
        return new JedisClusterCommand<List<byte[]>>(connectionHandler, maxRedirections) {
          @Override
          public List<byte[]> execute(Jedis connection) {
            return connection.geohash(key, members);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<GeoCoordinate> geopos(final byte[] key, final byte[]... members) {
        return new JedisClusterCommand<List<GeoCoordinate>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoCoordinate> execute(Jedis connection) {
            return connection.geopos(key, members);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadius(final byte[] key, final double longitude, final double latitude,
          final double radius, final GeoUnit unit) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadius(key, longitude, latitude, radius, unit);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadius(final byte[] key, final double longitude, final double latitude,
          final double radius, final GeoUnit unit, final GeoRadiusParam param) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadius(key, longitude, latitude, radius, unit, param);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadiusByMember(final byte[] key, final byte[] member,
          final double radius, final GeoUnit unit) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadiusByMember(key, member, radius, unit);
          }
        }.runBinary(key);
      }
    
      @Override
      public List<GeoRadiusResponse> georadiusByMember(final byte[] key, final byte[] member,
          final double radius, final GeoUnit unit, final GeoRadiusParam param) {
        return new JedisClusterCommand<List<GeoRadiusResponse>>(connectionHandler, maxRedirections) {
          @Override
          public List<GeoRadiusResponse> execute(Jedis connection) {
            return connection.georadiusByMember(key, member, radius, unit, param);
          }
        }.runBinary(key);
      }
    
    }
    package redis.clients.jedis;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    
    import redis.clients.jedis.exceptions.JedisConnectionException;
    
    public abstract class JedisClusterConnectionHandler {
      protected final JedisClusterInfoCache cache;
    
      abstract Jedis getConnection();
    
      abstract Jedis getConnectionFromSlot(int slot);
    
      public Jedis getConnectionFromNode(HostAndPort node) {
        cache.setNodeIfNotExist(node);
        return cache.getNode(JedisClusterInfoCache.getNodeKey(node)).getResource();
      }
    
      public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
          final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {
        this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout);
        initializeSlotsCache(nodes, poolConfig);
      }
      
      public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
              final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout,String password) {
            this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout);
            initializeSlotsCache(nodes, poolConfig,password);
          }
    
      public Map<String, JedisPool> getNodes() {
        return cache.getNodes();
      }
    
      private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig) {
        for (HostAndPort hostAndPort : startNodes) {
          Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
          try {
            cache.discoverClusterNodesAndSlots(jedis);
            break;
          } catch (JedisConnectionException e) {
            // try next nodes
          } finally {
            if (jedis != null) {
              jedis.close();
            }
          }
        }
    
        for (HostAndPort node : startNodes) {
          cache.setNodeIfNotExist(node);
        }
      }
    
      private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig,String password) {
            for (HostAndPort hostAndPort : startNodes) {
              Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
              jedis.auth(password);
              try {
                cache.discoverClusterNodesAndSlots(jedis);
                break;
              } catch (JedisConnectionException e) {
                // try next nodes
              } finally {
                if (jedis != null) {
                  jedis.close();
                }
              }
            }
    
            for (HostAndPort node : startNodes) {
              cache.setNodeIfNotExist(node);
            }
          }
      
      public void renewSlotCache() {
        for (JedisPool jp : getShuffledNodesPool()) {
          Jedis jedis = null;
          try {
            jedis = jp.getResource();
            cache.discoverClusterSlots(jedis);
            break;
          } catch (JedisConnectionException e) {
            // try next nodes
          } finally {
            if (jedis != null) {
              jedis.close();
            }
          }
        }
      }
    
      public void renewSlotCache(Jedis jedis) {
        try {
          cache.discoverClusterSlots(jedis);
        } catch (JedisConnectionException e) {
          renewSlotCache();
        }
      }
    
      protected List<JedisPool> getShuffledNodesPool() {
        List<JedisPool> pools = new ArrayList<JedisPool>();
        pools.addAll(cache.getNodes().values());
        Collections.shuffle(pools);
        return pools;
      }
    }
    redis.clients.jedis.JedisClusterConnectionHandler
    package redis.clients.jedis;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    
    import java.util.Set;
    
    import redis.clients.jedis.exceptions.JedisConnectionException;
    
    public class JedisSlotBasedConnectionHandler extends JedisClusterConnectionHandler {
    
      public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
          final GenericObjectPoolConfig poolConfig, int timeout) {
        this(nodes, poolConfig, timeout, timeout);
      }
      
      public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
              final GenericObjectPoolConfig poolConfig, int timeout,String password) {
            this(nodes, poolConfig, timeout, timeout,password);
          }
    
      public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
          final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {
        super(nodes, poolConfig, connectionTimeout, soTimeout);
      }
      
      public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
              final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout,String password) {
            super(nodes, poolConfig, connectionTimeout, soTimeout,password);
          }
      
    
      @Override
      public Jedis getConnection() {
        // In antirez's redis-rb-cluster implementation,
        // getRandomConnection always return valid connection (able to
        // ping-pong)
        // or exception if all connections are invalid
    
        List<JedisPool> pools = getShuffledNodesPool();
    
        for (JedisPool pool : pools) {
          Jedis jedis = null;
          try {
            jedis = pool.getResource();
    
            if (jedis == null) {
              continue;
            }
    
            String result = jedis.ping();
    
            if (result.equalsIgnoreCase("pong")) return jedis;
    
            pool.returnBrokenResource(jedis);
          } catch (JedisConnectionException ex) {
            if (jedis != null) {
              pool.returnBrokenResource(jedis);
            }
          }
        }
    
        throw new JedisConnectionException("no reachable node in cluster");
      }
    
      @Override
      public Jedis getConnectionFromSlot(int slot) {
        JedisPool connectionPool = cache.getSlotPool(slot);
        if (connectionPool != null) {
          // It can't guaranteed to get valid connection because of node
          // assignment
          return connectionPool.getResource();
        } else {
          return getConnection();
        }
      }
    }
    redis.clients.jedis.JedisSlotBasedConnectionHandler

    重写的jedis的代码如上,重写了jedis的4个类,4个类中分别新增了一个方法,最新项目中调用时,就可以

    直接

        public RedisClusterUtil(String redisUris, JedisPoolConfig jedisPoolConfig) throws  Exception{

            init(redisUris);

            checkHostAndPost();

            jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig,"密码");

        }

    这样就结束啦

    public class RedisClusterUtil {    private static final Logger LOGGER = Logger.getLogger(RedisClusterUtil.class);    private int timeout = 10000;    private JedisCluster jedisCluster;    private Set<HostAndPort> clusterNodes ;
        public RedisClusterUtil(String redisUris, JedisPoolConfig jedisPoolConfig) throws  Exception{        init(redisUris);        checkHostAndPost();        jedisCluster = new JedisCluster(clusterNodes,timeout,jedisPoolConfig,"!QAZ2wsx");    }        /**     * reids 链接节点地址     */    public void init(String redisUris) {        LOGGER.info("redisUris:" + redisUris);        // ## 注册redis连接节点        clusterNodes = Sets.newHashSet();        if(StringUtils.isNotBlank(redisUris)){            // 以“;”分割成"ip:post"            String [] ipAndPostes = redisUris.split(";");            // 以“:”分割成 “ip”,“post”            if(ipAndPostes != null){                for (String ipAndPost : ipAndPostes){                    //ipAndPost 值:(ip:端口)                    String [] ipAndPostArray = ipAndPost.split(":");                    clusterNodes.add(new HostAndPort(ipAndPostArray[0], Integer.parseInt(ipAndPostArray[1])));                }            }        }        LOGGER.info("redis链接节点个数(clusterNodes):" + clusterNodes.size());    }

  • 相关阅读:
    MATLAB GUI制作快速入门
    JavaFX Chart设置数值显示
    Unity查找物体的四大主流方法及区别
    Matlab 图像转极坐标系
    使用python获得N个区分度较高的RGB颜色值
    Arduino学习笔记30
    Arduino学习笔记27
    Arduino学习笔记26
    Arduino学习笔记25
    Arduino学习笔记24
  • 原文地址:https://www.cnblogs.com/snowstar123/p/5696052.html
Copyright © 2011-2022 走看看