redis-jedis-热爱与分享

jedis方法

菜鸟教程:https://www.runoob.com/redis/redis-keys.html

这里记录一些比较有意思的方法

  • 有效期
    Long pexpire(String key, long milliseconds);//时间单位是毫秒
    Long pexpireAt(String key, long millisecondsTimestamp);;//过期时间是具体的时间戳
  • 扫描参数(这个入参在很多地方使用到)
    ScanParams scanParams = new ScanParams().count(5).match("key*");
  • 扫描大数据
    ScanResult<String> scan(String cursor, ScanParams params);//scan字符串扫描,sscan set集合扫描,hscan hash扫描,zscan zset扫描
  • 递增递减
    Long incrBy(String key, long increment);//指定步长递增,还有递减方法,另外对于hash也有对应的递增递减方法
  • 批量处理
    List<String> mget(String... keys);//还有mset,提高效率,其他数据类型也有对应的方法
  • get和del同步
    String getDel(String key);//对于需要删除和返回的业务场景
  • 异步del
    Long unlink(String... keys);//可以取代del提高效率,特别是大的hash或者list
  • 序列化
    byte[] dump(String key);//对于需要使用到网络传输的,可以考虑序列化value
  • 小内存保存布尔类型
    Boolean setbit(String key, long offset, boolean value);//相对比keyValue,这个方式将会在一个value上保存多个boolean值,应该注意这里采用下标作为区分,可用于黑名单过滤。获取用getbit
  • 分布式锁
    Long setnx(String key, String value);//如果是同一个业务上不同的key做分布式锁,可以用hsetnx
  • 随机数
    String hrandfield(String key);//可以适应与随机返回业务,另外有lrange是list随机数,spop、srandmember是针对set随机数
  • 两个集合之间的数据迁移
    String lmove(String srcKey, String dstKey, ListDirection from, ListDirection to);还有一个操作是带阻塞和失效时间的brpoplpush,smove是对set集合从操作
  • 阻塞式弹出list的元素
    List<String> blpop(int timeout, String... keys);
  • 删除集合中具体的成员
    Long lrem(String key, long count, String value);//srem删除set中的具体成员
  • 获取指定下标的元素
    List<String> lrange(String key, long start, long stop);//另外还有去空ltrim,trem删除
  • set和zset中的交集并集合集
    差集:sdiff,sdiffstore
    交集:sinter,sinterstore
    并集:sunion,sunionstore
  • 集合set或者list的排序sort
    一种是设置排序规则,另一种是按照默认的数字排序
  • zset可以添加并且分数可以递增
  • zset获取区间包括zrange、zrevrange和zrangeWithScores,还有很多与score有关的操作

jedis类中的所有方法

