今天看啥  ›  专栏  ›  zxiaofan

玩转Redis-高级程序员必知的Key命令

zxiaofan  · 掘金  ·  · 2019-10-31 15:42
阅读 25

玩转Redis-高级程序员必知的Key命令

《玩转Redis》系列文章主要讲述Redis的基础及中高级应用,文章基于Redis5.0.4+。本文主要讲述Redis的Key相关命令,主要包含以下内容:

  • 【Key过期命令】:EXPIRE、PEXPIRE、EXPIREAT、PEXPIREAT、TTL、PTTL;
  • 【其他Key命令】:DEL、EXISTS、KEYS、DUMP、MIGRATE、MOVE、PERSIST、RANDOMKEY、RENAME、RENAMENX、RESTORE、TOUCH、TYPE、UNLINK、WAIT、OBJECT、SORT;

最新思维导图原图可于公众号【zxiaofan】留言获取。

Redis-最新思维导图原图

1、Key过期命令

1.1、Key过期命令简述

  • 设置过期时间为一段时间后(EXPIRE、PEXPIRE);
  • 设置过期时间为指定时间点(EXPIREAT、PEXPIREAT);
  • 查询过期时间(TTL、PTTL);
命令 功能 参数
EXPIRE 设置key的过期时间 key seconds
PEXPIRE 设置key的过期时间(毫秒) key milliseconds
EXPIREAT 设置key的过期时间为Unix时间戳(since 1970-01-01) key timestamp
PEXPIREAT 设置key的过期时间为Unix毫秒时间戳(since 1970-01-01) key milliseconds-timestamp
TTL 查询指定key的剩余生存时间 key
PTTL 查询指定key的剩余生存时间(毫秒) key

1.2、Key过期命令注意

  • Redis Version >= 2.6.0后,过期时间支持毫秒;
  • 过期时间支持设置一段时间后过期,也支持设置指定时间点过期;
  • 过期时间和电脑时钟相关,如果修改时钟为未来的时间,则key会立即过期;
  • key被rename后,新key过期时间沿用旧key的过期时间;
  • version<=2.4时,过期精度有0-1S误差,Redis2.6起(支持PSETEX),误差缩小到0-1MS;
  • 以上6个命令时间复杂度都是O(1);
  • 【TTL、PTTL】
    • Redis version <= 2.6:key不存在或存在且未设置过期时间返回-1;
    • Redis version >=Redis 2.8:key不存在返回-2;存在且未设置过期时间返回-1;

1.3、Key过期命令详细对比分析

Key过期命令详细对比分析


1.4、Key过期命令示例

127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> expire dyh 5
(integer) 1
127.0.0.1:6378> ttl dyh
(integer) 0
127.0.0.1:6378> expire dyh 5
(integer) 0
127.0.0.1:6378> ttl dyh
(integer) -2
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> expire dyh 50
(integer) 1
127.0.0.1:6378> ttl dyh
(integer) 47
127.0.0.1:6378> ttl dyh
(integer) 44
127.0.0.1:6378> pexpire dyh 3000
(integer) 1
127.0.0.1:6378> pttl dyh
(integer) -2
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> pexpire dyh 30000
(integer) 1
127.0.0.1:6378> pttl dyh
(integer) 26575
127.0.0.1:6378> pttl dyh
(integer) 25039
127.0.0.1:6378> pexpireat dyh 1572536378000
(integer) 0
127.0.0.1:6378> pttl dyh
(integer) -2
127.0.0.1:6378> set dyh @zxiaofan
OK
127.0.0.1:6378> pexpireat dyh 1572536378000
(integer) 1
127.0.0.1:6378> ttl dyh
(integer) 86359
127.0.0.1:6378> ttl dyh
(integer) 86357
复制代码

2、Redis其他Key命令

2.1、Redis其他Key命令简述

Redis的Key命令众多,支持各式各样的功能:删除、查找、迭代、判断、排序、移动等。

