首页 > 代码库 > Redis学习笔记之五:redis keys命令 (24个)

Redis学习笔记之五:redis keys命令 (24个)

Redis 版本:3.2.100

 

Redis 命令

Redis 命令用于在 redis 服务上执行操作。

要在 redis 服务上执行命令需要一个 redis 客户端。

一.客户端连接服务器

  基本语法: redis-cli [-h host -p port -a password] 

  不带参数,则默认连接本地,带上三个参数,则连接远程服务器。

  举例: 如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass 的 redis 服务上。

     redis-cli -h 127.0.0.1 -p 6379 -a "mypass" 

     然后可以 执行 PING 命令,该命令用于检测 redis 服务是否启动,成功返回 pong .

二.redis 键(key)

redis键命令用于管理redis的键。

语法:command key_name

举例: set myName justin   设置

    get myName    获取

    del myName    删除

Redis keys 命令   以下为redis键相关的命令

1. del   

  用于删除已存在的key,不存在的key会被忽略,返回被删除key的数量

  语法: del key_name

  版本:>=1.0.0

  返回:被删除key的数量

2. dump 

  序列化给定 key ,并返回被序列化的值,使用 RESTORE 命令可以将这个值反序列化为 Redis 键。

  序列化生成的值有以下几个特点:
    它带有 64 位的校验和,用于检测错误,RESTORE 在进行反序列化之前会先检查校验和。
    值的编码格式和 RDB 文件保持一致。
    RDB 版本会被编码在序列化值当中,如果因为 Redis 的版本不同造成 RDB 格式不兼容,那么 Redis 会拒绝对这个值进行反序列化操作。
    序列化的值不包括任何生存时间信息。

  语法:dump key_name

  版本:>=2.6.0

  返回:如果key不存在,则返回 nil , 否则返回序列化之后的值。

3. exists 

  用于检测给定的key是否存在

  语法:exists key_name

  版本:>=1.0.0

  返回:若key存在返回1,否则返回0。

  注意:从redis 3.0.3 开始,exists命令可以指定多个key而不是单个key,此时它的返回值为存在的key的总数。

       对于单个key返回1或0就只是一种特殊情况了,所以exists命令向后兼容。

     另外,如果相同的key在参数中多次出现,则会多次计数。所以,如果somekey存在,那么 exists somekey somekey 将返回 2 。

4. expire

  用于设置key的过期时间,以秒计,key过期后不再可用,将被自动删除。

  语法:expire key_name time_in_seconds

  版本:>=1.0.0

  返回:设置成功返回1。当key不存在或者不能为key设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间),返回0.

5. expireat

  用于以unix 时间戳(unix timestamp)格式设置key的过期时间。key过期后将不再可用,自动删除。

  语法:expireat key_name time_in_unix_timestamp

  版本:>=1.2.0

  返回:设置成功返回1。当key不存在或者不能为key设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间),返回0.

6. pexpire

  用于以设置key的过期时间,以毫秒计,key过期后将不再可用,自动删除 。(与expire类似,除了过期时间以毫秒计)

  语法:pexpire key_name  time_in_milliseconds

  版本 :>=2.6.0

  返回 :设置成功返回1,当key不存在或者不能为key设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间),返回0.  

7. pexpireat

  用于以unix时间戳(unix timestamp)以毫秒计设置key的过期 时间,key过期将不再 可用,自动删除。(与expireat类似,除了时间以毫秒计)

  语法:pexpireat key_name  time_in_milliseconds_in_unix_timestamp

  版本 :>=2.6.0

  返回 :设置成功返回1,当key不存在或者不能为key设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间),返回0. 

8. keys

  用于查找所有符合给定模式 pattern(正则表达式)的key。pattern中使用星号*模糊匹配或者直接使用*查找所有key

  语法:keys pattern

  版本:>=1.0.0

  返回:符合给定模式的key列表(Array)。

9. move

  用于将当前数据库的key移动到给定的数据库db当中

  语法:move key_name destination_database

  版本:>=1.0.0

  返回:移动成功返回1,失败则返回0.

  注意:当且仅当 key在当前数据库存在,而在给定的数据库db中不存在时,才能移动成功,否则均失败。