//----------------------------------------------------key--------------------------------------------------------------

    /**
     * 删除多个key,如果key不存在,不做任何操作,最终返回的是删除的个数。
     * <p>
     * Remove the specified keys. If a given key does not exist no operation is performed for this
     * key. The command returns the number of keys removed. Time complexity: O(1)
     *
     * @param keys
     * @return Integer reply, specifically: an integer greater than 0 if one or more keys were removed
     * 0 if none of the specified key existed
     */
    Long del(String... keys);

    /**
     * 删除一个key
     */
    Long del(String key);

    /**
     * 判断key是否存在,存在返回true,不存在返回false
     * 即使保存的是空字符串也返回true
     * Test if the specified key exists. The command returns true if the key exists, otherwise false is
     * returned. Note that even keys set with an empty string as value will return true. Time
     * complexity: O(1)
     *
     * @param key
     * @return Boolean reply, true if the key exists, otherwise false
     */
    Boolean exists(String key);

    /**
     * 设置key的失效时间,
     * 失效的key也会像其他的不失效key一样在磁盘保存,
     * redis保存的时间是不再可用的Unix时间戳,而不是保存入参的剩余秒数(redis会转为具体的时间戳)
     * redis2.1.3之后,可以修改过期值
     * <p>
     * Set a timeout on the specified key. After the timeout the key will be automatically deleted by
     * the server. A key with an associated timeout is said to be volatile in Redis terminology.
     * <p>
     * Volatile keys are stored on disk like the other keys, the timeout is persistent too like all
     * the other aspects of the dataset. Saving a dataset containing expires and stopping the server
     * does not stop the flow of time as Redis stores on disk the time when the key will no longer be
     * available as Unix time, and not the remaining seconds.
     * <p>
     * Since Redis 2.1.3 you can update the value of the timeout of a key already having an expire
     * set. It is also possible to undo the expire at all turning the key into a normal key using the
     * {@link #persist(String) PERSIST} command.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param seconds
     * @return Integer reply, specifically: 1: the timeout was set. 0: the timeout was not set since
     * the key already has an associated timeout (this may happen only in Redis versions &lt;
     * 2.1.3, Redis &gt;= 2.1.3 will happily update the timeout), or the key does not exist.
     * @see <a href="http://redis.io/commands/expire">Expire Command</a>
     */
    Long expire(String key, long seconds);

    /**
     * 与expire(String, int)类似,但是expire需要redis对失效时间转为unix时间戳,
     * 而这条命令是直接设置到期的时间戳,时间的单位是秒,时间是相对于1970年1月
     * <p>
     * EXPIREAT works exactly like {@link #expire(String, int) EXPIRE} but instead to get the number
     * of seconds representing the Time To Live of the key as a second argument (that is a relative
     * way of specifying the TTL), it takes an absolute one in the form of a UNIX timestamp (Number of
     * seconds elapsed since 1 Gen 1970).
     * <p>
     * EXPIREAT was introduced in order to implement the Append Only File persistence mode so that
     * EXPIRE commands are automatically translated into EXPIREAT commands for the append only file.
     * Of course EXPIREAT can also used by programmers that need a way to simply specify that a given
     * key should expire at a given time in the future.
     * <p>
     * Since Redis 2.1.3 you can update the value of the timeout of a key already having an expire
     * set. It is also possible to undo the expire at all turning the key into a normal key using the
     * {@link #persist(String) PERSIST} command.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param unixTime
     * @return Integer reply, specifically: 1: the timeout was set. 0: the timeout was not set since
     * the key already has an associated timeout (this may happen only in Redis versions &lt;
     * 2.1.3, Redis &gt;= 2.1.3 will happily update the timeout), or the key does not exist.
     * @see <a href="http://redis.io/commands/expire">Expire Command</a>
     */
    Long expireAt(String key, long unixTime);

    /**
     * 过期时间设置,单位是毫秒
     */
    Long pexpire(String key, long milliseconds);

    /**
     * 具体过期时间戳设置,单位是毫秒
     */
    Long pexpireAt(String key, long millisecondsTimestamp);

    /**
     * 返回key的剩余存活秒数,
     * <p>
     * The TTL command returns the remaining time to live in seconds of a key that has an
     * {@link #expire(String, int) EXPIRE} set. This introspection capability allows a Redis client to
     * check how many seconds a given key will continue to be part of the dataset.
     *
     * @param key
     * @return Integer reply, returns the remaining time to live in seconds of a key that has an
     * EXPIRE. In Redis 2.6 or older, if the Key does not exists or does not have an
     * associated expire, -1 is returned. In Redis 2.8 or newer, if the Key does not have an
     * associated expire, -1 is returned or if the Key does not exists, -2 is returned.
     */
    Long ttl(String key);

    /**
     * 功能跟ttl相同,返回的是毫秒
     * setex
     * pexpire
     */
    Long pttl(String key);

    /**
     * 返回符合正则表达式的key
     * 比如"user*"
     */
    Set<String> keys(final String pattern);

    /**
     * 返回一个随机key
     */
    String randomKey();

    /**
     * 对key进行重命名,如果存在名字跟新的key名字相同,类型相同,就会导致报错
     * <p>
     * Atomically renames the key oldkey to newkey. If the source and destination name are the same an
     * error is returned. If newkey already exists it is overwritten.
     * <p>
     * Time complexity: O(1)
     *
     * @param oldkey
     * @param newkey
     * @return Status code repy
     */
    String rename(final String oldkey, final String newkey);

    /**
     * 如果存在名字跟新的key名字相同,就会返回0
     * 相对rename来说比较严格,但是不会报错,所以重命名更加推荐
     * nx实际上就是说不存在才能成功
     * <p>
     * Rename oldkey into newkey but fails if the destination key newkey already exists.
     * <p>
     * Time complexity: O(1)
     *
     * @param oldkey
     * @param newkey
     * @return Integer reply, specifically: 1 if the key was renamed 0 if the target key already exist
     */
    Long renamenx(final String oldkey, final String newkey);

    /**
     * 将key移动到指定数据库位置
     * 查看菜鸟教程,select 可以切换数据
     * <p>
     * Move the specified key from the currently selected DB to the specified destination DB. Note
     * that this command returns 1 only if the key was successfully moved, and 0 if the target key was
     * already there or if the source key was not found at all, so it is possible to use MOVE as a
     * locking primitive.
     *
     * @param key
     * @param dbIndex
     * @return Integer reply, specifically: 1 if the key was moved 0 if the key was not moved because
     * already present on the target DB or was not found in the current DB.
     */
    Long move(String key, int dbIndex);


    /**
     * 移除给定 key 的过期时间,使得 key 永不过期
     * 返回1或者0
     */
    Long persist(String key);

    /**
     * 返回数据类型,如果key不存在,返回none
     * <p>
     * Return the type of the value stored at key in form of a string. The type can be one of "none",
     * "string", "list", "set". "none" is returned if the key does not exist. Time complexity: O(1)
     *
     * @param key
     * @return Status code reply, specifically: "none" if the key does not exist "string" if the key
     * contains a String value "list" if the key contains a List value "set" if the key
     * contains a Set value "zset" if the key contains a Sorted Set value "hash" if the key
     * contains a Hash value
     */
    String type(String key);

    /**
     * 查看ScanParams.SCAN_POINTER_START = "0"
     * <p>
     * ScanResult<String> scan = jedisPool.getResource().scan(ScanParams.SCAN_POINTER_START);
     * String cursor = scan.getCursor();
     * List<String> result = scan.getResult();
     *
     * @param cursor
     * @return
     */
    ScanResult<String> scan(String cursor);

    /**
     * 迭代数据库中的数据库键
     * 返回的是增量迭代器,scan不会像keys()造成服务器阻塞,scan可以在生产上使用,
     * scan根据游标进行扫描,所以存在返回重复数据的可能。
     * 返回包括游标和迭代的数组
     * <p>
     * ScanParams设置返回的个数和通配符
     * ScanParams scanParams = new ScanParams().count(5).match("key*");
     * ScanResult<String> scan = jedisPool.getResource().scan(ScanParams.SCAN_POINTER_START,scanParams);
     * String cursor = scan.getCursor();
     * List<String> result = scan.getResult();
     * <p>
     * 从上面的代码也可以看出,scan是根据确定游标执行扫描的,个数和通配符可配置,
     * 这种情况下,实际上就是人为控制scan,保证redis不阻塞
     * <p>
     * ------------------------------------------------------------------------------------------------------
     * Iterates the set of keys in the currently selected Redis database.
     * <p>
     * Since this command allows for incremental iteration, returning only a small number of elements
     * per call, it can be used in production without the downside of commands like
     * {@link #keys(String)} or {@link JedisCommands#smembers(String)} )} that may block the server
     * for a long time (even several seconds) when called against big collections of keys or elements.
     * <p>
     * SCAN basic usage
     * SCAN is a cursor based iterator. This means that at every call of the command, the server
     * returns an updated cursor that the user needs to use as the cursor argument in the next call.
     * An iteration starts when the cursor is set to 0, and terminates when the cursor returned by the
     * server is 0.
     * <p>
     * Scan guarantees
     * The SCAN command, and the other commands in the SCAN family, are able to provide to the user a
     * set of guarantees associated to full iterations.
     * <p>
     * A full iteration always retrieves all the elements that were present in the collection from
     * the start to the end of a full iteration. This means that if a given element is inside the
     * collection when an iteration is started, and is still there when an iteration terminates, then
     * at some point SCAN returned it to the user.
     * A full iteration never returns any element that was NOT present in the collection from the
     * start to the end of a full iteration. So if an element was removed before the start of an
     * iteration, and is never added back to the collection for all the time an iteration lasts, SCAN
     * ensures that this element will never be returned.
     * <p>
     * However because SCAN has very little state associated (just the cursor) it has the following
     * drawbacks:
     * <p>
     * A given element may be returned multiple times. It is up to the application to handle the
     * case of duplicated elements, for example only using the returned elements in order to perform
     * operations that are safe when re-applied multiple times.
     * Elements that were not constantly present in the collection during a full iteration, may be
     * returned or not: it is undefined.
     * <p>
     * <p>
     * Time complexity: O(1) for every call. O(N) for a complete iteration, including enough command
     * calls for the cursor to return back to 0. N is the number of elements inside the DB.
     *
     * @param cursor The cursor.
     * @param params the scan parameters. For example a glob-style match pattern
     * @return the scan result with the results of this iteration and the new position of the cursor
     * @see <a href="https://redis.io/commands/scan">Redis SCAN documentation</a>
     */
    ScanResult<String> scan(String cursor, ScanParams params);

    /**
     * 迭代集合键中的元素value
     */
    ScanResult<String> sscan(String key, String cursor);

    ScanResult<String> sscan(String key, String cursor, ScanParams params);

    /**
     * 迭代哈希键中的键值对
     */
    ScanResult<Map.Entry<String, String>> hscan(String key, String cursor);

    ScanResult<Map.Entry<String, String>> hscan(String key, String cursor, ScanParams params);

    /**
     * 迭代有序集合中的元素(包括元素成员和元素分值)
     */
    ScanResult<Tuple> zscan(String key, String cursor);

    ScanResult<Tuple> zscan(String key, String cursor, ScanParams params);