命令
功能 参数
DEL 删除指定key key [key ...]
EXISTS 判断指定key是否存在 key [key ...]
KEYS 查找指定Pattern的key pattern
DUMP 返回指定key序列化后的值 key
MIGRATE 原子迁移指定key到指定实例的指定DB host port key | "" destination-db timeout [COPY] [REPLACE] [KEYS key [key ...]]
MOVE 移动key到指定DB key db
PERSIST 移除key的超时时间 key
RANDOMKEY 返回一个随机key 无参
RENAME 重命名key key newkey
RENAMENX newkey不存在时重命名key key newkey
RESTORE 反序列化数据并存储到指定key key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]
SORT 返回list、set、sorted list排序后的数据 key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC
TOUCH (批量)修改key的最后访问时间 key [key ...]
TYPE 查询key类型 key
UNLINK 将keys从keyspace中删除,后续将异步删除value key [key ...]
WAIT 阻塞客户端直到超时或之前的写命令被同步到指定数量的副本 numreplicas timeout(毫秒)
OBJECT 调试key对应的value,常用于优化 subcommand [arguments [arguments ...]]

2.2、Redis其他Key命令注意

  • 【EXISTS】判断指定key是否存在

    • key存在返回1,不存在返回0;
    • 参数key有多个时,返回存在key的数量;
    • 3.0.3支持多参数;
  • 【KEYS】查找指定Pattern的key

    • 命令功能强大,但性能低下,建议使用SCAN替代;
    • 扫描1百万key需要40ms,大数据库下性能非常低下;
    • 仅用于调试或特殊操作,如键空间keyspace改变;
    • pattern通配符:
      • ?:任一字符; *:任意多个字符
      • [ae]:匹配a或e; [^e]:匹配非e
      • [a-b]:匹配a-b之间(含)的字符
      • \ : 字符转义
  • 【DUMP】返回指定key序列化后的值

    • 序列化的值不包含过期时间;
    • 序列化结果包含64位校验和用于检查错误;
    • 编码格式和RDB使用的格式一致;
    • 序列化值包含RDB版本信息,RDB格式不兼容的Redis版本,将拒绝处理序列化的值(拒绝反序列化操作);
  • 【MIGRATE】原子迁移指定key到指定实例的指定DB

    • 原理:源DB执行DUMP+DEL;目标DB执行RESTORE。源DB DUMP》目标DB RESTORE》目标DB返回“OK”则源DB DEL;
    • 迁移时会阻塞2个实例,直到成功或者超时(毫秒)、异常;
    • 迁移多key:key参数为“”,keys指定多key;
    • 超时(毫秒)不是指完成时间,而是指数据传输时间;
    • IOERR:
      • MIGRATE需要在指定时间完成IO操作,如果IO异常或超时将返回IOERR;
      • 可能产生2种场景:1、key存在于2个实例;2、key仅存在于源实例;
      • key丢失不肯能发生;
      • 如果遇到超时,应检查key是否存在于目标实例;
    • 如果返回异常(ERR开头),MIGRATE保证key仅存在于源实例(除非目标实例有同名key);
    • AUTH不能放在KEYS参数后;
  • 【MOVE】移动key倒指定DB

    • 当前DB不存在该key ==》 不移动;
    • 目标DB已有该key ==》 不移动;
  • 【RENAME】重命名key

    • key不存在:error(no such key);
    • <Redis3.2.0,若新旧key名字相同,会返回异常"ERR source and destination objects are the same";
    • 原理:先删除key再添加新key;
    • 如果原key是big key,会导致高延迟;
    • 注意和【RENAMENX】对比学习;
  • 【RESTORE】反序列化数据并存储到指定key

    • 序列化值可通过DUMP获得;
    • ttl为0表示不设置超时时间,否则设置超时时间(单位毫秒);
    • Redis》=5..0:支持ABSTTL修饰符,ttl表示Unix时间戳(毫秒);
    • IDLETIME seconds:设置反序列化的值的idletime,idletime可通过Object idletime key 查询;
    • FREQ frequency:设置反序列化的值的FREQ,FREQ 可通过Object freq key 查询;
    • key已存在:返回(error) BUSYKEY Target key name already exists.【或者使用REPLACE修饰符】;
    • RESTORE将检查RDB版本信息以及数据校验和,不匹配将返回异常;
    • RESTORE时间复杂度:O(1)+O(N*M)
      • O(1):创建新key;
      • N:组成value的数据结构的元素数量;
      • M:组成value的数据结构的元素的平均大小;
      • value是小字符串:O(1)+O(1*M)且M较小,故近似看成O(1);
      • value是sorted set:复杂度是O(NMlog(N)),因为插入数据到sorted sets是O(log(N));
  • 【SORT】返回list、set、sorted list排序后的数据

    • 默认按照数值由小到大排序,按照双精度浮点数进行比较;
    • 逆序:DESC;
    • 字母顺序排序:ALPHA,不使用此修饰符会异常;
    • 正确设置!LC_COLLATE环境变量后,可使用lIMIT修饰符;
    • 外部key排序:SORT user_id BY user_level_* DESC GET user_name_*;
      • *实际是user_id(列表)中value的占位符;
      • by对应key不存在时,将不会排序;
      • GET返回排序结果对应的值;
        • #将返回列表元素本身;
    • STORE resultkey:保存排序结果到指定key;
  • 【TYPE】查询key类型

    • 返回类型:string, list, set, zset, hash and stream;
  • 【UNLINK】将keys从keyspace中删除,后续将异步删除value

    • 和DEL类似。删除key:DEL、UNLINK都是同步;删除value:DEL是同步,UNLINK是异步;
    • 常用于删除大key(4.0.0之前可使用Pipeline批量删除value);
  • 【WAIT】阻塞客户端直到超时或之前的写命令被同步到指定数量的副本

    • WAIT命令返回时,当前连接所有之前的写命令一定会被指定数量的副本接收;
    • 如果WAIT命令是多事物的一部分,WAIT将不会阻塞而是尽快返回参数指定的副本数量;
    • timeout为0意味着一直阻塞;
    • 不论成功失败,WAIT都将返回处理的副本数量,客户端应检查返回结果是否大于等于预期;
    • 【一致性】
      • WAIT不保证強一致性;
      • 在哨兵Sentinel或Redis Cluster的故障转移中,可以提高数据安全性;
    • 【实现细节】
      • 基于PSYNC(Redis主从同步)特性,副本会带上已处理过的偏移量,可应用于多种场景:
      • 1、检测副本超时情况;2、连接断开后再同步;3、实现WAIT;
      • WAIT场景中:当客户端执行写命令后,Redis会记录副本的偏移量。执行WAIT时,Redis会检测副本是否已经完成该操作或者已经执行更新的操作;
  • 【OBJECT】调试key对应的value,常用于优化

    • refcount或idletime子命令:返回数字;
      • 返回指定key对应value被引用的次数;
      • 场景:整数共享对象池节省内存;
    • encoding子命令:返回value的底层结构;
      • 返回key对应的value的底层结构;
    • IDLETIME
      • 返回key被闲置(未写未读)的时间(秒);
      • 当Redis内存策略是LRU或noeviction时可用;
    • FREQ
      • 返回key的对数访问频率计数器;
      • 结合SCAN获取热key;
    • key不存在:返回nil;
    • OBJECT可以了解value的类型;
    • 根据调试信息设置key的回收策略;

