Redis Key

本文将介绍 Redis 中的 Key,它是 Redis 中数据的唯一标识。

一、说明

Redis 是一种 Key-Value 数据库,所有数据均以键值对的形式存储,Key 担负着标识数据和索引数据的作用。

二、底层数据结构

Redis 是一种 Key-Value 数据库,所有的数据均以键值对的形式存储。为了实现 Key 到 Value 的快速访问,Redis 在底层使用了哈希表。

  • 哈希表中有数个哈希桶,每个哈希桶对应一个哈希值

  • 每增加一个元素,Redis 会实例化一个保存 Key 和 Value 的指针的 entry,将其放入 Key 的哈希值对应的哈希桶中

  • 为了避免哈希冲突(两个不同的 Key 计算出相同的哈希值),Redis 使用了链式哈希,同一个链表中的多个元素会串联形成一个链表

  • 为了避免 “严重的” 哈希冲突,Redis 使用了 rehash 操作,

    具体做法为:

    • 为另一个哈希表分配比 “原哈希表” 更大的空间,将其作为 “新哈希表”
    • 如果用户操作 Key-Value,正常处理请求,”顺便” 将 Key-Value 迁移至 “新哈希表” 中
    • 如果用户没有操作 Key-Value,Redis 后台会 “定时渐进” 迁移 Key-Value
    • 当 “原哈希表” 中没有 Key 时,释放空间

三、常用命令

1. 命令 - 查找

1
2
3
4
5
// 返回符合匹配模式的所有键
KEYS 匹配模式

// 基于游标对键进行迭代
SCAN 游标 MATCH 模式 COUNT 遍历个数

KEYS 模式 可以从数据库中获取符合模式的所有键,但由于它的算法是粗暴的遍历并且无法对遍历起点、遍历总数做限制,因此该命令可能会造成 Redis 服务卡顿。

SCAN 是 Redis 针对这一问题提供的解决方案。

  • 如果希望开启一轮新的迭代,应该将游标设为 0
  • 如果希望继续上一轮迭代,应该将游标设为上一轮迭代中返回的游标
  • 每一轮迭代结束以后,将会返回两份结果,其中:
    • 第一份是游标,用于在下次迭代时填入,以便基于上次迭代继续迭代
    • 第二份是迭代结果
  • COUNT 遍历个数 限制的是遍历个数而非结果个数,如果返回的结果为空,不代表遍历结束,只是该次迭代中并没有找到符合的键值对
  • 如果迭代返回的游标为 0,代表迭代结束

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2) 1) "key:611"
2) "key:711"
3) "key:118"
4) "key:117"
5) "key:311"
6) "key:112"
7) "key:111"
8) "key:110"
9) "key:113"
10) "key:211"
11) "key:411"
12) "key:115"
13) "key:116"
14) "key:114"
15) "key:119"
16) "key:811"
17) "key:511"
18) "key:11"
redis 127.0.0.1:6379>

2. 命令 - 过期时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 设置键值对的过期时间
EXPIRE key名 秒数
EXPIREAT key名 时间戳
PEXPIRE key名 毫秒数
PEXPIREAT key名 以毫秒为单位的时间戳

// 移除键值对的过期时间
PERSIST key名

// 返回键值对的过期时间,以秒为单位
PTTL key名

// 返回键值对的过期时间,以毫秒为单位
TTL key名

3. 命令 - 更名

1
2
3
4
5
// 修改key名
RENAME key名 新key名

// 当且仅当新key名不存在时,修改key名
RENAMENX key名 新key名

4. 命令 - 删除

1
2
3
4
5
6
7
8
// 删除键值对
DEL key名

// 清空当前数据库下所有键值对
flushdb

// 清空整个Redis中所有键值对 [慎用]
flushall

5. 命令 - 其它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 序列化键值对(把值转化为可传输的字节序列)
DUMP key名

// 检查键值对是否存在
EXISTS key名

// 将键值对移动到其它数据库中
MOVE key名 数据库索引

// 随机获取一个Key
RANDOMKEY

// 查看值的类型
type key名

参考