//---------------------------------------------------string-------------------------------------------------------------

    /**
     * 设置键值对,value不能大于1G,实际上大value会带来各种问题,一般都是要进行拆分
     * Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
     * GB).
     * 时间复杂度为O(1)
     * Time complexity: O(1)
     */
    String set(String key, String value);

    /**
     * 【组合命令】自定义set的属性,相当于组合命令,可以设置失效时间,是否存在
     * SetParams是一个静态变量类,
     * 静态变量XX表示当key存在的时候可以设置
     * 静态变量EX失效时间为秒
     * 静态变量PX失效时间为毫秒
     * 从SetParams.setParams().ex(12345L),其实这个就是一个动态的设置方式,
     * redis的其他的方法也能相似的功能,这里只不多可以自定义
     *
     * @param params NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the
     *               key if it already exist. EX|PX, expire time units: EX = seconds; PX = milliseconds
     */
    String set(String key, String value, SetParams params);

    /**
     * 设置批量的键值对,
     * msetnx是当存在一个key是已经存在的,就会操作失败
     * MSETNX是为了确保每个key不同
     * <p>
     * Set the the respective keys to the respective values. MSET will replace old values with new
     * values, while {@link #msetnx(String...) MSETNX} will not perform any operation at all even if
     * just a single key already exists.
     * <p>
     * Because of this semantic MSETNX can be used in order to set different keys representing
     * different fields of an unique logic object in a way that ensures that either all the fields or
     * none at all are set.
     * <p>
     * Both MSET and MSETNX are atomic operations. This means that for instance if the keys A and B
     * are modified, another client talking to Redis can either see the changes to both A and B at
     * once, or no modification at all.
     *
     * @param keysvalues
     * @return Status code reply Basically +OK as MSET can't fail
     * @see #msetnx(String...)
     */
    String mset(String... keysvalues);

    /**
     * 当存在一个相同的key,所有的键值对都修改失败
     * <p>
     * Set the the respective keys to the respective values. {@link #mset(String...) MSET} will
     * replace old values with new values, while MSETNX will not perform any operation at all even if
     * just a single key already exists.
     * <p>
     * Because of this semantic MSETNX can be used in order to set different keys representing
     * different fields of an unique logic object in a way that ensures that either all the fields or
     * none at all are set.
     * <p>
     * Both MSET and MSETNX are atomic operations. This means that for instance if the keys A and B
     * are modified, another client talking to Redis can either see the changes to both A and B at
     * once, or no modification at all.
     *
     * @param keysvalues
     * @return Integer reply, specifically: 1 if the all the keys were set 0 if no key was set (at
     * least one key already existed)
     * @see #mset(String...)
     */
    Long msetnx(String... keysvalues);

    /**
     * 覆盖原来的value,覆盖的位置从偏移量开始
     */
    Long setrange(String key, long offset, String value);

    /**
     * 如果不存在,就设置成功,
     * 返回1或者0
     * <p>
     * SETNX works exactly like {@link #set(String, String) SET} with the only difference that if the
     * key already exists no operation is performed. SETNX actually means "SET if Not eXists".
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param value
     * @return Integer reply, specifically: 1 if the key was set 0 if the key was not set
     */
    Long setnx(String key, String value);


    /**
     * @deprecated Use {@link #setex(java.lang.String, long, java.lang.String)}.
     */
    @Deprecated
    default String setex(String key, int seconds, String value) {
        return setex(key, (long) seconds, value);
    }

    /**
     * 对key设置秒级别的有效期
     */
    String setex(String key, long seconds, String value);

    /**
     * 对key设置毫秒级别的有效期
     */
    String psetex(String key, long milliseconds, String value);

    /**
     * key所包含的数字按照decrement进行递减,不存在就从0开始,如果value不是数字,就报错
     * 递减差值最大是16位数字
     * <p>
     * IDECRBY work just like {@link #decr(String) INCR} but instead to decrement by 1 the decrement
     * is integer.
     * <p>
     * INCR commands are limited to 64 bit signed integers.
     * <p>
     * Note: this is actually a string operation, that is, in Redis there are not "integer" types.
     * Simply the string stored at the key is parsed as a base 10 64 bit signed integer, incremented,
     * and then converted back as a string.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param decrement
     * @return Integer reply, this commands will reply with the new value of key after the increment.
     * @see #incr(String)
     * @see #decr(String)
     * @see #incrBy(String, long)
     */
    Long decrBy(String key, long decrement);

    /**
     * value的值按照1进行递减,不存在就从0开始
     * <p>
     * Decrement the number stored at key by one. If the key does not exist or contains a value of a
     * wrong type, set the key to the value of "0" before to perform the decrement operation.
     * <p>
     * INCR commands are limited to 64 bit signed integers.
     * <p>
     * Note: this is actually a string operation, that is, in Redis there are not "integer" types.
     * Simply the string stored at the key is parsed as a base 10 64 bit signed integer, incremented,
     * and then converted back as a string.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @return Integer reply, this commands will reply with the new value of key after the increment.
     * @see #incr(String)
     * @see #incrBy(String, long)
     * @see #decrBy(String, long)
     */
    Long decr(String key);

    Long incr(String key);

    /**
     * value的值按照指定步长increment进行递增,不存在就从0开始
     */
    Long incrBy(String key, long increment);

    /**
     * redis没有double类型,所以实际上是将字符串转为双精度的数字,计算之后转为字符串类型进行赋值
     * <p>
     * INCRBYFLOAT commands are limited to double precision floating point values.
     * <p>
     * Note: this is actually a string operation, that is, in Redis there are not "double" types.
     * Simply the string stored at the key is parsed as a base double precision floating point value,
     * incremented, and then converted back as a string. There is no DECRYBYFLOAT but providing a
     * negative value will work as expected.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param increment
     * @return Double reply, this commands will reply with the new value of key after the increment.
     */
    Double incrByFloat(String key, double increment);

    /**
     * 如果key存在,这个请求的value会拼接在原来的value后面,
     * 如果key不存在,会创建一个空字符串,所以效果等同于set(key,value)
     * 返回字符串的总长度
     * <p>
     * If the key already exists and is a string, this command appends the provided value at the end
     * of the string. If the key does not exist it is created and set as an empty string, so APPEND
     * will be very similar to SET in this special case.
     * <p>
     * Time complexity: O(1). The amortized time complexity is O(1) assuming the appended value is
     * small and the already present value is of any size, since the dynamic string library used by
     * Redis will double the free space available on every reallocation.
     *
     * @param key
     * @param value
     * @return Integer reply, specifically the total length of the string after the append operation.
     */
    Long append(String key, String value);

    /**
     * 返回字符串的start到end区间的字符串(包括start和end)
     * -1表示最后一个字符,-2表示倒数第二个字符
     * 下标越界的时候会报错
     * <p>
     * Return a subset of the string from offset start to offset end (both offsets are inclusive).
     * Negative offsets can be used in order to provide an offset starting from the end of the string.
     * So -1 means the last char, -2 the penultimate and so forth.
     * <p>
     * The function handles out of range requests without raising an error, but just limiting the
     * resulting range to the actual length of the string.
     * <p>
     * Time complexity: O(start+n) (with start being the start index and n the total length of the
     * requested range). Note that the lookup part of this command is O(1) so for small strings this
     * is actually an O(1) command.
     *
     * @param key
     * @param start
     * @param end
     * @return Bulk reply
     */
    String substr(String key, int start, int end);

    /**
     * 实际测试结果跟substr结果一样
     */
    String getrange(String key, long startOffset, long endOffset);

    /**
     * 当key不存在,返回null,如果存储的value不是string,返回异常。
     * 存在checkIsInMultiOrPipeline();所以get一定要进行异常的捕捉,这是一个重点。
     * 并且所有的get都有判断value是否为string
     * Get the value of the specified key. If the key does not exist the special value 'nil' is
     * returned. If the value stored at key is not a string an error is returned because GET can only
     * handle string values.
     * <p>
     * Time complexity: O(1)
     */
    String get(String key);

    /**
     * 【组合命令】获取老的value,并用新的value进行覆盖
     * 如果key不存在,就返回新value
     * <p>
     * GETSET is an atomic set this value and return the old value command. Set key to the string
     * value and return the old value stored at key. The string can't be longer than 1073741824 bytes
     * (1 GB).
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param value
     * @return Bulk reply
     */
    String getSet(String key, String value);

    /**
     * 批量获取键值对
     * 如果有key不存在或者value不是string,返回nil,但是不会导致命令失败
     * <p>
     * Get the values of all the specified keys. If one or more keys don't exist or is not of type
     * String, a 'nil' value is returned instead of the value of the specified key, but the operation
     * never fails.
     * <p>
     * Time complexity: O(1) for every key
     *
     * @param keys
     * @return Multi bulk reply
     */
    List<String> mget(String... keys);


    /**
     * 【组合命令】获取对应value的同时,删除key。
     * 这里的前提条件是value是string类型,需要捕捉异常
     * Get the value of key and delete the key. This command is similar to GET, except for the fact
     * that it also deletes the key on success (if and only if the key's value type is a string).
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @return the value of key
     * @since Redis 6.2
     */
    String getDel(String key);

    /**
     * 【组合命令】get之后,对key修改失效时间
     * 自定义GetExParams
     * 这里相当于限定了返回的条件,秒,毫秒,微妙,纳秒,删除失效时间
     */
    String getEx(String key, GetExParams params);


    /**
     * 这个命令与del相似,只是实际的删除是采用异步执行,所以不阻塞,但是del是阻塞的。
     * 这个命令的效果就是断开key的空间连接,实际的删除是在之后发生。
     * <p>
     * This command is very similar to DEL: it removes the specified keys. Just like DEL a key is
     * ignored if it does not exist. However the command performs the actual memory reclaiming in a
     * different thread, so it is not blocking, while DEL is. This is where the command name comes
     * from: the command just unlinks the keys from the keyspace. The actual removal will happen later
     * asynchronously.
     * <p>
     * Time complexity: O(1) for each key removed regardless of its size. Then the command does O(N)
     * work in a different thread in order to reclaim memory, where N is the number of allocations the
     * deleted objects where composed of.
     *
     * @param keys
     * @return Integer reply: The number of keys that were unlinked
     */
    Long unlink(String... keys);

    /**
     * 异步删除单个key
     */
    Long unlink(String key);


    /**
     * 更改key的最后访问时间,返回更改的个数
     * <p>
     * Alters the last access time of a key(s). A key is ignored if it does not exist.
     * Time complexity: O(N) where N is the number of keys that will be touched.
     *
     * @param keys
     * @return Integer reply: The number of keys that were touched.
     */
    Long touch(String... keys);

    Long touch(String key);

    /**
     * @deprecated Use {@link #restore(java.lang.String, long, byte[])}.
     */
    @Deprecated
    default String restore(String key, int ttl, byte[] serializedValue) {
        return restore(key, (long) ttl, serializedValue);
    }

    /**
     * 序列化给定 key ,并返回被序列化的值
     * 通常用于网络传输或者跨平台
     */
    byte[] dump(String key);

    /**
     * 反序列化,跟序列化相对
     */
    String restore(String key, long ttl, byte[] serializedValue);

    /**
     * 反序列化,可以设置参数
     */
    String restore(String key, long ttl, byte[] serializedValue, RestoreParams params);

    /**
     * 返回vlaue的长度
     */
    Long strlen(String key);

    /**
     * 设置或者清理bit在字符串的偏移量
     * 因为bit只有0或者1,所以这里用boolean没有问题
     * <p>
     * Sets or clears the bit at offset in the string value stored at key
     *
     * @param key
     * @param offset
     * @param value
     * @return
     */
    Boolean setbit(String key, long offset, boolean value);

    /**
     * value必须是0或者1,否则会报错,所以不推荐使用
     */
    Boolean setbit(String key, long offset, String value);

    /**
     * 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
     * 默认情况是返回0,也就是false
     */
    Boolean getbit(String key, long offset);