2.3、Redis其他Key命令详细对比分析

  • DEL、UNLINK、EXISTS、KEYS、DUMP详细对比分析:

    Redis其他Key命令详细对比分析1

  • MIGRATE、MOVE、PERSIST、RENAME、RENAMENX详细对比分析:

    Redis其他Key命令详细对比分析2

  • RESTORE、RANDOMKEY、TOUCH、TYPE、WAIT详细对比分析:

    Redis其他Key命令详细对比分析3

  • OBJECT、SORT详细对比分析:

    Redis其他Key命令详细对比分析4


2.4、Redis其他Key命令示例

2.4.1、unlink、del、exists、keys示例

127.0.0.1:6378> set key1 dyh
OK
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> unlink key1
(integer) 1
127.0.0.1:6378> del key2
(integer) 1
127.0.0.1:6378> exists key1 key2
(integer) 0
127.0.0.1:6378> keys key*
1) "key3"
2) "keylist"
3) "key4"
4) "key"
127.0.0.1:6378> keys key?
1) "key3"
2) "key4"
127.0.0.1:6378> keys key[35]
1) "key3"
127.0.0.1:6378> keys key[^3]
1) "key4"
复制代码

2.4.2、dump示例

127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> get key2
"@zxiaofan"
127.0.0.1:6378> dump key2
"\x00\t@zxiaofan\t\x00\xe8\xd2c%\x02\xc7]="
复制代码

