前言

鉴于公司Redis目前的使用现状及问题,架构组将提供统一Redis使用方案,在通用组件包内置redis功能,提高开发效率,降低项目的耦合性。以下是我这次设计改造的过程。

一、Redis使用现状

1、每个应用使用jedis自行配置并实现访问redis的功能。具体依赖如下:


<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>


2、目前各应用redis使用情况如下:

ci框架 redis使用 redis组件_Test

二、Redis使用问题

1、每个应用单独实现redis,造成冗余,增加使用复杂度;

2、每个应用单独实现redis,不同应用之间,可能会出现重复的key;

3、每个应用单独实现redis,目前没有约束,容易造成一些不可预知的风险;

三、Redis使用方案

鉴于目前现状及问题,基础架构组提供统一redis使用方案,具体如下:

1、组件包提供redis功能,各应用直接使用它来操作redis。各应用无需在单独实现redis功能;

2、组件包提供了对redis  中5种类型的常规操作方法;

3、组件包对redis所有的操作,会对key进行特殊处理(增加前缀:集群名称:应用名称),从而保证key的唯一性。但对各应用来说是透明的。

      例如:code  ——>  mrp:umpg:code

4、对【非字符串类型】,获取所有元素的方法(如:hgetall、lrange、smembers、zrange等等),进行了限制(最多返回2000个元素);

5、对【集合类型】,(sinter、sunion、sdiff)方法,进行了限制(单个key不能超过2000个元素);

6、对【非字符串类型】,如果有bigkey,不要使用del方法删除,组件提供了相关方法(delBigHash、delBigList、delBigSet、delBigZset)渐进式删除。

………

四、实现设计

在通用组件包中,增加redis标签定义,标签解析,初始化jedisCluster的功能。新增加中间件包【zat-middleware】,将具体的实现逻辑放在这里。各应用如果标签了这个标签,在服务启动时就进行相应的处理。

  • 组件包【esbproxy】修改:

ci框架 redis使用 redis组件_数据库_02

  1. esb.xsd:增加redis标签元素;
  2. RedisConfig:增加redis配置类;
  3. Namespacehandler:增加对redis标签处理;
  4. EsbBeanDefinitionParser:解析redis标签,将标签的属性转换成RedisConfig对象的属性值;
  5. Scanner:初始化 zat-middleware 包;
  6. AnnotationBean:初始化jedisCluster对象;

 

  • 中间件包【zat-middleware】: 

ci框架 redis使用 redis组件_Test_03

  1. JedisClusterFactory:jedisCluster的工厂类, JedisPool连接池的实现;
  2. RedisClusterUtil:操作redis集群的工具类;
  3. AbstracRedisCluster:公共抽像类,包含一些通用的方法;
  4. RedisConst:redis常量类;

五、Redis使用方法

 

配置redis标签:

在*-config.xml 配置文件中,增加redis标签,填写相关属性值(可固定值或从配置中心获取)


<esb:redis address="${redis.url}" timeout="${redis.timeout}" maxRedirections="${redis.maxRedirections}" maxTotal="${redis.maxTotal}" maxIdle="${redis.maxIdle}" minIdle="${redis.minIdle}" maxWaitMillis="${redis.maxWait}" testOnBorrow="${redis.testOnBorrow}" testOnCreate="${redis.testOnCreate}" testOnReturn="${redis.testOnReturn}"/>


使用方法:


RedisClusterUtils.getInstance().set(key, value); RedisClusterUtils.getInstance().get(key);


注:这里只举例了2个方法。

删除应用原有redis 实现:

避免重复实现,如果应用中已经以实现redis的功能,需把它删除掉,具体方法如下:

1、删除配置文件,一般是:context-redis.xml或 context-beans.xml;

2、删除初始化类,一般是:SimpleJedisCluster.java;

3、删除具体实现类,一般是:RedisDao.java或RedisUtil.java;

六、注意事项

1、原有应用使用了redis,现改造成使用组件包中的redis后,需要进行压力测试。

2、组件包中操作redis的所有方法,都没有处理异常。对于有些应用要吃掉异常的场景,请在应用中自行处理。

七、单元测试

package com.zat.umpg.bus.redis;

import com.zat.redis.util.RedisClusterUtils;
import com.zat.sproxy.logger.Logger;
import com.zat.sproxy.logger.LoggerFactory;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Tuple;