//-----------------------------------------------hash---------------------------------------------------------------

    /**
     * 如果field已经存在,直接覆盖,返回0
     * 如果field不存在,返回1
     */
    Long hset(String key, String field, String value);

    Long hset(String key, Map<String, String> hash);

    String hget(String key, String field);

    /**
     * 当field不存在的时候,返回1
     * 当field存在的时候,返回0
     */
    Long hsetnx(String key, String field, String value);

    String hmset(String key, Map<String, String> hash);

    List<String> hmget(String key, String... fields);

    /**
     * 跟incrBy相似
     */
    Long hincrBy(String key, String field, long value);

    Double hincrByFloat(String key, String field, double value);

    /**
     * 判断field是否存在
     */
    Boolean hexists(String key, String field);

    /**
     * 删除多个field,返回删除的个数
     */
    Long hdel(String key, String... field);

    /**
     * 返回field的个数
     */
    Long hlen(String key);

    /**
     * 返回所有的field
     */
    Set<String> hkeys(String key);

    /**
     * 返回hash的所有value
     */
    List<String> hvals(String key);

    /**
     * 返回hash的所有键值对
     */
    Map<String, String> hgetAll(String key);

    /**
     * 随机返回一个field
     */
    String hrandfield(String key);

    /**
     * 随机返回多个field
     */
    List<String> hrandfield(String key, long count);

    /**
     * 随机返回多个键值对
     */
    Map<String, String> hrandfieldWithValues(String key, long count);

    //------------------------------------------------list----------------------------------------------------------

    /**
     * 添加字符串到list的头部L或者尾部R,
     * 如果key对应的list不存在,则创建一个空list
     * 如果key存在,但不是list结构,就会报错(string和hash都没有这样的描述)
     * rpush是尾部插入
     * <p>
     * Add the string value to the head (LPUSH) or tail (RPUSH) of the list stored at key. If the key
     * does not exist an empty list is created just before the append operation. If the key exists but
     * is not a List an error is returned.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @param strings
     * @return Integer reply, specifically, the number of elements inside the list after the push
     * operation.
     */
    Long rpush(String key, String... strings);

    /**
     * 头部插入
     */
    Long lpush(String key, String... string);

    /**
     * list队列的长度
     */
    Long llen(String key);

    /**
     * 从左边到右边,下标是从0开始递增
     * 从右边到左边,下标是从-1开始递减
     * 比如(0,2)是左边三个,(-1,-3)是右边三个
     * 下边越界不会导致异常,而是返回一个空的list
     * <p>
     * Return the specified elements of the list stored at the specified key. Start and end are
     * zero-based indexes. 0 is the first element of the list (the list head), 1 the next element and
     * so on.
     * <p>
     * For example LRANGE foobar 0 2 will return the first three elements of the list.
     * <p>
     * start and end can also be negative numbers indicating offsets from the end of the list. For
     * example -1 is the last element of the list, -2 the penultimate element and so on.
     * <p>
     * Consistency with range functions in various programming languages
     * <p>
     * Note that if you have a list of numbers from 0 to 100, LRANGE 0 10 will return 11 elements,
     * that is, rightmost item is included. This may or may not be consistent with behavior of
     * range-related functions in your programming language of choice (think Ruby's Range.new,
     * Array#slice or Python's range() function).
     * <p>
     * LRANGE behavior is consistent with one of Tcl.
     * <p>
     * Out-of-range indexes
     * <p>
     * Indexes out of range will not produce an error: if start is over the end of the list, or start
     * &gt; end, an empty list is returned. If end is over the end of the list Redis will threat it
     * just like the last element of the list.
     * <p>
     * Time complexity: O(start+n) (with n being the length of the range and start being the start
     * offset)
     *
     * @param key
     * @param start
     * @param stop
     * @return Multi bulk reply, specifically a list of elements in the specified range.
     */
    List<String> lrange(String key, long start, long stop);

    /**
     * 去除空元素
     * 一般去掉尾部的元素,比如原本就只有3个,获取的stop是99,其实后面都是空
     */
    String ltrim(String key, long start, long stop);

    /**
     * 获取队列某个下标的元素
     * 从左边计算是从0开始,从右边计算是从-1开始
     * 如果下边越界,返回nil
     */
    String lindex(String key, long index);

    /**
     * 通过key的下标设置一个新的value,如果下标越界会导致错误。
     * 下标-1表示最后一个元素,-2表示倒数第二个元素
     * <p>
     * Set a new value as the element at index position of the List at key.
     * Out of range indexes will generate an error.
     * <p>
     * Similarly to other list commands accepting indexes, the index can be negative to access
     * elements starting from the end of the list. So -1 is the last element, -2 is the penultimate,
     * and so forth.
     * <p>
     * Time complexity:
     * O(N) (with N being the length of the list), setting the first or last elements of the list is
     * O(1).
     */
    String lset(String key, long index, String value);

    /**
     * 根据count删除list中的与value相同的元素,正负号表示从左到右,或者从右到左,-2表示删除右边的两个元素
     * 如果count是0,表示删除所有的元素
     * key不存在的时候,返回0
     * <p>
     * Remove the first count occurrences of the value element from the list. If count is zero all the
     * elements are removed. If count is negative elements are removed from tail to head, instead to
     * go from head to tail that is the normal behaviour. So for example LREM with count -2 and hello
     * as value to remove against the list (a,b,c,hello,x,hello,hello) will leave the list
     * (a,b,c,hello,x). The number of removed elements is returned as an integer, see below for more
     * information about the returned value. Note that non existing keys are considered like empty
     * lists by LREM, so LREM against non existing keys will always return 0.
     * <p>
     * Time complexity: O(N) (with N being the length of the list)
     *
     * @return Integer Reply, specifically: The number of removed elements if the operation succeeded
     */
    Long lrem(String key, long count, String value);

    /**
     * 返回并删除第一个元素(左边或者右边)
     * 如果key不存在,返回nil
     * <p>
     * Atomically return and remove the first (LPOP) or last (RPOP) element of the list. For example
     * if the list contains the elements "a","b","c" LPOP will return "a" and the list will become
     * "b","c".
     * <p>
     * If the key does not exist or the list is already empty the special value 'nil' is returned.
     */
    String lpop(String key);

    /**
     * 返回并删除count个元素,如果key不存在,返回nil
     */
    List<String> lpop(String key, int count);

    /**
     * 删除list中的element元素,删除一个元素,返回0或者1
     */
    Long lpos(String key, String element);

    Long lpos(String key, String element, LPosParams params);

    List<Long> lpos(String key, String element, LPosParams params, long count);

    /**
     * list中移除元素,ListDirection静态变量包括了左和右
     */
    String lmove(String srcKey, String dstKey, ListDirection from, ListDirection to);

    /**
     * 在lmove的基础上增加了延时
     */
    String blmove(String srcKey, String dstKey, ListDirection from, ListDirection to, double timeout);

    /**
     * lpop和rpop都不是阻塞式,blpop和brpop是阻塞式,当key不存在或者是空集合的时候,请求会阻塞
     * 返回两个元素的数组,第一个是key,第二个是value
     * 如果blpop三个list中,第一个是不存在,第二个第三个是空list,这个时候会先监听list2
     * 当处于阻塞状态,如果客户端存入数据,就会理解被监听到
     * 当出现超时,返回nil,如果超时时间是0,就相当于永久阻塞
     * 如果监听多个key相同,key会被放入队列中,逐个监听
     * blpop可以放在管道流操作中,但是不可以放在事务中,这样会导致无限阻塞
     * <p>
     * BLPOP (and BRPOP) is a blocking list pop primitive. You can see this commands as blocking
     * versions of LPOP and RPOP able to block if the specified keys don't exist or contain empty
     * lists.
     * <p>
     * The following is a description of the exact semantic. We describe BLPOP but the two commands
     * are identical, the only difference is that BLPOP pops the element from the left (head) of the
     * list, and BRPOP pops from the right (tail).
     * <p>
     * <b>Non blocking behavior</b>
     * <p>
     * When BLPOP is called, if at least one of the specified keys contain a non empty list, an
     * element is popped from the head of the list and returned to the caller together with the name
     * of the key (BLPOP returns a two elements array, the first element is the key, the second the
     * popped value).
     * <p>
     * Keys are scanned from left to right, so for instance if you issue BLPOP list1 list2 list3 0
     * against a dataset where list1 does not exist but list2 and list3 contain non empty lists, BLPOP
     * guarantees to return an element from the list stored at list2 (since it is the first non empty
     * list starting from the left).
     * <p>
     * <b>Blocking behavior</b>
     * <p>
     * If none of the specified keys exist or contain non empty lists, BLPOP blocks until some other
     * client performs a LPUSH or an RPUSH operation against one of the lists.
     * <p>
     * Once new data is present on one of the lists, the client finally returns with the name of the
     * key unblocking it and the popped value.
     * <p>
     * When blocking, if a non-zero timeout is specified, the client will unblock returning a nil
     * special value if the specified amount of seconds passed without a push operation against at
     * least one of the specified keys.
     * <p>
     * The timeout argument is interpreted as an integer value. A timeout of zero means instead to
     * block forever.
     * <p>
     * <b>Multiple clients blocking for the same keys</b>
     * <p>
     * Multiple clients can block for the same key. They are put into a queue, so the first to be
     * served will be the one that started to wait earlier, in a first-blpopping first-served fashion.
     * <p>
     * <b>blocking POP inside a MULTI/EXEC transaction</b>
     * <p>
     * BLPOP and BRPOP can be used with pipelining (sending multiple commands and reading the replies
     * in batch), but it does not make sense to use BLPOP or BRPOP inside a MULTI/EXEC block (a Redis
     * transaction).
     * <p>
     * The behavior of BLPOP inside MULTI/EXEC when the list is empty is to return a multi-bulk nil
     * reply, exactly what happens when the timeout is reached. If you like science fiction, think at
     * it like if inside MULTI/EXEC the time will flow at infinite speed :)
     * <p>
     * Time complexity: O(1)
     *
     * @param timeout
     * @param keys
     * @return BLPOP returns a two-elements array via a multi bulk reply in order to return both the
     * unblocking key and the popped value.
     * <p>
     * When a non-zero timeout is specified, and the BLPOP operation timed out, the return
     * value is a nil multi bulk reply. Most client values will return false or nil
     * accordingly to the programming language used.
     * @see #brpop(int, String...)
     */
    List<String> blpop(int timeout, String... keys);

    /**
     * 注解同上
     */
    KeyedListElement blpop(double timeout, String... keys);

    /**
     * 注解同上
     */
    List<String> brpop(int timeout, String... keys);

    /**
     * 注解同上
     */
    KeyedListElement brpop(double timeout, String... keys);

    List<String> blpop(int timeout, String key);

    KeyedListElement blpop(double timeout, String key);

    List<String> blpop(String... args);

    List<String> brpop(String... args);

    KeyedZSetElement bzpopmax(double timeout, String... keys);

    KeyedZSetElement bzpopmin(double timeout, String... keys);

    String rpop(String key);

    List<String> rpop(String key, int count);

    List<String> brpop(int timeout, String key);

    KeyedListElement brpop(double timeout, String key);

    /**
     * 在指定元素pivot的左边ListPosition.BEFORE或者右边ListPosition.AFTER插入value,
     * 当元素pivot不存在的时候,不做任何操作
     */
    Long linsert(String key, ListPosition where, String pivot, String value);

    /**
     * 当key存在的时候,可以插入
     */
    Long lpushx(String key, String... string);

    /**
     * 当key存在的时候,可以插入
     */
    Long rpushx(String key, String... string);

    /**
     * 从source list的右边pop一个元素存放到destination左边,超时时间是timeout
     */
    String brpoplpush(String source, String destination, int timeout);


    //-----------------------------------------------------set------------------------------------------------------------

    /**
     * 添加成员到set集合,
     * 如果成员已经存在,不做任何操作,这里不会像java那样覆盖
     * 如果key不是一个set类型,报错
     * <p>
     * Add the specified member to the set value stored at key. If member is already a member of the
     * set no operation is performed. If key does not exist a new set with the specified member as
     * sole member is created. If the key exists but does not hold a set value an error is returned.
     * <p>
     * Time complexity O(1)
     *
     * @param key
     * @param members
     * @return Integer reply, specifically: 1 if the new element was added 0 if the element was
     * already a member of the set
     */
    Long sadd(String key, String... member);

    /**
     * 返回set中所有的成员
     */
    Set<String> smembers(String key);

    /**
     * 删除具体的成员
     */
    Long srem(String key, String... member);

    /**
     * 随机获取多个随机数
     */
    Set<String> spop(String key, long count);

    String spop(String key);

    /**
     * 将成员member从srckey迁移到dstkey
     * 如果数据源的成员变量不存在,不做任何操作,
     * 如果是目标数据源已经存在了成员,会返回1
     * 数据源或者目标源不是set将会导致报错
     * <p>
     * Move the specified member from the set at srckey to the set at dstkey. This operation is
     * atomic, in every given moment the element will appear to be in the source or destination set
     * for accessing clients.
     * <p>
     * If the source set does not exist or does not contain the specified element no operation is
     * performed and zero is returned, otherwise the element is removed from the source set and added
     * to the destination set. On success one is returned, even if the element was already present in
     * the destination set.
     * <p>
     * An error is raised if the source or destination keys contain a non Set value.
     * <p>
     * Time complexity O(1)
     *
     * @param srckey
     * @param dstkey
     * @param member
     * @return Integer reply, specifically: 1 if the element was moved 0 if the element was not found
     * on the first set and no operation was performed
     */
    Long smove(String srckey, String dstkey, String member);

    /**
     * 返回存储在key1处的集合与所有集合key2,…,keyN之间的差值
     */
    Set<String> sdiff(String... keys);

    /**
     * 功能上与sdiff相同,但是返回的是一个long
     */
    Long sdiffstore(String dstkey, String... keys);

    /**
     * 交集
     */
    Set<String> sinter(String... keys);

    /**
     * 功能与sinter相同
     */
    Long sinterstore(String dstkey, String... keys);

    /**
     * 根据指定的参数对集合或列表进行排序,并将结果存储在dstkey。
     */
    Long sort(String key, SortingParams sortingParameters, String dstkey);

    /**
     * 默认进行数字的排序,结果存储到dstkey
     */
    Long sort(String key, String dstkey);

    /**
     * 并集,相似功能可以查看LRANG
     */
    Set<String> sunion(String... keys);

    /**
     * 功能与sunion相同
     */
    Long sunionstore(String dstkey, String... keys);

    String watch(String... keys);

    String unwatch();

    Long scard(String key);

    /**
     * 判断set重是否存在
     */
    Boolean sismember(String key, String member);

    /**
     * 判断set是否存在,判断的参数是数组
     */
    List<Boolean> smismember(String key, String... members);

    /**
     * set中随机返回一个元素
     * */
    String srandmember(String key);

    /**
     * 获取count个随机成员变量
     */
    List<String> srandmember(String key, int count);

    //-----------------------------------------------------zset-----------------------------------------------------------

    Long zadd(String key, double score, String member);

    Long zadd(String key, double score, String member, ZAddParams params);

    Long zadd(String key, Map<String, Double> scoreMembers);

    Long zadd(String key, Map<String, Double> scoreMembers, ZAddParams params);

    Double zaddIncr(String key, double score, String member, ZAddParams params);

    Set<String> zrange(String key, long start, long stop);

    Long zrem(String key, String... members);

    Double zincrby(String key, double increment, String member);

    Double zincrby(String key, double increment, String member, ZIncrByParams params);

    Long zrank(String key, String member);

    Long zrevrank(String key, String member);

    Set<String> zrevrange(String key, long start, long stop);

    Set<Tuple> zrangeWithScores(String key, long start, long stop);

    Set<Tuple> zrevrangeWithScores(String key, long start, long stop);

    String zrandmember(String key);

    Set<String> zrandmember(String key, long count);

    Set<Tuple> zrandmemberWithScores(String key, long count);

    Long zcard(String key);

    Double zscore(String key, String member);

    List<Double> zmscore(String key, String... members);

    Tuple zpopmax(String key);

    Set<Tuple> zpopmax(String key, int count);

    Tuple zpopmin(String key);

    Set<Tuple> zpopmin(String key, int count);

    List<String> sort(String key);

    List<String> sort(String key, SortingParams sortingParameters);

    Long zcount(String key, double min, double max);

    Long zcount(String key, String min, String max);

    Set<String> zrangeByScore(String key, double min, double max);

    Set<String> zrangeByScore(String key, String min, String max);

    Set<String> zrevrangeByScore(String key, double max, double min);

    Set<String> zrangeByScore(String key, double min, double max, int offset, int count);

    Set<String> zrevrangeByScore(String key, String max, String min);

    Set<String> zrangeByScore(String key, String min, String max, int offset, int count);

    Set<String> zrevrangeByScore(String key, double max, double min, int offset, int count);

    Set<Tuple> zrangeByScoreWithScores(String key, double min, double max);

    Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min);

    Set<Tuple> zrangeByScoreWithScores(String key, double min, double max, int offset, int count);

    Set<String> zrevrangeByScore(String key, String max, String min, int offset, int count);

    Set<Tuple> zrangeByScoreWithScores(String key, String min, String max);

    Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min);

    Set<Tuple> zrangeByScoreWithScores(String key, String min, String max, int offset, int count);

    Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min, int offset, int count);

    Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min, int offset, int count);

    Long zremrangeByRank(String key, long start, long stop);

    Long zremrangeByScore(String key, double min, double max);

    Long zremrangeByScore(String key, String min, String max);

    Long zlexcount(String key, String min, String max);

    Set<String> zrangeByLex(String key, String min, String max);

    Set<String> zrangeByLex(String key, String min, String max, int offset, int count);

    Set<String> zrevrangeByLex(String key, String max, String min);

    Set<String> zrevrangeByLex(String key, String max, String min, int offset, int count);

    Long zremrangeByLex(String key, String min, String max);


    String echo(String string);


    Long bitcount(String key);

    Long bitcount(String key, long start, long end);

    Long bitpos(String key, boolean value);

    Long bitpos(String key, boolean value, BitPosParams params);

    Long pfadd(String key, String... elements);

    long pfcount(String key);

    // Geo Commands

    Long geoadd(String key, double longitude, double latitude, String member);

    Long geoadd(String key, Map<String, GeoCoordinate> memberCoordinateMap);

    Long geoadd(String key, GeoAddParams params, Map<String, GeoCoordinate> memberCoordinateMap);

    Double geodist(String key, String member1, String member2);

    Double geodist(String key, String member1, String member2, GeoUnit unit);

    List<String> geohash(String key, String... members);

    List<GeoCoordinate> geopos(String key, String... members);

    List<GeoRadiusResponse> georadius(String key, double longitude, double latitude, double radius,
                                      GeoUnit unit);

    List<GeoRadiusResponse> georadiusReadonly(String key, double longitude, double latitude,
                                              double radius, GeoUnit unit);

    List<GeoRadiusResponse> georadius(String key, double longitude, double latitude, double radius,
                                      GeoUnit unit, GeoRadiusParam param);

    List<GeoRadiusResponse> georadiusReadonly(String key, double longitude, double latitude,
                                              double radius, GeoUnit unit, GeoRadiusParam param);

    List<GeoRadiusResponse> georadiusByMember(String key, String member, double radius, GeoUnit unit);

    List<GeoRadiusResponse> georadiusByMemberReadonly(String key, String member, double radius, GeoUnit unit);

    List<GeoRadiusResponse> georadiusByMember(String key, String member, double radius, GeoUnit unit,
                                              GeoRadiusParam param);

    List<GeoRadiusResponse> georadiusByMemberReadonly(String key, String member, double radius,
                                                      GeoUnit unit, GeoRadiusParam param);

    /**
     * Executes BITFIELD Redis command
     *
     * @param key
     * @param arguments
     * @return
     */
    List<Long> bitfield(String key, String... arguments);

    List<Long> bitfieldReadonly(String key, String... arguments);

    /**
     * Used for HSTRLEN Redis command
     *
     * @param key
     * @param field
     * @return length of the value for key
     */
    Long hstrlen(String key, String field);

    /**
     * XADD key ID field string [field string ...]
     *
     * @param key
     * @param id
     * @param hash
     * @return the ID of the added entry
     */
    StreamEntryID xadd(String key, StreamEntryID id, Map<String, String> hash);

    /**
     * XADD key MAXLEN ~ LEN ID field string [field string ...]
     *
     * @param key
     * @param id
     * @param hash
     * @param maxLen
     * @param approximateLength
     * @return
     */
    StreamEntryID xadd(String key, StreamEntryID id, Map<String, String> hash, long maxLen, boolean approximateLength);

    /**
     * XADD key [NOMKSTREAM] [MAXLEN|MINID [=|~] threshold [LIMIT count]] *|ID field value [field value ...]
     *
     * @param key
     * @param hash
     * @param params
     * @return
     */
    StreamEntryID xadd(String key, Map<String, String> hash, XAddParams params);

    /**
     * XLEN key
     *
     * @param key
     * @return
     */
    Long xlen(String key);

    /**
     * XRANGE key start end
     *
     * @param key
     * @param start minimum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate minimum ID possible in the stream
     * @param end   maximum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate maximum ID possible in the stream
     * @return The entries with IDs matching the specified range.
     */
    List<StreamEntry> xrange(String key, StreamEntryID start, StreamEntryID end);

    /**
     * XRANGE key start end COUNT count
     *
     * @param key
     * @param start minimum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate minimum ID possible in the stream
     * @param end   maximum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate maximum ID possible in the stream
     * @param count maximum number of entries returned
     * @return The entries with IDs matching the specified range.
     */
    List<StreamEntry> xrange(String key, StreamEntryID start, StreamEntryID end, int count);

    /**
     * XREVRANGE key end start
     *
     * @param key
     * @param start minimum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate minimum ID possible in the stream
     * @param end   maximum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate maximum ID possible in the stream
     * @return the entries with IDs matching the specified range, from the higher ID to the lower ID matching.
     */
    List<StreamEntry> xrevrange(String key, StreamEntryID end, StreamEntryID start);

    /**
     * XREVRANGE key end start COUNT count
     *
     * @param key
     * @param start minimum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate minimum ID possible in the stream
     * @param end   maximum {@link StreamEntryID} for the retrieved range, passing <code>null</code> will indicate maximum ID possible in the stream
     * @param count The entries with IDs matching the specified range.
     * @return the entries with IDs matching the specified range, from the higher ID to the lower ID matching.
     */
    List<StreamEntry> xrevrange(String key, StreamEntryID end, StreamEntryID start, int count);

    /**
     * XACK key group ID [ID ...]
     *
     * @param key
     * @param group
     * @param ids
     * @return
     */
    long xack(String key, String group, StreamEntryID... ids);

    /**
     * XGROUP CREATE <key> <groupname> <id or $>
     *
     * @param key
     * @param groupname
     * @param id
     * @param makeStream
     * @return
     */
    String xgroupCreate(String key, String groupname, StreamEntryID id, boolean makeStream);

    /**
     * XGROUP SETID <key> <groupname> <id or $>
     *
     * @param key
     * @param groupname
     * @param id
     * @return
     */
    String xgroupSetID(String key, String groupname, StreamEntryID id);

    /**
     * XGROUP DESTROY <key> <groupname>
     *
     * @param key
     * @param groupname
     * @return
     */
    long xgroupDestroy(String key, String groupname);

    /**
     * XGROUP DELCONSUMER <key> <groupname> <consumername>
     *
     * @param key
     * @param groupname
     * @param consumername
     * @return
     */
    Long xgroupDelConsumer(String key, String groupname, String consumername);

    /**
     * XPENDING key group
     *
     * @param key
     * @param groupname
     * @return
     */
    StreamPendingSummary xpending(String key, String groupname);

    /**
     * XPENDING key group [start end count] [consumer]
     *
     * @param key
     * @param groupname
     * @param start
     * @param end
     * @param count
     * @param consumername
     * @return
     */
    List<StreamPendingEntry> xpending(String key, String groupname, StreamEntryID start,
                                      StreamEntryID end, int count, String consumername);

    /**
     * XPENDING key group [[IDLE min-idle-time] start end count [consumer]]
     *
     * @param key
     * @param groupname
     * @param params
     */
    List<StreamPendingEntry> xpending(String key, String groupname, XPendingParams params);

    /**
     * XDEL key ID [ID ...]
     *
     * @param key
     * @param ids
     * @return
     */
    long xdel(String key, StreamEntryID... ids);

    /**
     * XTRIM key MAXLEN [~] count
     *
     * @param key
     * @param maxLen
     * @param approximate
     * @return
     */
    long xtrim(String key, long maxLen, boolean approximate);

    /**
     * XTRIM key MAXLEN|MINID [=|~] threshold [LIMIT count]
     *
     * @param key
     * @param params
     * @return
     */
    long xtrim(String key, XTrimParams params);

    /**
     * XCLAIM <key> <group> <consumer> <min-idle-time> <ID-1> <ID-2>
     * [IDLE <milliseconds>] [TIME <mstime>] [RETRYCOUNT <count>]
     * [FORCE] [JUSTID]
     */
    List<StreamEntry> xclaim(String key, String group, String consumername, long minIdleTime,
                             long newIdleTime, int retries, boolean force, StreamEntryID... ids);

    /**
     * XCLAIM <key> <group> <consumer> <min-idle-time> <ID-1> ... <ID-N>
     * [IDLE <milliseconds>] [TIME <mstime>] [RETRYCOUNT <count>]
     * [FORCE]
     */
    List<StreamEntry> xclaim(String key, String group, String consumername, long minIdleTime,
                             XClaimParams params, StreamEntryID... ids);

    /**
     * XCLAIM <key> <group> <consumer> <min-idle-time> <ID-1> ... <ID-N>
     * [IDLE <milliseconds>] [TIME <mstime>] [RETRYCOUNT <count>]
     * [FORCE] JUSTID
     */
    List<StreamEntryID> xclaimJustId(String key, String group, String consumername, long minIdleTime,
                                     XClaimParams params, StreamEntryID... ids);

    /**
     * Introspection command used in order to retrieve different information about the stream
     *
     * @param key Stream name
     * @return {@link StreamInfo} that contains information about the stream
     */
    StreamInfo xinfoStream(String key);

    /**
     * Introspection command used in order to retrieve different information about groups in the stream
     *
     * @param key Stream name
     * @return List of {@link StreamGroupInfo} containing information about groups
     */
    List<StreamGroupInfo> xinfoGroup(String key);

    /**
     * Introspection command used in order to retrieve different information about consumers in the group
     *
     * @param key   Stream name
     * @param group Group name
     * @return List of {@link StreamConsumersInfo} containing information about consumers that belong
     * to the the group
     */
    List<StreamConsumersInfo> xinfoConsumers(String key, String group);




版权声明:本文为weixin_45149147原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。