10. persist

  用于移除给定key的过期时间,使得key永不过期(持久化)。

  语法:persist key_name 

  版本:>=2.2.0

  返回:当过期时间移除成功时,返回1,如果key不存在或者key没有设置过期时间,返回0.

11. ttl

  用于以秒为单位返回key的剩余过期时间。

  语法:ttl key_name

  版本:>1.0.0

  返回:当key不存在时,返回-2;当key存在但没有设置剩余生存时间,返回-1;否则,以秒为单位返回key的剩余生存时间。

  注意:在 redis 2.8 以前,当key不存在,或者key存在但没有设置剩余生存时间时,命令都返回-1.

12. pttl

  用于以毫秒为单位返回key的剩余过期时间。(与ttl类似,除了时间单位不一样)

  语法;pttl key_name

  版本:>=2.6.0

  返回:当key不存在时,返回-2;当key存在但没有设置剩余生存时间,返回-1;否则,以秒为单位返回key的剩余生存时间。

  注意:在 redis 2.8 以前,当key不存在,或者key存在但没有设置剩余生存时间时,命令都返回-1. 

13. randomkey

  用于从当前数据库中随机返回一个key。(redis 默认使用数据库 0)

  语法:randomkey

  版本:>=1.0.0

  返回:当数据库为空时,返回 nil ,否则返回一个随机的key。

14. rename

  用于修改key的名称

  语法:rename old_key_name new_key_name

  版本:>=1.0.0

  返回:改名成功,提示OK;失败则返回一个错误。

     当old_key_name不存在时,返回一个错误;

     当new_key_name已经存在时,new_key_name的值将被覆盖,此时会执行隐士的 del 操作,因此如果删除的key包含非常大的值,

     即使rename 命令是一个常时操作,也可能导致高延迟。  

  注意:在redis 3.2.0 以前,当old_key_name和new_key_name相同时,返回一个错误。

15. renamenx

  用于当new_key_name不存在时,修改key的名称。

  语法:renamenx old_key_name new_key_name

  版本:>=1.0.0

  返回:修改成功,返回1;如果new_key_name已存在,返回0;如果old_key_name不存在,返回一个错误。

  注意:在redis 3.2.0 以前,当old_key_name和new_key_name相同时,返回一个错误。

16. type

  用于返回key所存储的值的数据类型。

  语法:type key_name

  版本:>=1.0.0

  返回:返回key的数据类型:none(key不存在)、string(字符串)、list(列表)、set(集合)、zset(有序集)、hash(哈希)。

17. migrate

MIGRATE host port key|"" destination-db timeout [COPY] [REPLACE] [KEYS key [key ...]]

将 key 原子性地从当前实例传送到目标实例的指定数据库上,一旦传送成功, key 保证会出现在目标实例上,而当前实例上的 key 会被删除。

这个命令是一个原子操作,它在执行的时候会阻塞进行迁移的两个实例,直到以下任意结果发生:迁移成功,迁移失败,等待超时。

命令的内部实现是这样的:它在当前实例对给定 key 执行 DUMP 命令 ,将它序列化,然后传送到目标实例,目标实例再使用 RESTORE 对数据进行反序列化,并将反序列化所得的数据添加到数据库中;当前实例就像目标实例的客户端那样,只要看到 RESTORE 命令返回 OK ,它就会调用 DEL 删除自己数据库上的 key 。

timeout 参数以毫秒为格式,指定当前实例和目标实例进行沟通的最大间隔时间。这说明操作并不一定要在 timeout 毫秒内完成,只是说数据传送的时间不能超过这个 timeout 数。

MIGRATE 命令需要在给定的时间规定内完成 IO 操作。如果在传送数据时发生 IO 错误,或者达到了超时时间,那么命令会停止执行,并返回一个特殊的错误: IOERR 。

当 IOERR 出现时,有以下两种可能:

key 可能存在于两个实例
key 可能只存在于当前实例
唯一不可能发生的情况就是丢失 key ,因此,如果一个客户端执行 MIGRATE 命令,并且不幸遇上 IOERR 错误,那么这个客户端唯一要做的就是检查自己数据库上的 key 是否已经被正确地删除。

