1 单个键管理
-
查看所有键
keys *
-
键总数
dbsize
dbsize命令在计算键总数时不会遍历所有键,而是直接获取Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1)。而keys命令会遍历所有键,所以它的时间复杂度是O(n),当Redis保存了大量键时,线上环境禁止使用。
-
检查键是否存在
exists key
-
删除键
del key [key ...]
-
键过期
expire key seconds
ttl命令会返回键的剩余过期时间,它有3种返回值:
- 大于等于0的整数:键剩余的过期时间。
- 1:键没设置过期时间。
- 2:键不存在
-
键的数据结构类型
type key
-
键重命名
rename key newkey
如果在rename之前,键java已经存在,那么它的值也将被覆盖。为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey不存在时候才被覆盖。
在使用重命名命令时,有两点需要注意:由于重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞Redis的可能性,这点不要忽视;如果rename和renamenx中的key和newkey如果是相同的,在Redis3.2和之前版本返回结果略有不同。 -
键过期
除了expire、ttl命令以外,Redis还提供了expireat、pexpire、pexpireat、pttl、persist等一系列命令,下面分别进行说
明:- expire key seconds:键在seconds秒后过期。
- expireat key timestamp:键在秒级时间戳timestamp后过期。
- pexpire key milliseconds:键在milliseconds毫秒后过期。
- pexpireat key milliseconds-timestamp键在毫秒级时间戳timestamp后过期。
- ttl命令和pttl都可以查询键的剩余过期时间,但是pttl精度更高可以达到毫秒级别。
在使用Redis相关过期命令时,需要注意以下几点。
1)如果expire key的键不存在,返回结果为0。
2)如果过期时间为负值,键会立即被删除,犹如使用del命令一样。
3)persist命令可以将键的过期时间清除。
4)对于字符串类型键,执行set命令会去掉过期时间,这个问题很容易在开发中被忽视。
5)Redis不支持二级数据结构(例如哈希、列表)内部元素的过期功能,例如不能对列表类型的一个元素做过期时间设置。
6)setex命令作为set+expire的组合,不但是原子执行,同时减少了一次网络通讯的时间。
2 迁移键
迁移键功能非常重要,因为有时候我们只想把部分数据由一个Redis迁移到另一个Redis(例如从生产环境迁移到测试环境),Redis发展历程中提供了move、dump+restore、migrate三组迁移键的方法,它们的实现方式以及使用的场景不太相同,下面分别介绍。
2.1 move命令
move命令用于在Redis内部进行数据迁移,Redis内部可以有多个数据库,由于多个数据库功能后面会进行介绍,这里只需要知道Redis内部可以有多个数据库,彼此在数据上是相互隔离的,move key db就是把指定的键从源数据库移动到目标数据库中,但笔者认为多数据库功能不建议在生产环境使用,所以这个命令读者知道即可。
2.2 dump+restore命令
dump key
restore key ttl value
dump+restore可以实现在不同的Redis实例之间进行数据迁移的功能,整个迁移的过程分为两步:
1)在源Redis上,dump命令会将键值序列化,格式采用的是RDB格式。
2)在目标Redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间。
有关dump+restore有两点需要注意:第一,整个迁移过程并非原子性的,而是通过客户端分步完成的。第二,迁移过程是开启了两个客户端连接,所以dump的结果不是在源Redis和目标Redis之间进行传输。
2.3 migrate命令
migrate命令也是用于在Redis实例间进行数据迁移的,实际上migrate命令就是将dump、restore、del三个命令进行组合,从而简化了操作流程。migrate命令具有原子性,而且从Redis3.0.6版本以后已经支持迁移多个键的功能,有效地提高了迁移效率,migrate在10.4节水平扩容中起到重要作用。
整个过程如图所示,实现过程和dump+restore基本类似,但是有3点不太相同:第一,整个过程是原子执行的,不需要在多个Redis实例上开启客户端的,只需要在源Redis上执行migrate命令即可。第二,migrate命令的数据传输直接在源Redis和目标Redis上完成的。第三,目标Redis完成restore后会发送OK给源Redis,源Redis接收后会根据migrate对应的选项来决定是否在源Redis上删除对应的键。
下面对migrate的参数进行逐个说明:
- host:目标Redis的IP地址。
- port:目标Redis的端口。
- key|"":在Redis3.0.6版本之前,migrate只支持迁移一个键,所以此处是要迁移的键,但Redis3.0.6版本之后支持迁移多个键,如果当前需要迁移多个键,此处为空字符串""。
- destination-db:目标Redis的数据库索引,例如要迁移到0号数据库,这里就写0。
- timeout:迁移的超时时间(单位为毫秒)。
- [copy]:如果添加此选项,迁移后并不删除源键。
- [replace]:如果添加此选项,migrate不管目标Redis是否存在该键都会正常迁移进行数据覆盖。
- [keys key[key...]]:迁移多个键,例如要迁移key1、key2、key3,此处填
写“keys key1 key2 key3”。
3 遍历键
3.1 全量遍历键:keys
keys pattern
该命令会造成redis阻塞,慎用。
3.2 渐进遍历键:scan
每次执行scan,可以想象成只扫描一个字典中的一部分键,直到将字典中的所有键遍历完毕。scan的使用方法如下:
scan cursor [match pattern] [count number]
- cursor是必需参数,实际上cursor是一个游标,第一次遍历从0开始,每
次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。 - match pattern是可选参数,它的作用的是做模式的匹配,这点和keys的
模式匹配很像。 - count number是可选参数,它的作用是表明每次要遍历的键个数,默认
值是10,此参数可以适当增大。
除了scan以外,Redis提供了面向哈希类型、集合类型、有序集合的扫描遍历命令,解决诸如hgetall、smembers、zrange可能产生的阻塞问题,对应的命令分别是hscan、sscan、zscan,它们的用法和scan基本类似。
渐进式遍历可以有效的解决keys命令可能产生的阻塞问题,但是scan并非完美无瑕,如果在scan的过程中如果有键的变化(增加、删除、修改),那么遍历效果可能会碰到如下问题:新增的键可能没有遍历到,遍历出了重复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键,这些是我们在开发时需要考虑的。