import javax.servlet.annotation.WebListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Redis集群单元测试类.
 *
 * @author weixiong.cao
 * @date 22/04/2020
 * @version 1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@WebListener
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/context-*.xml","classpath:conf/*/*.xml"})
public class RedisClusterUtilTest extends TestCase {

    /**
     * logger.
     */
    private static Logger logger = LoggerFactory.getLogger(RedisClusterUtilTest.class);

    @Before
    public void before() throws Exception {
    }

    @After
    public void after() throws Exception {
    }

    public static final String value_end = "_value";

    /**
     * 存入并获取数据.
     */
    @Test
    public void testSetAndGet() {
        String key = "unittest:set";
        String value = key + value_end;
        RedisClusterUtils.getInstance().set(key, value);
        String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【set】 {}={}", key, redisValue);
        assertEquals("set失败,查询结果不等于期望值", value, redisValue);
    }

    /**
     * 存入并获取数据—不存在时.
     */
    @Test
    public void testSetnxAndGet() {
        String key = "unittest:setnx";
        String value = key + value_end;
        RedisClusterUtils.getInstance().setnx(key, value);
        String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【setnx】 {}={}", key, redisValue);
        assertEquals("setnx失败,查询结果不等于期望值", value, redisValue);
    }

    /**
     * 存入并获取数据—自动删除.
     */
    @Test
    public void testSetExpireAndGet() throws InterruptedException {
        String key = "unittest:setex";
        String value = key + value_end;
        RedisClusterUtils.getInstance().setex(key, value, 3);
        Thread.sleep(5000);
        String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【setex】 {}={}", key, redisValue);
        assertNull("setex失败,过期时间后还能查到值", redisValue);
    }

    /**
     * 设置过期时间.
     */
    @Test
    public void testExpire() throws InterruptedException {
        String key = "unittest:expire";
        String value = key + value_end;
        RedisClusterUtils.getInstance().set(key, value);
        RedisClusterUtils.getInstance().expire(key, 3);
        Thread.sleep(5000);
        final String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【expire】 {}={}", key, redisValue);
        assertNull("expire失败,过期时间后还能查到值", redisValue);
    }

    /**
     * 删除key.
     */
    @Test
    public void testDel() {
        String key = "unittest:del";
        String value = key + value_end;
        RedisClusterUtils.getInstance().set(key, value);
        final Long del = RedisClusterUtils.getInstance().del(key);
        final String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【del】 {}={}", key, redisValue);
        assertEquals("del失败,返回结果不为1", "1", del.toString());
        assertNull("del失败,还能查到值", redisValue);
    }

    /**
     * 判断是否存在.
     */
    @Test
    public void testExists() {
        String key = "unittest:exists";
        String value = key + value_end;
        RedisClusterUtils.getInstance().set(key, value);
        final boolean exists = RedisClusterUtils.getInstance().exists(key);
        logger.info("【exists】 {}={}", key, exists);
        assertEquals("exists失败,返回结果不为true", "true", String.valueOf(exists));
    }

    /**
     * key的值加1.
     */
    @Test
    public void testIncr() {
        String key = "unittest:incr";
        RedisClusterUtils.getInstance().del(key);
        long incr = 0l;
        incr = RedisClusterUtils.getInstance().incr(key, 0);
        incr = RedisClusterUtils.getInstance().incr(key, 0);
        incr = RedisClusterUtils.getInstance().incr(key, 0);
        logger.info("【incr】 {}={}", key, incr);
        assertEquals("incr失败,返回结果不为3", "3", String.valueOf(incr));
    }

    /**
     * key的值加给定值.
     */
    @Test
    public void testIncrBy() {
        String key = "unittest:incrby";
        RedisClusterUtils.getInstance().del(key);
        long incr = 0l;
        incr = RedisClusterUtils.getInstance().incrBy(key, 5);
        incr = RedisClusterUtils.getInstance().incrBy(key, 10);
        logger.info("【incrby】 {}={}", key, incr);
        assertEquals("incrby失败,返回结果不为15", "15", String.valueOf(incr));
    }

    /**
     * key的值加给定值—自动删除.
     */
    @Test
    public void testIncrExpirt() throws InterruptedException {
        long incr = 0l;
        String key = "unittest:incr_expirt";
        RedisClusterUtils.getInstance().del(key);
        incr = RedisClusterUtils.getInstance().incr(key, 5);
        incr = RedisClusterUtils.getInstance().incr(key, 5);
        incr = RedisClusterUtils.getInstance().incr(key, 5);
        logger.info("【incr_expirt】 {}={}", key, incr);
        Thread.sleep(6000);
        final String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【incr_expirt】 {}={}", key, redisValue);
        assertNull("incr_expirt失败,还能查到值", redisValue);
    }

    /**
     * key的值减1.
     */
    @Test
    public void testDecr() {
        String key = "unittest:decr";
        RedisClusterUtils.getInstance().del(key);

        // 先增加3
        long incr = 0l;
        incr = RedisClusterUtils.getInstance().incr(key, 0);
        incr = RedisClusterUtils.getInstance().incr(key, 0);
        incr = RedisClusterUtils.getInstance().incr(key, 0);

        // 再减2
        incr = RedisClusterUtils.getInstance().decr(key, 0);
        incr = RedisClusterUtils.getInstance().decr(key, 0);

        // 最终等于1
        logger.info("【decr】 {}={}", key, incr);
        assertEquals("decr失败,返回结果不为1", "1", String.valueOf(incr));
    }

    /**
     * key的值减给定值.
     */
    @Test
    public void testDecrBy() {
        String key = "unittest:decrby";
        RedisClusterUtils.getInstance().del(key);

        // 先增加30
        long incr = 0l;
        incr = RedisClusterUtils.getInstance().incrBy(key, 10);
        incr = RedisClusterUtils.getInstance().incrBy(key, 10);
        incr = RedisClusterUtils.getInstance().incrBy(key, 10);

        // 再减20
        incr = RedisClusterUtils.getInstance().decrBy(key, 10);
        incr = RedisClusterUtils.getInstance().decrBy(key, 10);

        // 最终等于10
        logger.info("【decrby】 {}={}", key, incr);
        assertEquals("decr失败,返回结果不为10", "10", String.valueOf(incr));
    }

    /**
     * key的值减给定值—自动删除.
     * @throws InterruptedException
     */
    @Test
    public void testDecrExpirt() throws InterruptedException {
        String key = "unittest:decr_expirt";
        RedisClusterUtils.getInstance().del(key);

        // 先增加3
        long incr = 0l;
        incr = RedisClusterUtils.getInstance().incr(key, 10);
        incr = RedisClusterUtils.getInstance().incr(key, 10);
        incr = RedisClusterUtils.getInstance().incr(key, 10);

        // 再减2
        incr = RedisClusterUtils.getInstance().decr(key, 10);
        incr = RedisClusterUtils.getInstance().decr(key, 10);
        logger.info("【decr_expirt】 {}={}", key, incr);
        Thread.sleep(11000);
        final String redisValue = RedisClusterUtils.getInstance().get(key);
        logger.info("【decr_expirt】 {}={}", key, redisValue);
        assertNull("decr_expirt失败,还能查到值", redisValue);
    }


    // =================================================================================================================
    // list列表操作
    // =================================================================================================================
    @Test
    public void testlpush() {
        String key = "unittest:lpush";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go");

        final Long llen = RedisClusterUtils.getInstance().llen(key);
        logger.info("【lpush】 {}={}", key, llen);
        assertEquals("lpush失败,返回结果不为2", "2", String.valueOf(llen));
    }

    @Test
    public void testrpush() {
        String key = "unittest:rpush";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().rpush(key, "payhon", "c++");

        final Long llen = RedisClusterUtils.getInstance().llen(key);
        logger.info("【rpush】 {}={}", key, llen);
        assertEquals("rpush失败,返回结果不为2", "2", String.valueOf(llen));
    }

    @Test
    public void testlrem() {
        String key = "unittest:lrem";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "python", "c++");
        RedisClusterUtils.getInstance().lrem(key, "c++");
        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, 1);
        final String redisValue = lrange.get(0);
        logger.info("【lrem】 {}={}", key, redisValue);
        assertEquals("lrem失败,返回结果不为1", "1", String.valueOf(lrange.size()));
        assertEquals("lrem失败,返回结果不为python", "python", redisValue);
    }

    @Test
    public void testllen() {
        String key = "unittest:llen";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");

        final Long llen = RedisClusterUtils.getInstance().llen(key);
        logger.info("【llen】 {}={}", key, llen);
        assertEquals("llen失败,返回结果不为4", "4", String.valueOf(llen));
    }

    @Test
    public void testlset() {
        String key = "unittest:lset";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");
        RedisClusterUtils.getInstance().lset(key, 0, "c++1");
        RedisClusterUtils.getInstance().lset(key, 2, "go1");

        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, -1);
        final String redisValue0 = lrange.get(0);
        final String redisValue2 = lrange.get(2);
        logger.info("【lset】 {}={}", key, redisValue0);
        logger.info("【lset】 {}={}", key, redisValue2);
        assertEquals("lset失败,返回结果不为c++1", "c++1", redisValue0);
        assertEquals("lset失败,返回结果不为go1", "go1", redisValue2);
    }

    @Test
    public void testlindex() {
        String key = "unittest:lindex";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");
        final String redisValue = RedisClusterUtils.getInstance().lindex(key, 0);
        logger.info("【lindex】 {}={}", key, redisValue);
        assertEquals("lindex失败,返回结果不为c++", "c++", redisValue);
    }

    @Test
    public void testlrange() {
        String key = "unittest:lrange";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");

        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, -1);
        logger.info("【lrange】 {}={}", key, lrange);
        assertEquals("lrange失败,返回结果不为4", "4", String.valueOf(lrange.size()));
    }

    @Test
    public void testlrangeLimit() {
        String key = "unittest:lrange_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().lpush(key, "java" + i);
        }

        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, -1);
        logger.info("【lrange_limit】 {}={}", key, lrange.size());
        logger.info("【lrange_limit】 {}={}", key, lrange);
        assertEquals("lrange_limit失败,返回结果不为2000", "2000", String.valueOf(lrange.size()));
    }

    @Test
    public void testltrim() {
        String key = "unittest:ltrim";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");
        RedisClusterUtils.getInstance().ltrim(key, 0, 1);

        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, -1);
        logger.info("【ltrim】 {}={}", key, lrange);
        assertEquals("ltrim失败,返回结果不为2", "2", String.valueOf(lrange.size()));
    }

    @Test
    public void testlpop() {
        String key = "unittest:lpop";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");
        final String redisValue = RedisClusterUtils.getInstance().lpop(key);

        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, -1);
        logger.info("【lpop】 {}={}", key, redisValue);
        logger.info("【lpop】 {}={}", key, lrange);
        assertEquals("lpop失败,返回结果不为c++", "c++", redisValue);
        assertEquals("lpop失败,返回结果不为3", "3", String.valueOf(lrange.size()));
    }

    @Test
    public void testrpop() {
        String key = "unittest:rpop";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().lpush(key, "java", "go", "python", "c++");
        final String redisValue = RedisClusterUtils.getInstance().rpop(key);

        final List<String> lrange = RedisClusterUtils.getInstance().lrange(key, 0, -1);
        logger.info("【rpop】 {}={}", key, redisValue);
        logger.info("【rpop】 {}={}", key, lrange);
        assertEquals("rpop失败,返回结果不为java", "java", redisValue);
        assertEquals("rpop失败,返回结果不为3", "3", String.valueOf(lrange.size()));
    }

    @Test
    public void testdelBigList() {
        String key = "unittest:delbigList";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=10000; i++) {
            RedisClusterUtils.getInstance().lpush(key, "java" + i);
        }
        Long llen = RedisClusterUtils.getInstance().llen(key);
        logger.info("【delbigList】 {}={}", key, llen);
        assertEquals("delbigList失败,返回结果不为10000", "10000", String.valueOf(llen));

        RedisClusterUtils.getInstance().delBigList(key);
        llen = RedisClusterUtils.getInstance().llen(key);
        logger.info("【delbigList】 {}={}", key, llen);
        assertEquals("delbigList失败,返回结果不为0", "0", String.valueOf(llen));
    }



    // =================================================================================================================
    // map哈希操作
    // =================================================================================================================
    @Test
    public void testhset() {
        String key = "unittest:hset";
        String field = "name";
        String value = "caoweixiong";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().hset(key, field, value);
        final String redisValue = RedisClusterUtils.getInstance().hget(key, field);
        logger.info("【hset】 {}={}", key, redisValue);
        assertEquals("hset失败,返回结果不为caoweixiong", value, redisValue);
    }

    @Test
    public void testhget() {
        String key = "unittest:hget";
        String field1 = "name";
        String value1 = "caoweixiong";
        String field2 = "age";
        String value2 = "35";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().hset(key, field1, value1);
        RedisClusterUtils.getInstance().hset(key, field2, value2);
        final String redisValue1 = RedisClusterUtils.getInstance().hget(key, field1);
        final String redisValue2 = RedisClusterUtils.getInstance().hget(key, field2);
        logger.info("【hget】 {}={}", key, redisValue1);
        logger.info("【hget】 {}={}", key, redisValue2);
        assertEquals("hset失败,返回结果不为caoweixiong", value1, redisValue1);
        assertEquals("hget失败,返回结果不为35", value2, redisValue2);
    }

    @Test
    public void testhsetnx() {
        String key = "unittest:hsetnx";
        String field = "name";
        String value = "caoweixiong";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().hsetnx(key, field, value);
        final String redisValue1 = RedisClusterUtils.getInstance().hget(key, field);
        logger.info("【hsetnx】 {}={}", key, redisValue1);
        assertEquals("hsetnx失败,返回结果不为caoweixiong", value, redisValue1);

        RedisClusterUtils.getInstance().hsetnx(key, field, "caoweixiong2");
        final String redisValue2 = RedisClusterUtils.getInstance().hget(key, field);
        logger.info("【hsetnx】 {}={}", key, redisValue2);
        assertEquals("hsetnx失败,返回结果不为caoweixiong", value, redisValue2);
    }

    @Test
    public void testhmset() {
        String key = "unittest:hmset";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        final Long hlen = RedisClusterUtils.getInstance().hlen(key);
        logger.info("【hmset】 {}={}", key, hlen);
        assertEquals("hmset失败,返回结果不为3", "3", String.valueOf(hlen));
    }

    @Test
    public void testhmget() {
        String key = "unittest:hmget";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        final List<String> hmget = RedisClusterUtils.getInstance().hmget(key, "name", "age");
        logger.info("【hmget】 {}={}", key, hmget);
        assertEquals("hmget失败,返回结果不为2", "2", String.valueOf(hmget.size()));
    }

    @Test
    public void testhlen() {
        String key = "unittest:hlen";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        final Long hlen = RedisClusterUtils.getInstance().hlen(key);
        logger.info("【hlen】 {}={}", key, hlen);
        assertEquals("hlen失败,返回结果不为3", "3", String.valueOf(hlen));
    }

    @Test
    public void testhdel() {
        String key = "unittest:hdel";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        RedisClusterUtils.getInstance().hdel(key, "name", "sex");

        final Long hlen = RedisClusterUtils.getInstance().hlen(key);
        logger.info("【hdel】 {}={}", key, hlen);
        assertEquals("hdel失败,返回结果不为1", "1", String.valueOf(hlen));
    }

    @Test
    public void testhexists() {
        String key = "unittest:hexists";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        Boolean name = RedisClusterUtils.getInstance().hexists(key, "name");
        logger.info("【hexists】 {}={}", key, name);
        assertEquals("hexists失败,返回结果不为true", "true", String.valueOf(name));

        RedisClusterUtils.getInstance().hdel(key, "name");
        name = RedisClusterUtils.getInstance().hexists(key, "name");
        logger.info("【hexists】 {}={}", key, name);
        assertEquals("hexists失败,返回结果不为false", "false", String.valueOf(name));
    }

    @Test
    public void testhkeys() {
        String key = "unittest:hkeys";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        final Set<String> hkeys = RedisClusterUtils.getInstance().hkeys(key);
        logger.info("【hkeys】 {}={}", key, hkeys);
        assertEquals("hkeys失败,返回结果不为3", "3", String.valueOf(hkeys.size()));
    }

    @Test
    public void testhkeysLimit() {
        String key = "unittest:hkeys_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().hset(key, "name" + i, "cwx" + i);
        }
        final Set<String> hkeys = RedisClusterUtils.getInstance().hkeys(key);
        logger.info("【hkeys_limit】 {}={}", key, hkeys.size());
        logger.info("【hkeys_limit】 {}={}", key, hkeys);
        assertEquals("hkeys_limit失败,返回结果不为2000", "2000", String.valueOf(hkeys.size()));
    }

    @Test
    public void testhvals() {
        String key = "unittest:hvals";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        final List<String> hvals = RedisClusterUtils.getInstance().hvals(key);
        logger.info("【hvals】 {}={}", key, hvals);
        assertEquals("hvals失败,返回结果不为3", "3", String.valueOf(hvals.size()));
    }

    @Test
    public void testhvalsLimit() {
        String key = "unittest:hvals_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().hset(key, "name" + i, "cwx" + i);
        }
        final List<String> hvals = RedisClusterUtils.getInstance().hvals(key);
        logger.info("【hvals_limit】 {}={}", key, hvals.size());
        logger.info("【hvals_limit】 {}={}", key, hvals);
        assertEquals("hvals_limit失败,返回结果不为2000", "2000", String.valueOf(hvals.size()));
    }

    @Test
    public void testhgetall() {
        String key = "unittest:hgetall";
        RedisClusterUtils.getInstance().del(key);
        Map<String, String> hashValue = new HashMap<>();
        hashValue.put("name", "caoweixiong");
        hashValue.put("age", "35");
        hashValue.put("sex", "man");
        RedisClusterUtils.getInstance().hmset(key, hashValue);

        final Map<String, String> allMap = RedisClusterUtils.getInstance().hgetAll(key);
        logger.info("【hgetall】 {}={}", key, allMap);
        assertEquals("hgetall失败,返回结果不为3", "3", String.valueOf(allMap.size()));
    }

    @Test
    public void testhgetallLimit() {
        String key = "unittest:hgetall_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().hset(key, "name" + i, "cwx" + i);
        }
        final Map<String, String> allMap = RedisClusterUtils.getInstance().hgetAll(key);
        logger.info("【hgetall_limit】 {}={}", key, allMap.size());
        logger.info("【hgetall_limit】 {}={}", key, allMap);
        assertEquals("hgetall_limit失败,返回结果不为2000", "2000", String.valueOf(allMap.size()));
    }

    @Test
    public void testhscan() {
        String key = "unittest:hscan";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().hset(key, "name" + i, "cwx" + i);
        }

        final Map<String, String> allMap = new HashMap<>();
        String cursor = "0";
        do {
            final ScanResult<Map.Entry<String, String>> scanResult = RedisClusterUtils.getInstance().hscan(key, cursor);
            final List<Map.Entry<String, String>> entityList = scanResult.getResult();
            if (null != entityList && !entityList.isEmpty()) {
                for (Map.Entry<String, String> entry : entityList) {
                    allMap.put(entry.getKey(), entry.getValue());
                }
            }
            logger.info("cursor={}", cursor);
            cursor = scanResult.getStringCursor();
        } while (!"0".equals(cursor));

        logger.info("【hscan】 {}={}", key, allMap.size());
        logger.info("【hscan】 {}={}", key, allMap);
        assertEquals("hscan失败,返回结果不为2100", "2100", String.valueOf(allMap.size()));
    }

    @Test
    public void testhscanParam() {
        String key = "unittest:hscan_param";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().hset(key, "name" + i, "cwx" + i);
        }

        final Map<String, String> allMap = new HashMap<>();
        String cursor = "0";
        ScanParams params = new ScanParams();
        params.count(200);
        params.match("name1*");
        do {
            final ScanResult<Map.Entry<String, String>> scanResult = RedisClusterUtils.getInstance().hscan(key, cursor, params);
            final List<Map.Entry<String, String>> entityList = scanResult.getResult();
            if (null != entityList && !entityList.isEmpty()) {
                for (Map.Entry<String, String> entry : entityList) {
                    allMap.put(entry.getKey(), entry.getValue());
                }
            }
            logger.info("cursor={}", cursor);
            cursor = scanResult.getStringCursor();
        } while (!"0".equals(cursor));

        logger.info("【hscan_param】 {}={}", key, allMap.size());
        logger.info("【hscan_param】 {}={}", key, allMap);
        assertEquals("hscan_param失败,返回结果不为1111", "1111", String.valueOf(allMap.size()));
    }

    @Test
    public void testdelBigHash() {
        String key = "unittest:delBigHash";
        for (int i=1; i<=10000; i++) {
            RedisClusterUtils.getInstance().hset(key, "name" + i, "cwx" + i);
        }
        Long hlen = RedisClusterUtils.getInstance().hlen(key);
        logger.info("【delBigHash】 {}={}", key, hlen);
        assertEquals("delBigHash失败,返回结果不为10000", "10000", String.valueOf(hlen));

        RedisClusterUtils.getInstance().delBigHash(key);

        hlen = RedisClusterUtils.getInstance().hlen(key);
        logger.info("【delBigHash】 {}={}", key, hlen);
        assertEquals("delBigHash失败,返回结果不为0", "0", String.valueOf(hlen));
    }



    // =================================================================================================================
    // set集合操作
    // =================================================================================================================
    @Test
    public void testsadd() {
        String key = "unittest:sadd";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().sadd(key, "apple");
        RedisClusterUtils.getInstance().sadd(key, "orange", "banana");

        final Long scard = RedisClusterUtils.getInstance().scard(key);
        logger.info("【sadd】 {}={}", key, scard);
        assertEquals("sadd失败,返回结果不为3", "3", String.valueOf(scard));
    }

    @Test
    public void testsrem() {
        String key = "unittest:srem";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().sadd(key, "apple", "orange", "banana");
        Long scard = RedisClusterUtils.getInstance().scard(key);
        logger.info("【srem】 {}={}", key, scard);
        assertEquals("srem失败,返回结果不为3", "3", String.valueOf(scard));

        RedisClusterUtils.getInstance().srem(key, "apple");

        scard = RedisClusterUtils.getInstance().scard(key);
        logger.info("【srem】 {}={}", key, scard);
        assertEquals("srem失败,返回结果不为2", "2", String.valueOf(scard));
    }

    @Test
    public void testscard() {
        String key = "unittest:scard";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().sadd(key, "orange", "banana");

        final Long scard = RedisClusterUtils.getInstance().scard(key);
        logger.info("【scard】 {}={}", key, scard);
        assertEquals("scard失败,返回结果不为2", "2", String.valueOf(scard));
    }

    @Test
    public void testsismember() {
        String key = "unittest:sismember";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().sadd(key, "apple", "orange", "banana");
        boolean apple = RedisClusterUtils.getInstance().sismember(key, "apple");
        logger.info("【sismember】 {}={}", key, apple);
        assertEquals("sismember失败,返回结果不为true", "true", String.valueOf(apple));

        RedisClusterUtils.getInstance().srem(key, "apple");

        apple = RedisClusterUtils.getInstance().sismember(key, "apple");
        logger.info("【sismember】 {}={}", key, apple);
        assertEquals("sismember失败,返回结果不为false", "false", String.valueOf(apple));
    }

    @Test
    public void testsmembers() {
        String key = "unittest:smembers";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().sadd(key, "apple", "orange", "banana");

        final Set<String> smembers = RedisClusterUtils.getInstance().smembers(key);
        logger.info("【smembers】 {}={}", key, smembers);
        assertEquals("smembers失败,返回结果不为3", "3", String.valueOf(smembers.size()));
    }

    @Test
    public void testsmembersLimit() {
        String key = "unittest:smembers_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().sadd(key, "apple" + i);
        }

        final Set<String> smembers = RedisClusterUtils.getInstance().smembers(key);
        logger.info("【smembers_limit】 {}={}", key, smembers.size());
        logger.info("【smembers_limit】 {}={}", key, smembers);
        assertEquals("smembers_limit失败,返回结果不为2000", "2000", String.valueOf(smembers.size()));
    }

    @Test
    public void testsunion() {
        String key1 = "{unittest:sunion}1";
        String key2 = "{unittest:sunion}2";
        RedisClusterUtils.getInstance().del(key1);
        RedisClusterUtils.getInstance().del(key2);
        RedisClusterUtils.getInstance().sadd(key1, "apple", "orange", "banana");
        RedisClusterUtils.getInstance().sadd(key2, "apple", "pea", "red");

        final Set<String> smembers = RedisClusterUtils.getInstance().sunion(key1, key2);
        logger.info("【sunion】 {}", smembers);
        assertEquals("sunion失败,返回结果不为5", "5", String.valueOf(smembers.size()));
    }

    @Test
    public void testsdiff() {
        String key1 = "{unittest:sdiff}1";
        String key2 = "{unittest:sdiff}2";
        RedisClusterUtils.getInstance().del(key1);
        RedisClusterUtils.getInstance().del(key2);
        RedisClusterUtils.getInstance().sadd(key1, "apple", "orange", "banana");
        RedisClusterUtils.getInstance().sadd(key2, "apple", "pea", "red");

        final Set<String> smembers = RedisClusterUtils.getInstance().sdiff(key1, key2);
        logger.info("【sdiff】 {}", smembers);
        assertEquals("sdiff,返回结果不为2", "2", String.valueOf(smembers.size()));
    }

    @Test
    public void testsinter() {
        String key1 = "{unittest:sinter}1";
        String key2 = "{unittest:sinter}2";
        RedisClusterUtils.getInstance().del(key1);
        RedisClusterUtils.getInstance().del(key2);
        RedisClusterUtils.getInstance().sadd(key1, "apple", "orange", "banana");
        RedisClusterUtils.getInstance().sadd(key2, "apple", "pea", "red");

        final Set<String> smembers = RedisClusterUtils.getInstance().sinter(key1, key2);
        logger.info("【sinter】 {}", smembers);
        assertEquals("sinter失败,返回结果不为1", "1", String.valueOf(smembers.size()));
    }

    @Test
    public void testsscan() {
        String key = "unittest:sscan";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().sadd(key, "java" + i);
        }

        final Map<String, String> allMap = new HashMap<>();
        String cursor = "0";
        do {
            final ScanResult<String> scanResult = RedisClusterUtils.getInstance().sscan(key, cursor);
            final List<String> result = scanResult.getResult();
            if (null != result && !result.isEmpty()) {
                for (String member : result) {
                    allMap.put(member, member);
                }
            }
            logger.info("cursor={}", cursor);
            cursor = scanResult.getStringCursor();
        } while (!"0".equals(cursor));

        logger.info("【sscan】 {}={}", key, allMap.size());
        logger.info("【sscan】 {}={}", key, allMap);
        assertEquals("sscan失败,返回结果不为2100", "2100", String.valueOf(allMap.size()));
    }

    @Test
    public void testhsscanParam() {
        String key = "unittest:sscan_param";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().sadd(key, "java" + i);
        }

        final Map<String, String> allMap = new HashMap<>();
        String cursor = "0";
        ScanParams params = new ScanParams();
        params.count(200);
        params.match("java1*");
        do {
            final ScanResult<String> scanResult = RedisClusterUtils.getInstance().sscan(key, cursor, params);
            final List<String> result = scanResult.getResult();
            if (null != result && !result.isEmpty()) {
                for (String member : result) {
                    allMap.put(member, member);
                }
            }
            logger.info("cursor={}", cursor);
            cursor = scanResult.getStringCursor();
        } while (!"0".equals(cursor));
        logger.info("【sscan_param】 {}={}", key, allMap.size());
        logger.info("【sscan_param】 {}={}", key, allMap);
        assertEquals("sscan_param失败,返回结果不为1111", "1111", String.valueOf(allMap.size()));
    }

    @Test
    public void testdelBigSset() {
        String key = "unittest:delBigSset";
        for (int i=1; i<=10000; i++) {
            RedisClusterUtils.getInstance().sadd(key, "java" + i);
        }
        Long hlen = RedisClusterUtils.getInstance().scard(key);
        logger.info("【delBigSset】 {}={}", key, hlen);
        assertEquals("delBigSset失败,返回结果不为10000", "10000", String.valueOf(hlen));

        RedisClusterUtils.getInstance().delBigSet(key);

        hlen = RedisClusterUtils.getInstance().scard(key);
        logger.info("【delBigSset】 {}={}", key, hlen);
        assertEquals("delBigSset失败,返回结果不为0", "0", String.valueOf(hlen));
    }


    // =================================================================================================================
    // zset有序集合操作
    // =================================================================================================================
    @Test
    public void testzadd() {
        String key = "unittest:zadd";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");

        final Set<String> zrange = RedisClusterUtils.getInstance().zrange(key, 0, -1);
        logger.info("【zadd】 {}={}", key, zrange.size());
        logger.info("【zadd】 {}={}", key, zrange);
        assertEquals("zadd失败,返回结果不为1", "1", String.valueOf(zrange.size()));
    }

    @Test
    public void testzaddMap() {
        String key = "unittest:zadd_map";
        RedisClusterUtils.getInstance().del(key);

        Map<String, Double> score = new HashMap<>();
        score.put("java", 80d);
        score.put("go", 90d);
        score.put("python", 100d);
        RedisClusterUtils.getInstance().zadd(key, score);

        final Set<String> zrange = RedisClusterUtils.getInstance().zrange(key, 0, -1);
        logger.info("【zadd_map】 {}={}", key, zrange.size());
        logger.info("【zadd_map】 {}={}", key, zrange);
        assertEquals("zadd_map失败,返回结果不为3", "3", String.valueOf(zrange.size()));
    }

    @Test
    public void testzrange() {
        String key = "unittest:zrange";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        final Set<String> zrange = RedisClusterUtils.getInstance().zrange(key, 0, -1);
        logger.info("【zrange】 {}={}", key, zrange.size());
        logger.info("【zrange】 {}={}", key, zrange);
        assertEquals("zrange失败,返回结果不为2", "2", String.valueOf(zrange.size()));
    }

    @Test
    public void testzrangeLimit() {
        String key = "unittest:zrange_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().zadd(key, 80 + i, "java" + i);
        }
        final Set<String> zrange = RedisClusterUtils.getInstance().zrange(key, 0, -1);
        logger.info("【zrange_limit】 {}={}", key, zrange.size());
        logger.info("【zrange_limit】 {}={}", key, zrange);
        assertEquals("zrange_limit失败,返回结果不为2000", "2000", String.valueOf(zrange.size()));
    }

    @Test
    public void testzrangeWithScores() {
        String key = "unittest:zrangeWithScores";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        double score;
        final Set<Tuple> go = RedisClusterUtils.getInstance().zrangeWithScores(key, 0, -1);
        for (Tuple tuple : go) {
            score = tuple.getScore();
            logger.info("【zrangeWithScores】 {}={}", tuple.getElement(), score);
        }
        assertEquals("zrangeWithScores失败,返回结果不为2", "2", String.valueOf(go.size()));
    }

    @Test
    public void testzrangeWithScoresLimit() {
        String key = "unittest:zrangeWithScores_limit";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().zadd(key, 80 + i, "java" + i);
        }

        double score;
        final Set<Tuple> go = RedisClusterUtils.getInstance().zrangeWithScores(key, 0, -1);
        logger.info("【zrangeWithScores_limit】 {}={}", key, go.size());
        for (Tuple tuple : go) {
            score = tuple.getScore();
            logger.info("【zrangeWithScores_limit】 {}={}", tuple.getElement(), score);
        }
        assertEquals("zrangeWithScores_limit失败,返回结果不为2000", "2000", String.valueOf(go.size()));
    }

    @Test
    public void testzrevrangeByScore() {
        String key = "unittest:zrevrangeByScore";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        double score;
        final Set<String> strings = RedisClusterUtils.getInstance().zrevrangeByScore(key, "100", "90", 0, 100);
        for (String s : strings) {
            logger.info("【zrevrangeByScore】 {}={}", key, s);
        }
        assertEquals("zrevrangeByScore失败,返回结果不为2", "2", String.valueOf(strings.size()));
    }

    @Test
    public void testzcard() {
        String key = "unittest:zcard";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        final Long zcard = RedisClusterUtils.getInstance().zcard(key);
        logger.info("【zcard】 {}={}", key, zcard);
        assertEquals("zcard失败,返回结果不为2", "2", String.valueOf(zcard));
    }

    @Test
    public void testzrem() {
        String key = "unittest:zrem";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        Long zcard = RedisClusterUtils.getInstance().zcard(key);
        logger.info("【zrem】 {}={}", key, zcard);
        assertEquals("zrem失败,返回结果不为2", "2", String.valueOf(zcard));

        RedisClusterUtils.getInstance().zrem(key, "java");

        zcard = RedisClusterUtils.getInstance().zcard(key);
        logger.info("【zrem】 {}={}", key, zcard);
        assertEquals("zrem失败,返回结果不为1", "1", String.valueOf(zcard));
    }

    @Test
    public void testzremrangeByRank() {
        String key = "unittest:zremrangeByRank";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        final Long zcount = RedisClusterUtils.getInstance().zremrangeByRank(key, 2, 2);
        logger.info("【zremrangeByRank】 {}={}", key, zcount);

        final Set<String> zrange = RedisClusterUtils.getInstance().zrange(key, 0, -1);
        logger.info("【zremrangeByRank】 {}={}", key, zrange.size());
        logger.info("【zremrangeByRank】 {}={}", key, zrange);

        assertEquals("zremrangeByRank失败,移除分值第3名的成員後,大小不等於2", "2", String.valueOf(zrange.size()));
    }

    @Test
    public void testzremrangeByScore() {
        String key = "unittest:zremrangeByScore";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        final Long zcount = RedisClusterUtils.getInstance().zremrangeByScore(key, 80, 90);
        logger.info("【zremrangeByScore】 {}={}", key, zcount);

        final Set<String> zrange = RedisClusterUtils.getInstance().zrange(key, 0, -1);
        logger.info("【zremrangeByScore】 {}={}", key, zrange.size());
        logger.info("【zremrangeByScore】 {}={}", key, zrange);

        assertEquals("zremrangeByScore失败,移除分值80~90的成員後,大小不等於1", "1", String.valueOf(zrange.size()));
    }

    @Test
    public void testzscore() {
        String key = "unittest:zscore";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        final Double java = RedisClusterUtils.getInstance().zscore(key, "java");
        logger.info("【zscore】 {}={}", key, java);
        assertEquals("zscore失败,成員java的分值不等於80", "80.0", String.valueOf(java));
    }

    @Test
    public void testzcount() {
        String key = "unittest:zcount";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        final Long zcount = RedisClusterUtils.getInstance().zcount(key, 90, 100);
        logger.info("【zcount】 {}={}", key, zcount);
        assertEquals("zcount失败,分值在90~100之間的成員不等於2", "2", String.valueOf(zcount));
    }

    @Test
    public void testzincrby() {
        String key = "unittest:zincrby";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        final Double java = RedisClusterUtils.getInstance().zincrby(key, 1, "java");
        logger.info("【zincrby】 {}={}", key, java);

        final Double java1 = RedisClusterUtils.getInstance().zscore(key, "java");
        logger.info("【zincrby】 {}={}", key, java1);
        assertEquals("zincrby失败,返回结果不为81", "81.0", String.valueOf(java1));
    }

    @Test
    public void testzrank() {
        String key = "unittest:zrank";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");

        final Long java = RedisClusterUtils.getInstance().zrank(key, "go");
        logger.info("【zrank】 {}={}", key, java);

        assertEquals("zrank失败,返回结果不为1", "1", String.valueOf(java));
    }

    @Test
    public void testzrevrank() {
        String key = "unittest:zrevrank";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        final Long java = RedisClusterUtils.getInstance().zrevrank(key, "python");
        logger.info("【zrevrank】 {}={}", key, java);

        assertEquals("zrevrank失败,返回结果不为0", "0", String.valueOf(java));
    }

    @Test
    public void testzrevrange() {
        String key = "unittest:zrevrange";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        final Set<String> zrevrange = RedisClusterUtils.getInstance().zrevrange(key, 0, -1);
        logger.info("【zrevrange】 {}={}", key, zrevrange);

        int i=0;
        String first = "";
        for (String s : zrevrange) {
            if (i==0) {
                first = s;
            }
            logger.info("【zrevrange】 {}{}={}", key, i, s);
            i++;
        }

        assertEquals("zrevrange失败,排名第1的成員不是python", "python", first);
    }

    @Test
    public void testzrevrangeWithScores() {
        String key = "unittest:zrevrangeWithScores";
        RedisClusterUtils.getInstance().del(key);
        RedisClusterUtils.getInstance().zadd(key, 80, "java");
        RedisClusterUtils.getInstance().zadd(key, 90, "go");
        RedisClusterUtils.getInstance().zadd(key, 100, "python");

        final Set<Tuple> tuples = RedisClusterUtils.getInstance().zrevrangeWithScores(key, 0, -1);
        int i=0;
        String firstElement = "";
        double firstScore = 0;
        for (Tuple tuple : tuples) {
            if (i==0) {
                firstElement = tuple.getElement();
                firstScore = tuple.getScore();
            }
            logger.info("【zrevrangeWithScores】 {}_{}_{}={}", key, i, tuple.getElement(), tuple.getScore());
            i++;
        }
        assertEquals("zrevrangeWithScores失败,排名第1的成員不是python", "python", firstElement);
        assertEquals("zrevrangeWithScores失败,排名第1的成員的值不是100.0", "100.0", String.valueOf(firstScore));
    }

    @Test
    public void testzscan() {
        String key = "unittest:zscan";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().zadd(key, 80 + i, "java" + i);
        }

        final Map<String, String> allMap = new HashMap<>();
        String cursor = "0";
        do {
            final ScanResult<Tuple> zcanResult = RedisClusterUtils.getInstance().zscan(key, cursor);
            final List<Tuple> result = zcanResult.getResult();
            if (null != result && !result.isEmpty()) {
                for (Tuple tuple : result) {
                    allMap.put(tuple.getElement(), String.valueOf(tuple.getScore()));
                }
            }
            logger.info("cursor={}", cursor);
            cursor = zcanResult.getStringCursor();
        } while (!"0".equals(cursor));

        logger.info("【zscan】 {}={}", key, allMap.size());
        logger.info("【zscan】 {}={}", key, allMap);
        assertEquals("zscan失败,返回结果不为2100", "2100", String.valueOf(allMap.size()));
    }

    @Test
    public void testhzcanParam() {
        String key = "unittest:zscan_param";
        RedisClusterUtils.getInstance().del(key);
        for (int i=1; i<=2100; i++) {
            RedisClusterUtils.getInstance().zadd(key, 80 + i, "java" + i);
        }

        final Map<String, String> allMap = new HashMap<>();
        String cursor = "0";
        ScanParams params = new ScanParams();
        params.count(200);
        params.match("java1*");
        do {
            final ScanResult<Tuple> zcanResult = RedisClusterUtils.getInstance().zscan(key, cursor, params);
            final List<Tuple> result = zcanResult.getResult();
            if (null != result && !result.isEmpty()) {
                for (Tuple tuple : result) {
                    allMap.put(tuple.getElement(), String.valueOf(tuple.getScore()));
                }
            }
            logger.info("cursor={}", cursor);
            cursor = zcanResult.getStringCursor();
        } while (!"0".equals(cursor));

        logger.info("【zscan_param】 {}={}", key, allMap.size());
        logger.info("【zscan_param】 {}={}", key, allMap);
        assertEquals("zscan_param失败,返回结果不为1111", "1111", String.valueOf(allMap.size()));
    }

    @Test
    public void testdelBigZset() {
        String key = "unittest:delBigZset";
        for (int i=1; i<=10000; i++) {
            RedisClusterUtils.getInstance().zadd(key, 80 + i, "java" + i);
        }
        Long hlen = RedisClusterUtils.getInstance().zcard(key);
        logger.info("【delBigZset】 {}={}", key, hlen);
        assertEquals("delBigHash失败,返回结果不为10000", "10000", String.valueOf(hlen));

        RedisClusterUtils.getInstance().delBigZset(key);

        hlen = RedisClusterUtils.getInstance().zcard(key);
        logger.info("【delBigZset】 {}={}", key, hlen);
        assertEquals("delBigZset失败,返回结果不为0", "0", String.valueOf(hlen));
    }

}