如果有其他错误发生,那么 MIGRATE 保证 key 只会出现在当前实例中。(当然,目标实例的给定数据库上可能有和 key 同名的键,不过这和 MIGRATE 命令没有关系)。

可选项:

COPY :不移除源实例上的 key 。
REPLACE :替换目标实例上已存在的 key 。
可用版本:
2.6.0及以上

返回值:
迁移成功时返回 OK ,否则返回相应的错误。
示例
先启动两个 Redis 实例,一个使用默认的 6379 端口,一个使用 7777 端口。

$ ./redis-server &
[1] 3557

$ ./redis-server –port 7777 &
[2] 3560


然后用客户端连上 6379 端口的实例,设置一个键,然后将它迁移到 7777 端口的实例上:

$ ./redis-cli

redis 127.0.0.1:6379> flushdb
OK

redis 127.0.0.1:6379> SET greeting “Hello from 6379 instance”
OK

redis 127.0.0.1:6379> MIGRATE 127.0.0.1 7777 greeting 0 1000
OK

redis 127.0.0.1:6379> EXISTS greeting # 迁移成功后 key 被删除
(integer) 0
使用另一个客户端,查看 7777 端口上的实例:

$ ./redis-cli -p 7777

redis 127.0.0.1:7777> GET greeting
“Hello from 6379 instance”

 

18. object

 OBJECT 命令可以在内部调试(debugging)给出keys的内部对象,它用于检查或者了解你的keys是否用到了特殊编码 的数据类型来存储空间z。 当redis作为缓存使用的时候,你的应用也可能用到这些由OBJECT命令提供的信息来决定应用层的key的驱逐策略(eviction policies)

OBJECT 支持多个子命令:

  • OBJECT REFCOUNT 该命令主要用于调试(debugging),它能够返回指定key所对应value被引用的次数.
  • OBJECT ENCODING 该命令返回指定key对应value所使用的内部表示(representation)(译者注:也可以理解为数据的压缩方式).
  • OBJECT IDLETIME 该命令返回指定key对应的value自被存储之后空闲的时间,以秒为单位(没有读写操作的请求) ,这个值返回以10秒为单位的秒级别时间,这一点可能在以后的实现中改善

对象可以用多种方式编码:

  • 字符串可以被编码为 raw (常规字符串) 或者int (用字符串表示64位无符号整数这种编码方式是为了节省空间).
  • 列表类型可以被编码为ziplist 或者 linkedlist. ziplist 是为了节省较小的列表空间而设计一种特殊编码方式.
  • 集合被编码为 intset 或者 hashtable. intset 是为了存储数字的较小集合而设计的一种特殊编码方式.
  • 哈希表可以被编码为 zipmap 或者hashtable. zipmap 是专为了较小的哈希表而设计的一种特殊编码方式
  • 有序集合被编码为ziplist 或者 skiplist 格式. ziplist可以表示较小的有序集合, skiplist 表示任意大小多的有序集合.

一旦你做了一个操作让redis无法再使用那些节省空间的编码方式,它将自动将那些特殊的编码类型转换为普通的编码类型.

返回值

不同的子命令会对应不同的返回值.

  • refcount 和 idletime 返回整数.
  • encoding 返回编码类型.

如果你尝试检查的参数缺失,将会返回为空

例子

redis> lpush mylist "Hello World"
(integer) 4
redis> object refcount mylist
(integer) 1
redis> object encoding mylist
"ziplist"
redis> object idletime mylist
(integer) 10

接下来的例子你可以看到redis一旦不能够实用节省空间的编码类型时编码方式的改变.

redis> set foo 1000
OK
redis> object encoding foo
"int"
redis> append foo bar
(integer) 7
redis> get foo
"1000bar"
redis> object encoding foo
"raw"
 

 19. restore

反序列化给定的序列化值,并将它和给定的 key 关联。

参数 ttl 以毫秒为单位为 key 设置生存时间;如果 ttl 为 0 ,那么不设置生存时间。

RESTORE 在执行反序列化之前会先对序列化值的 RDB 版本和数据校验和进行检查,如果 RDB 版本不相同或者数据不完整的话,那么 RESTORE 会拒绝进行反序列化,并返回一个错误。

