目录
目标
列举redis中与key相关的指令,包括作用、使用时需要注意的地方等。对于某些基本用不到的指令仅一带而过。
DEL
DEL key [key ...]
对于单key
val为string,则O(1);
val为集合,则O(M),M:集合成员数量
对于多个key
val为string,O(N),N:key个数
val为集合,O(M1+M2+……),Mn:第n个集合的元素个数M
删除key和val,若key不存在则忽略。若需删除数据较多,会阻塞redis server处理其他请求。
返回真实删除的key的个数
UNLINK
UNLINK key [key ...]
O(N) N:参数key的数量,与key对应val的大小无关。
与DEL类似,删除key和val。但是UNLINK将异步删除内存空间数据,所以不会阻塞;但是DEL会阻塞。
EXISTS
EXISTS key [key ...]
O(1)
返回存在key的个数,如果key存在且参数重复列举,则返回结果也会重复计数
EXPIRE
EXPIRE key seconds
O(1)
对key设置过期时间,当key过期时将被删除。
设置成功返回1,key不存在返回0
timeout何时清除
- 仅对key的val进行删除、覆盖时,超时设置才会被清除,如del、set、getset、*strore。换句话说,仅对key的val内容进行修改而不是替换整个val,不会影响超时设置,例如INCR叠加val、LPUSH向list中push新val、HSET设置field对应的val。
- 使用PWRSIST将key转为持久化key,key的超时设置将被清除。
RENAME keyB keyA,keyA将继承keyB的所有设置,包括timeout。
EXPIRE、PEXPIRE使用负值,EXPIREAT、PEXPIREAT使用过去时间,则key将被删除。
刷新超时
对已经设置超时的key再次使用EXPIRE,对key重新设置超时。
刷新超时举例:nav session导航会话模式
针对'用户最近访问的页面'类似场景,可以考虑用户导航会话。例如会话中暂存用户最近浏览的商品,以便之后进行推荐。
redis提供的策略,每次用如下方式记录用户访问
MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC
因此若用户空闲60s,则key被删除。
不局限RPUSH,只要是更新val内容的命令都可以,如INCR
key的timeout信息是使用绝对UNIX时间戳记录的。若在两台机器间移动RDB文件,务必保证机器时间一致。
如何超时key
被动
当key被访问时,发现超时,则删除。
主动
如果key设置超时后不再被访问,则不会被删除,所以引出主动方式。
每秒执行10次如下行为
设置超时的key的set中随机取20个key
删除已超时的
如果超时比例超时25%,则再次重复上述步骤
在同步和AOF中如何控制超时
复制
slave不处理超时
key超时后,master会同步DEL指令
AOF
追加DEL指令
PEXPIRE
作用于EXPIRE相同,时间单位为毫秒
EXPIREAT
EXPIREAT key 秒timestamp
O(1)
作用同expire,差异在于参数为具体的UNIX时间戳
PEXPIREAT
作用于EXPIREAT相同,毫秒时间戳
PTLL key
key可存活时间,单位毫秒
O(1)
返回值
redis2.6以及之前版本,key不存在或key存在但没有超时设置,返回-1
redis2.8以及之后,key不存在返回-2,key存在但没有超时设置,返回-1
TLL key
同PTLL
KEYS pattern
O(N) N:redis db中key的数量
以数组形式返回与pattern匹配的所有key
虽然时间复杂度为O(N),但是耗时相对较低,如运行在笔记本的redis实例,40毫秒可扫描1百万key。
注意:正式环境不要使用keys,因为对于大db,该命令耗时长,严重影响性能。代码中不要使用keys,如果想查询key,请使用scan或sets。
pattern
h?llo matches hello, hallo and hxllo,1个任意字符
h*llo matches hllo and heeeello,0或多个任意字符
h[ae]llo matches hello and hallo, but not hillo,使用[]限定范围字符范围a或e,仅限一个字符
h[^e]llo matches hallo, hbllo, ... but not hello,使用[]限定范围字符范围为除e之外的任意字符,仅限一个字符
h[a-b]llo matches hallo and hbllo,使用[]限定范围字符范围为a至b的任意字符,仅限一个字符
SCAN
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
每次调用为O(1),遍历为O(N)
返回数组,第一个元素为游标,第二个元素为本次返回的元素数组
游标是迭代过程唯一表示状态的数据,仅存在client,在server没有迭代的任何状态。
SCAN SSCAN HSCAN ZSCAN 递增式迭代元素集合
- SCAN 针对当前所选db,迭代匹配的key
- SSCAN key 针对key对应set类型val,迭代其元素
- HSCAN key 针对key对应hash类型val,迭代field和val
- ZSCAN key 针对key对应sorted set类型val,迭代元素和score
每次调用只返回小部分元素,优点为不会像keys或smembers造成redis服务(长时间)阻塞,缺点为在遍历过程中,数据集合可能发生变化。
用法
scan是迭代器的一个游标,每次调用均返回一个新的游标,该游标用于下次调用。
游标设置为0表示开始迭代,游标返回0表示迭代结束。
保证
元素在[迭代开始,迭代结束]期间一直在集合中,则迭代器一定会返回
元素在[迭代开始,迭代结束]期间一直不在集合中,则迭代器一定不会返回
弊端
元素可能返回多次
在[迭代开始,迭代结束]期间进行元素的增加或删除,则迭代器有可能返回或不返回,取决于元素位置在游标前或后。
当前迭代返回游标为50,增加元素且元素位置小于50,则之后迭代不会出现该元素。
当前迭代返回游标为50,增加元素且元素位置大于50,则之后迭代会出现该元素。
当前迭代返回游标为50,删除位置小于50的元素,则该元素已被迭代。
当前迭代返回游标为50,删除位置大于50的元素,则该元素不会被迭代。
PERSIST key
O(1)
移除key的timeout配置
返回1,删除timeout成功;返回0,删除timeout失败或key没有timeout配置。
RANDOMKEY
返回一个随机key
SORT
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
O(N+M*log(M)) N:集合元素个数 M:返回元素个数 如果不排序则为O(N)
针对list、set、sorted set进行排序,将结果返回或另存为其他key
如果元素是数字或可以解释为浮点数,则可直接进行排序
sort key
默认asc,从小到大;可使用desc,从大到小。
如果无法解释为浮点数,将返回error
当元素包含string时,可使用字典排序
sort key alpha asc/desc
限制返回元素个数
limit offset count
不使用元素本身排序,而是使用权重
SORT key BY weight_*
TOUCH
TOUCH key [key ...]
O(N) N:参数key的个数
用于改变key的最近访问时间,如果key不存在则忽略。
返回真实进行touch的key的数量
TYPE key
O(1)
返回key对应val的类型的字符串表示,返回值包括string, list, set, zset, hash and stream
WAIT
WAIT numreplicas timeout
在timeout时间内,对当前连接进行同步,等待n个写操作的ack
返回收到ack的数量
RENAME
RENAME key newkey
O(1)
将key重命名为newkey
当key不存在时,返回error;当newkey存在时,则覆盖其原始val
注意:当newkey存在时,rename会引起一个隐含的del操作,如果newkey的原始数据很大,则del会造成一定时间的阻塞。
RENAMENX
RENAMENX key newkey
仅当newkey不存在时,将key重命名为newkey。
返回1,成功;返回0,newkey已经存在。
DUMP
DUMP key
O(N*M) N:对象个数 M:对象大小均值
返回被序列化的val,可以使用RESTORE存储到另一个key。若key不存在则返回null
RESTORE
RESTORE key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]
MIGRATE
MIGRATE remote-host remote-port key|"" destination-db timeout [COPY] [REPLACE] [KEYS key [key ...]]
在当前连接的redis db,将单个或多个key,迁移到另一个redis db中。
过程
- DUMP source redis序列化待迁移key val
- RESTORE source redis向目标redis db同步数据
- 目标redis针对RESTORE返回OK
- source redis db针对key执行DEL
期间error,导致的可能结果
- 两个redis均有key val
- source redis有key val
MOVE key db
将key val从redis当前db移动到另一个db
O(1)