redis入门系列(四)
常见面试问题
①reids如何从海量数据查询某些特定的key?
②redis如何批量删除key?
-
keys命令
今天我们来看看redis的keys常见相关命令,我们可以看下面的表格:
命令 | 描述 |
---|---|
DEL key | 该命令用于在 key 存在时删除 key。 |
EXISTS key | 检查给定 key 是否存在。 |
EXPIRE key seconds | 为给定 key 设置过期时间,以秒计。 |
EXPIREAT key timestamp | EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。 |
KEYS pattern | 查找所有符合给定模式( pattern)的 key 。 |
PTTL key | 以毫秒为单位返回 key 的剩余的过期时间。 |
TTL key | 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。 |
SCAN cursor [MATCH pattern] [COUNT count] | 迭代数据库中的数据库键。 |
通过keys命令可以从redis查询出符合条件的某个特定key,但是要注意的是实际生产应用中,这个命令是禁止的,KEYS命令的性能随着数据库数据的增多而越来越慢,KEYS命令会引起阻塞,连续的 KEYS命令足以让 Redis 阻塞,keys 的时间复杂度是O(N)。
在实际应用中,我们可以使用scan命令,这里我们详细演示一下scan命令,Redis从2.8版本开始支持scan命令,SCAN命令的基本用法如下:
1:复杂度虽然也是 O(n),通过游标分步进行不会阻塞线程;
2:有限制参数 COUNT ;
3:同 keys命令 一样提供模式匹配功能;
4:服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;
scan 命令提供三个参数,第一个是cursor,第二个是要匹配的正则,第三个是单次遍历的数量,第一个遍历是 cursor 值为0,然后将返回结果的第一个整数作为下一个遍历的游标,如果最后返回的到cursor的值为0就代表结束。
这里要稍微注意的是,游标是一个 Hash 值,是乱序的,一个遍历从 从 0 开始,到 0 结束,意味着重新返回起点;无需为每次迭代使用相同的COUNT值。只要在下一次遍历时是传入上一次的获得的游标即可,这样下一次遍历会使用上一次的 COUNT 值;scan 返回的结果可能会有重复数据,需要进行去重,在java里面可以把获取到的key放到set里面就可以了。
- 批量删除scan命令
redis-cli --scan --pattern “key前缀*” | xargs -L 1000 redis-cli del
因为KEYS命令的时间复杂度为O(n),而SCAN命令会将遍历操作分解成x次,然后每次去执行,从而时间复杂度为O(1)。也解决使用keys命令遍历大量数据而导致Redis服务器阻塞的情况。
重要的事情再说一遍,一定一定要切记生产环境禁止使用keys命令,很可能会导致程序雪崩。