返回值

如果反序列化成功那么返回 OK ,否则返回一个错误。

例子

redis> DEL mykey
0
redis> RESTORE mykey 0 "\n\x17\x17\x00\x00\x00\x12\x00\x00\x00\x03\x00                        x00\xc0\x01\x00\x04\xc0\x02\x00\x04\xc0\x03\x00                        xff\x04\x00u#<\xc0;.\xe9\xdd"
OK
redis> TYPE mykey
list
redis> LRANGE mykey 0 -1
1) "1"
2) "2"
3) "3"
   

 20.  scan

语法:scan cursor [match pattern] [count count]

版本: >=2.8.0

SCAN 命令及其相关的 SSCAN, HSCAN 和 ZSCAN 命令都用于增量迭代一个集合元素。

  • SCAN 命令用于迭代当前数据库中的key集合。 scan cursor [match pattern] [count count]
  • SSCAN 命令用于迭代SET集合中的元素。   sscan key cursor [match pattern] [count count]
  • HSCAN 命令用于迭代Hash类型中的键值对。  hscan key cursor [match pattern] [count count]
  • ZSCAN 命令用于迭代SortSet集合中的元素和元素对应的分值  zscan key cursor [match pattern] [count count]

以上列出的四个命令都支持增量式迭代,它们每次执行都只会返回少量元素,所以这些命令可以用于生产环境,而不会出现像 KEYS 或者 SMEMBERS 命令带来的可能会阻塞服务器的问题。

不过,SMEMBERS 命令可以返回集合键当前包含的所有元素, 但是对于SCAN这类增量式迭代命令来说,有可能在增量迭代过程中,集合元素被修改,对返回值无法提供完全准确的保证。

因为 SCAN, SSCAN, HSCAN 和 ZSCAN 四个命令的工作方式都非常相似, 所以这个文档会一并介绍这四个命令,需要注意的是SSCAN, HSCAN ,ZSCAN命令的第一个参数总是一个key; SCAN 命令则不需要在第一个参数提供任何key,因为它迭代的是当前数据库中的所有key。

SCAN命令的基本用法

SCAN命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程

当SCAN命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。

以下是一个 SCAN 命令的迭代过程示例 :

redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

在上面这个例子中, 第一次迭代使用 0 作为游标, 表示开始一次新的迭代。第二次迭代使用的是第一次迭代时返回的游标 17 ,作为新的迭代参数 。

显而易见,SCAN命令的返回值 是一个包含两个元素的数组, 第一个数组元素是用于进行下一次迭代的新游标, 而第二个数组元素则是一个数组, 这个数组中包含了所有被迭代的元素。

在第二次调用 SCAN 命令时, 命令返回了游标 0 , 这表示迭代已经结束, 整个数据集已经被完整遍历过了。

full iteration :以 0 作为游标开始一次新的迭代, 一直调用 SCAN 命令, 直到命令返回游标 0 , 我们称这个过程为一次完整遍历。

Scan命令的保证

SCAN命令以及其他增量式迭代命令, 在进行完整遍历的情况下可以为用户带来以下保证 :

  • 从完整遍历开始直到完整遍历结束期间, 一直存在于数据集内的所有元素都会被完整遍历返回; 这意味着, 如果有一个元素, 它从遍历开始直到遍历结束期间都存在于被遍历的数据集当中, 那么 SCAN 命令总会在某次迭代中将这个元素返回给用户。
  • 同样,如果一个元素在开始遍历之前被移出集合,并且在遍历开始直到遍历结束期间都没有再加入,那么在遍历返回的元素集中就不会出现该元素。

然而因为增量式命令仅仅使用游标来记录迭代状态, 所以这些命令带有以下缺点:

  • 同一个元素可能会被返回多次。 处理重复元素的工作交由应用程序负责, 比如说, 可以考虑将迭代返回的元素仅仅用于可以安全地重复执行多次的操作上。
  • 如果一个元素是在迭代过程中被添加到数据集的, 又或者是在迭代过程中从数据集中被删除的, 那么这个元素可能会被返回, 也可能不会。

SCAN命令每次执行返回的元素数量