2.4.3、move示例

127.0.0.1:6378> set key1 hi
OK
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> select 1
OK
127.0.0.1:6378[1]> del key1
(integer) 0
127.0.0.1:6378[1]> set key2 @zxiaofan-db1
OK
127.0.0.1:6378[1]> select 0
OK
127.0.0.1:6378> move key1 1
(integer) 1
127.0.0.1:6378> move key2 1
(integer) 0
127.0.0.1:6378> get key1
(nil)
127.0.0.1:6378> get key2
"@zxiaofan"
127.0.0.1:6378> select 1
OK
127.0.0.1:6378[1]> get key2
"@zxiaofan-db1"
复制代码

2.4.4、rename、renamenx示例

127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> rename key2 key2019
OK
127.0.0.1:6378> rename key2 key2019
(error) ERR no such key
127.0.0.1:6378> set key1 hi
OK
127.0.0.1:6378> rename key2019 key1
OK
127.0.0.1:6378> get key1
"@zxiaofan"
127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> renamenx key2019 key1
(error) ERR no such key
127.0.0.1:6378> renamenx key2 key1
(integer) 0
127.0.0.1:6378> rename key2 key1
OK
复制代码

2.4.5、type示例

127.0.0.1:6378> set key2 @zxiaofan
OK
127.0.0.1:6378> type key2
string
127.0.0.1:6378> set key1 1
OK
127.0.0.1:6378> type key1
string
127.0.0.1:6378> lpush listkey csdn github zxiaofan.com
(integer) 6
127.0.0.1:6378> type listkey
list
127.0.0.1:6378> hmset hashkey name zxiaofan blog csdn
OK
127.0.0.1:6378> type hashkey
hash
复制代码

2.4.5、RANDOMKEY示例

127.0.0.1:6378> RANDOMKEY
"list3"
127.0.0.1:6378> RANDOMKEY
"num4"
127.0.0.1:6378> RANDOMKEY
"dyh"
127.0.0.1:6378> mget list3 num4 dyh
1) (nil)
2) "200"
3) "@zxiaofan"
127.0.0.1:6378> 
复制代码

3、总结

关于Redis的Key命令,你掌握了多少了呢?不清楚的赶紧往上翻翻。

  • 过期时间支持哪几种;
  • 如何查询指定key的过期时间;
  • 如何移除指定key的过期时间;
  • 如何判断Redis中是否存在某些key,若存在返回值是什么;
  • 功能强大的KEYS命令通配符支持哪些;
  • key可以重命名吗,重命名需要注意什么;
  • SORT排序支持哪几种数据类型,各数据类型默认排序规则是怎样的;
  • UNLINK和DEL的区别是什么;
  • OBJECT命令都有哪些子命令,如何应用于调试分析;

Redis的Key相关命令到此结束了吗?路漫漫其修远兮...

  • SCAN系列命令(SCAN / SSCAN / HSCAN /ZSCAN),如何高性能处理海量Redis数据;
  • SORT实战中如何排序;
  • Object实战中如何用于性能分析。

敬请关注后续《玩转Redis》系列文章。


祝君好运!
Life is all about choices!
将来的你一定会感激现在拼命的自己!
CSDN】【GitHub】【OSCHINA】【掘金】【微信公众号
欢迎订阅zxiaofan的微信公众号,扫码或直接搜索zxiaofan





原文地址:访问原文地址
快照地址: 访问文章快照