# 管理单元
Redis 的管理单元从上到下依次分为:
- database :数据库
- 一个 Redis 中默认创建了 16 个数据库,从 0 开始编号。
- key-value :键值对
- 每个数据库中可以存储很多键值对,类似于 Python 中的字典。
# database
- 命令:
select n # 切换到第 n 号数据库 move <key> n # 将当前数据库的一个 key 移动到第 n 号数据库 dbsize # 返回当前数据库的 key 总数 flushdb # 删除当前数据库的所有 key flushall # 删除所有数据库的所有 key
# key
- 命令:
keys <pattern> # 显示匹配 pattern 的所有 key(例如 keys *) exists <key>... # 判断 key 是否存在 del <key>... # 删除 key 。需要指定具体的 key 名,不能指定 pattern 。这属于同步操作,会阻塞当前终端 unlink <key>... # 删除 key 。这属于异步操作,不会阻塞当前终端 scan cursor [MATCH pattern] [COUNT count] [TYPE type] # 从游标 cursor 位置开始迭代一定数量的 key ,最多返回的数量为 count(默认为 10 ) rename <key> <newkey> # 重命名 key(如果 newkey 已存在,则覆盖它) renamenx <key> <newkey> # 重命名 key(如果 newkey 已存在,则不执行操作) type <key> # 返回 key 的数据类型 dump <key> # 返回 key 的序列化后的 value
- keys 的时间复杂度为 O(n) ,如果在上千万的 key 中进行查询,容易阻塞 Redis 几秒,因此要谨慎使用。
- 大部分命令执行之后会返回生效的 key 数,返回值为 0 则表示执行失败,返回值为 nil 则表示不存在该 key 。如下:
127.0.0.1:6379> exists key1 key2 (integer) 2 127.0.0.1:6379> get key1 "hello" 127.0.0.1:6379> del key1 (integer) 1 127.0.0.1:6379> get key1 (nil)
- 关于 scan 命令:
- 例:
127.0.0.1:6379> scan 0 MATCH key* 1) "1152" # 返回本次迭代后的游标位置 2) 1) "key:000000001311" # 返回 10 个 key 2) "key:000000000626" 3) "key:000000001973" 4) "key:000000000554" 5) "key:000000001630" 6) "key:000000000318" 7) "key:000000000761" 8) "key:000000000291" 9) "key:000000001039" 10) "key:000000001179"
- 使用本次迭代后的游标位置,作为下一次 scan 迭代的起始游标,就可以继续迭代剩下的 key 。但是多次迭代后返回的 key 可能有重复的,客户端需要自己去重。
- 如果某次迭代后返回的游标位置为 0 ,则说明已迭代完所有 key 。
- scan 每次迭代的时间复杂度为 O(1) ,不会阻塞 Redis 。不过迭代完所有 key 的时间复杂度依然为 O(n) 。
- 基于 scan 命令批量删除 key ,不会阻塞 Redis ,如下:
redis-cli scan 0 COUNT 1000 | xargs redis-cli del
login_redis='redis-cli -n 0' cursor=0 while [ 1 ] do echo `date`, dbsize=`$login_redis dbsize`, cursor=$cursor list=(`$login_redis scan $cursor COUNT 1000`) echo ${list[@]:1} | xargs -n 1 -d ' ' echo del | $login_redis > /dev/null cursor=${list[0]} if [ cursor == 0 ] then break fi done
- 实测发现,主从部署时,删 key 的速度为每秒 1000 个左右,即使每次删 1w 个 key 也是这么慢。
- 例:
# 过期时间
可以给 key 设置过期时间(time to live),过期之后会被 Redis 自动删除(不一定会立即删除)。
- 如果 key 的 ttl 为-1 ,则表示不会过期。
命令:
expire <key> <seconds> # 设置 key 在几秒后过期 pexpire <key> <milliseconds> # 设置 key 在几毫秒后过期 expireat <key> <timestamp> # 设置 key 在某个时间戳(单位为秒)之后过期 pexpireat <key> <milliseconds-timestamp> # 设置 key 在某个时间戳(单位为毫秒)之后过期 ttl <key> # 返回 key 剩下的过期时间(单位为秒) pttl <key> # 返回 key 剩下的过期时间(单位为毫秒) persist <key> # 取消 key 的过期时间