SCAN增量式迭代命令并不保证每次执行都返回某个给定数量的元素,甚至可能会返回零个元素, 但只要命令返回的游标不是 0 , 应用程序就不应该将迭代视作结束。

不过命令返回的元素数量总是符合一定规则的, 对于一个大数据集来说, 增量式迭代命令每次最多可能会返回数十个元素;而对于一个足够小的数据集来说, 如果这个数据集的底层表示为编码数据结构(小的sets, hashes and sorted sets), 那么增量迭代命令将在一次调用中返回数据集中的所有元素。

如果需要的话,用户可以通过增量式迭代命令提供的COUNT选项来指定每次迭代返回元素的最大值。

COUNT选项

对于增量式迭代命令不保证每次迭代所返回的元素数量,我们可以使用COUNT选项, 对命令的行为进行一定程度上的调整。COUNT 选项的作用就是让用户告知迭代命令, 在每次迭代中应该从数据集里返回多少元素。使用COUNT 选项对于对增量式迭代命令相当于一种提示, 大多数情况下这种提示都比较有效的控制了返回值的数量。

  • COUNT 参数的默认值为 10 。
  • 数据集比较大时,如果没有使用MATCH 选项, 那么命令返回的元素数量通常和 COUNT 选项指定的一样, 或者比 COUNT 选项指定的数量稍多一些。
  • 在迭代一个编码为整数集合(intset,一个只由整数值构成的小集合)、 或者编码为压缩列表(ziplist,由不同值构成的一个小哈希或者一个小有序集合)时, 增量式迭代命令通常会无视 COUNT 选项指定的值, 在第一次迭代就将数据集包含的所有元素都返回给用户。

注意: **并非每次迭代都要使用相同的 COUNT 值 **,用户可以在每次迭代中按自己的需要随意改变 COUNT 值, 只要记得将上次迭代返回的游标用到下次迭代里面就可以了。

MATCH 选项

类似于KEYS 命令,增量式迭代命令通过给定 MATCH 参数的方式实现了通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素。

以下是一个使用 MATCH 选项进行迭代的示例:

redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood
(integer) 6
redis 127.0.0.1:6379> sscan myset 0 match f*
1) "0"
2) 1) "foo"
   2) "feelsgood"
   3) "foobar"
redis 127.0.0.1:6379>

MATCH功能对元素的模式匹配工作是在命令从数据集中取出元素后和向客户端返回元素前的这段时间内进行的, 所以如果被迭代的数据集中只有少量元素和模式相匹配, 那么迭代命令或许会在多次执行中都不返回任何元素。

以下是这种情况的一个例子:

redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"
redis 127.0.0.1:6379>

可以看出,以上的大部分迭代都不返回任何元素。在最后一次迭代, 我们通过将 COUNT 选项的参数设置为 1000 , 强制命令为本次迭代扫描更多元素, 从而使得命令返回的元素也变多了。

并发执行多个迭代

在同一时间, 可以有任意多个客户端对同一数据集进行迭代, 客户端每次执行迭代都需要传入一个游标, 并在迭代执行之后获得一个新的游标, 而这个游标就包含了迭代的所有状态, 因此, 服务器无须为迭代记录任何状态。

中止迭代

因为迭代的所有状态都保存在游标里面, 而服务器无须为迭代保存任何状态, 所以客户端可以在中途停止一个迭代, 而无须对服务器进行任何通知。即使有任意数量的迭代在中途停止, 也不会产生任何问题。

使用错误的游标

使用SCAN 命令传入间断的(broken)、负数、超出范围或者其他非正常的游标来执行增量式迭代并不会造成服务器崩溃, 但可能会让命令产生未定义的行为。未定义行为指的是, 增量式命令对返回值所做的保证可能会不再为真。 只有两种游标是合法的:

  • 在开始一个新的迭代时, 游标必须为 0 。
  • 增量式迭代命令在执行之后返回的, 用于延续迭代过程的游标。

迭代能终止的前提

增量式迭代命令所使用的算法只保证在数据集的大小有界的情况下, 迭代才会停止, 换句话说, 如果被迭代数据集的大小不断地增长的话, 增量式迭代命令可能永远也无法完成一次完整迭代。

