文章目录
  1. 03_Redis基本键的管理
  2. 1. 简介
  3. 2. 单个键的命令
    1. 2.1 键重命名
    2. 2.2 随机返回一个键
    3. 2.3 键过期
    4. 2.4 迁移键
      1. 2.4.1 move
      2. 2.4.2 dump+restore
      3. 2.4.3 migrate
  4. 3. 遍历键
    1. 3.1 全量遍历
    2. 3.2 渐进式遍历
  5. 4. 数据库管理
    1. 4.1 切换数据库
    2. 4.2 flushdb/flushall

[TOC]

03_Redis基本键的管理

1. 简介

针对键的管理,如typedelobjectexistsexpire等,下面介绍几个重要的。

2. 单个键的命令

2.1 键重命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ rename key newkey

> 示例
127.0.0.1:6379> set oldKey heihei
OK
127.0.0.1:6379> rename oldKey newKey
OK
127.0.0.1:6379> get oldKey
(nil)
127.0.0.1:6379> get newKey
"heihei"

# 如果newKey已经存在,将被覆盖
# 所以Redis提供如下命令防止被覆盖。
$ renamenx key newkey

注意

  • 由于rename执行期间会del旧的key,所以如果对应值比较大的时候,注意redis阻塞的可能性。
  • 在oldKey和newKey相同时,Redis3.2会返回OK,之前的版本会提示key相同的错误。

2.2 随机返回一个键

1
2
3
4
5
6
7
8
9
$ randomkey

> 示例
127.0.0.1:6379> dbsize
(integer) 10
127.0.0.1:6379> randomkey
"user:rank"
127.0.0.1:6379> randomkey
"key2"

2.3 键过期

1
2
3
4
5
6
7
8
9
10
# 多少秒后
$ expire key seconds
# 多少毫秒后
$ pexpire key milliseconds


# 在某个"秒级时间戳"后
$ expireat key timestamp
# 在某个"毫秒级时间戳"后d
$ pexpireat key milliseconds-timestamp
1
2
3
4
# 查询键剩余过期时间(秒)
$ ttl
# 查询键剩余过期时间(毫秒)
$ pttl
  • 清除键的过期时间
1
$ persist key

注意:对于字符串类型的key,执行set命令的同时会去掉过期时间,这个问题需要注意下。

  • Redis不支持二级数据结构(哈希,列表等)内部元素的过期功能。

2.4 迁移键

Redis在发展过程中提供了movedump+restoremigrate三种迁移方式,但是使用场景不太一样。

2.4.1 move

1
$ move key db

move命令用于redis内部进行数据迁移,因为redis内部有多个数据库(后面会说),彼此在数据上是相互隔离的。move就是将指定的键从源数据库移动到目标数据库

注:不建议在生产中使用多数据库功能。

2.4.2 dump+restore

dump+restore可以实现在不同redis实例之间迁移数据,功能分为两步,如下:

  • dump命令将键序列化,格式采用RDB的格式。
1
$ dump key
  • 在目标Redis上,restore命令将上述的序列化的值进行复原。
1
2
3
$ restore key ttl serialized-value [REPLACE]

# ttl表示过期时间,0表示没有过期时间

注意点如下:

  • 整个迁移过程非原子性,是通过客户端分步完成的。
  • 迁移过程中开启了两个客户端连接,所以dump结果不是在源Redis目标Redis之间传输的。
1
2
3
4
5
6
7
8
9
10
11
12
13
> 示例

# redis1
127.0.0.1:6379> set a hello
OK
127.0.0.1:6379> dump a
"\x00\x05hello\b\x00\xda_3\xc9\xcc-\xaa2"

# redis2
127.0.0.1:6379> restore a 0 "\x00\x05hello\b\x00\xda_3\xc9\xcc-\xaa2"
OK
127.0.0.1:6379> get a
"hello"

2.4.3 migrate

migrate实际是将dump、restore、del三个命令进行组合,从而简化操作,且具有原子性。Redis3.0.6后支持多键迁移,有效提高了迁移效率。migrate在后续水平扩展中起到重要作用。

1
2
3
4
5
6
7
8
$  migrate host port key| destination-db timeout [COPY] [REPLACE] [keys key[key...]]

# host和port表示目标redis
# key|"":表示迁移key,可以多个。多个的话此处填`空字符串`
# destination-db:目标redis的数据库
# timeout:迁移的超时时间,毫秒。
# COPY:表示只是拷贝操作
# REPLACE:是否不管目标redis中key的存在性