从直觉上可以看出, 当一个数据集不断地变大时, 想要访问这个数据集中的所有元素就需要做越来越多的工作, 能否结束一个迭代取决于用户执行迭代的速度是否比数据集增长的速度更快。

返回值

SCAN, SSCAN, HSCAN 和 ZSCAN 命令都返回一个包含两个元素的 multi-bulk 回复: 回复的第一个元素是字符串表示的无符号 64 位整数(游标), 回复的第二个元素是另一个 multi-bulk 回复, 包含了本次被迭代的元素。

  • SCAN 命令返回的每个元素都是一个key。
  • SSCAN 命令返回的每个元素都是一个集合成员。
  • HSCAN 命令返回的每个元素都是一个键值对,一个键值对由一个键和一个值组成。
  • ZSCAN命令返回的每个元素都是一个有序集合元素,一个有序集合元素由一个成员(member)和一个分值(score)组成。

另外的例子

迭代hash中的键值对:

redis 127.0.0.1:6379> hmset hash name Jack age 33
OK
redis 127.0.0.1:6379> hscan hash 0
1) "0"
2) 1) "name"
   2) "Jack"
   3) "age"
   4) "33"

 

21.  sort

版本:>=1.0.0

语法:SORT key [BY pattern] [LIMIT offset count] [GET pattern] [ASC|DESC] [ALPHA] destination 

返回或存储key的list、 set 或sorted set 中的元素。默认是按照数值类型排序的,并且按照两个元素的双精度浮点数类型值进行比较。下面是SORT的最简形式:

SORT mylist

假设mylist是一个数字列表,这条命令将返回一个元素从小到大排序的相同大小列表。如果想从大到小排序,可以使用 !DESC 修饰符。

SORT mylist DESC

当 mylist 包含的是字符串值并且需要按照字典顺序排序,可以使用 ALPHA 修饰符:

SORT mylist ALPHA

假设正确地设置了环境变量 !LC_COLLATE ,Redis可以感知UTF-8编码。

返回元素的数量可以通过 LIMIT 修饰符限制。此修饰符有一个 offset 参数,指定了跳过的元素数量;还带有一个 count 参数,指定了从 offset 开始返回的元素数量。下面的例子将会返回排序后的列表 mylist 从第0个元素(offset 是从0开始的)开始的10个元素:

SORT mylist LIMIT 0 10

几乎所有的修饰符可以一起使用。下述例子将返回按字典顺序降序排序后的前5个元素:

SORT mylist LIMIT 0 5 ALPHA DESC

通过外部key排序

有时我们需要使用外部的key作为权重来排序,而不是使用列表、集合或有序集合中实际的元素值。假设列表 mylist包含元素1、 2 和 3,分别代表了存储在object_1object_2 和 object_3中的对象的唯一ID。当这些对象关联到存储在weight_1、 weight_2 和 weight_3 中的权重后, SORT 命令就能使用这些权重按照下述语句来对 mylist 排序:

SORT mylist BY weight_*

BY 选项带有一个模式(此例中的 weight_* ),用于生成用于排序的 Key 。这些key的名称指向首次与列表(本例中的1、 2 和 3)中元素的实际值出现 *

跳过排序的元素

BY 选项可以是一个并不存在的key,这会导致 SORT 命令跳过排序操作。这在我们获取未经排序的外部key(参考下文的 GET 选项)时非常有用。

SORT mylist BY nosort

获取外部key

前面的例子仅仅是返回排序后的ID。在某些情况下,获取实际的对象而不是他们的ID更加重要(object_1object_2 和 object_3)。获取存储在一个列表、集合或者有序集合中的key可以使用以下命令:

SORT mylist BY weight_* GET object_*

GET 选项可多次使用,以便获取每一个原始列表、集合或有序集合中元素的key。

还可以通过使用特殊 # 模式获取 GET 元素本身:

SORT mylist BY weight_* GET object_* GET #

保存排序操作的结果

默认的,SORT 命令返回排序后的元素给客户端。使用 STORE 选项,可以将结果存储于一个特定的列表中,以代替返回到客户端。

SORT mylist BY weight_* STORE resultkey

SORT ... STORE的一种有趣应用模式,是联合 EXPIRE 超时命令返回key,以便在应用中可以缓存SORT操作的返回结果。 其他客户端将会使用已缓存的列表,代替每个请求的 SORT 调用。当key即将过期时,一个更新版本的缓存将会通过 SORT ... STORE 再次创建。

注意,为了正确实现这种模式,很重要的一点是防止多个客户端同时重建缓存。 此时需要使用一些锁(具体的使用 SETNX)。

在 BY 和 GET中使用hash

可以在hash的属性上按下述语法使用 BY 和 GET 选项:

SORT mylist BY weight_*->fieldname GET object_*->fieldname

字符串 -> 用于区分key名称和哈希属性的名称。key被替换为上面所记录的,结果key中存储的hash用于获取特定hash的属性。

返回值

array-reply: 返回排序后的元素列表

 

22. touch

  用于更改key的最后访问时间,如果key不存在则忽略。

  语法:touch key [key...]

  版本:>=3.2.1

  返回:被touch的key的数量

23. wait

语法:wait numslaves timeout

版本:>=3.0.0

此命令将阻止当前客户端,直到所有以前的写入命令成功传输并至少由指定数量的从站确认。如果达到了以毫秒为单位指定的超时,即使尚未达到指定数量的从站,命令也将返回。

在达到指定数量的从站的情况下,或达到超时时,该命令将始终返回确认在WAIT命令之前发送的写入命令的从站数。

几句话:

  1. 当WAIT返回时,在当前连接的上下文中发送的所有以前的写入命令都保证由WAIT返回的从站数接收。
  2. 如果命令是作为MULTI事务的一部分发送的,则该命令不会阻塞,而只是返回ASAP确认先前写入命令的从站数。
  3. 超时为0意味着永远阻止。
  4. 由于WAIT返回在故障和成功的情况下达到的从站数,客户端应检查返回值是否等于或大于所要求的复制级别。

一致性和等待

请注意,WAIT不会使Redis成为强烈一致的存储:同步复制是复制状态机的一部分,但它不是唯一需要的。然而,在Sentinel或Redis Cluster故障切换的情况下,WAIT可以改善现实世界的数据安全性。

具体来说,如果一个给定的写入被传送到一个或多个从站,则更有可能(但不能保证)如果主站出现故障,我们将能够在故障切换期间提升接收到写入的从站:Sentinel和Redis集群将尽力尝试在一系列可用的从站中推广最佳的从站。

然而,这只是一个尽力而为的努力,所以有可能仍然失去同时复制到多个从站的写入。

实施细节

由于引入与从站的部分重新同步(PSYNC功能)Redis从站异步地将其主机与已在复制流中处理的偏移量进行ping。这用于多种方式:

  1. 检测超时奴隶。
  2. 断开后执行部分重新同步。
  3. 实施WAIT。

在实施WAIT的具体情况下,当给定的客户端的上下文中执行给定的写入命令时,Redis会为每个客户端记住生成的复制流的复制偏移量。当调用WAIT时,Redis会检查指定数量的从站是否已经确认此偏移量或更大的从站。

返回值

整数回复:该命令返回在当前连接的上下文中执行的所有写入所达到的从站数。

例子

> SET foo bar
OK
> WAIT 1 0
(integer) 1
> WAIT 2 1000
(integer) 1

在下面的例子中,WAIT的第一次调用不会使用超时,并要求写入到1个从站。它成功返回。在第二次尝试中,我们放置一个超时,并要求复制到两个从站。由于存在单个从站可用,在等待一秒后解除阻塞并返回1,所达到的从站数。

 

 

24. unlink

版本:>=4.0.0

语法:unlink key [key...]

  此命令非常类似于DEL:它删除指定的键。就像DEL一样,如果键不存在,则忽略它。然而,该命令在不同的线程中执行实际的内存回收,所以它不阻塞,而DEL是。这是命令名称来自哪里:命令只是将键从键空间中取消链接。实际的删除将在以后异步发生。

 

返回值

Integer reply:取消关联的键数。

 

Redis学习笔记之五:redis keys命令 (24个)