示例

1
2
3
4
5
# 一个key
$ migrate 127.0.0.1 6380 k1 0 1000

# 多个可以
$ migrate 127.0.0.1 6380 "" 0 5000 keys k1 k2 k3

3. 遍历键

Redis提供两种遍历键的方式:keysscan

3.1 全量遍历

1
2
3
$ keys pattern

# pattern:正则匹配

如当想删除某一批键的时候,还是有很大帮助的:

1
redis-cli keys video* | xargs redis-cli del

但是考虑到redis时单线程的架构,执行keys很有可能会造成redis阻塞,所以一般不建议在生产使用。如果要使用,可在如下情况中使用:

  • 在一个不对外提供服务的redis节点上执行,这样不会阻塞客户端的请求,但是会影响主从复制。
  • 如果确认键确实很少。
  • 使用scan命令,渐进式遍历。

3.2 渐进式遍历

1
2
3
4
5
6
$ scan cursor [MATCH pattern] [COUNT count]

# cursor:游标,第一次遍历从0开始。
每次遍历完会返回当前游标,直到游标值为0,表示遍历结束。
# MATCH pattern:符合的正则
# COUNT count:每次遍历键个数,默认是10

Redis2.8之后提供scan命令可以有效的解决keys带来的问题,所以要真正实现keys的功能,需要多次scan。

Redis存储键值对实际使用的是hashtable的数据结构,简化模型如下,所以每次scan的时间复杂度是O(1)。

除了scan,redis还提供面向哈希,集合,有序几个的扫描命令,解决hgetall,smembers,zrange可能产生的阻塞问题,命令分别是hscan、sscan、zscan,用法基本和scan类似:

1
2
3
$ hscan key cursor [MATCH pattern] [COUNT count]
$ sscan key cursor [MATCH pattern] [COUNT count]
$ zscan key cursor [MATCH pattern] [COUNT count]

注意: scan虽然可以有效解决keys所可能产生阻塞的问题,但也并非完美,如果在scan的过程中有键的变化(增加,删除,修改等),那么遍历的时候可能不能保证遍历出所有的键:如新增的键可能没有遍历到,遍历出重复的键等等。

4. 数据库管理

Redis数据库提供了几个面向数据库的操作,分别是dbsize、select、flushdb/flushall命令。

4.1 切换数据库

1
$ select index

redis默认配置中有16个数据库(配置是databases 16),从0开始。库与库之间没有任何关联,可以存在相同的键。

1
2
3
4
5
6
7
8
9
> 示例
127.0.0.1:6379> set a hello
OK
127.0.0.1:6379> get a
"hello"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get a
(nil)

问题?

1
可以将正式数据库放在0库中,测试数据放在1库中吗?

Redis3.0已经逐渐弱化了这个功能,例如Redis分布式实现Redis Cluster只允许使用0号库。只不过为了兼容旧版本,没有完全废弃掉这个功能。不建议使用的原因如下几点:

  • Redis是单线程的
  • 多数据库的使用方式,会让调试和运维不同业务数据库变得很困难
  • 部分Redis客户端就不支持这种方式,即使支持,在开发过程也很容易造成混乱。

建议如果需要使用多数据库的功能,完全可以在一台机器上部署多个redis实例,用端口来区分。

4.2 flushdb/flushall

两个命令用去清楚数据库。flushdb清除当前库,flushall清除所有库。

1
2
$ flushdb
$ flushall

这两个命令可以非常方便清理数据,但是也带来两个问题:

  • 一旦执行,后果不堪设想。后面会将使用rename-command进行规避,或者误操作后快速恢复。
  • 当数据库键数据很多的时候,存在阻塞redis的可能性。

切记谨慎使用!!!!

文章目录
  1. 03_Redis基本键的管理
  2. 1. 简介
  3. 2. 单个键的命令
    1. 2.1 键重命名
    2. 2.2 随机返回一个键
    3. 2.3 键过期
    4. 2.4 迁移键
      1. 2.4.1 move
      2. 2.4.2 dump+restore
      3. 2.4.3 migrate
  4. 3. 遍历键
    1. 3.1 全量遍历
    2. 3.2 渐进式遍历
  5. 4. 数据库管理
    1. 4.1 切换数据库
    2. 4.2 flushdb/flushall