Redis 键管理

键(Key)是Redis中数据的基本单元,本课学习键的管理操作。

键的基本操作

设置键值

REDIS
# 设置字符串
SET user:1 "Alice"

# 设置哈希
HSET user:2 name "Bob" age 30

# 设置列表
LPUSH articles "article1" "article2"

# 设置集合
SADD tags:article1 "redis" "database"

# 设置有序集合
ZADD leaderboard 100 "player1"

获取键值

REDIS
# 获取字符串
GET user:1

# 获取哈希
HGETALL user:2

# 获取列表
LRANGE articles 0 -1

# 获取集合
SMEMBERS tags:article1

# 获取有序集合
ZRANGE leaderboard 0 -1 WITHSCORES

删除键

REDIS
# 删除单个键
DEL user:1
(integer) 1  # 返回删除的键数量

# 删除多个键
DEL user:2 user:3
(integer) 2

# 删除不存在的键
DEL notexist
(integer) 0

检查键是否存在

REDIS
SET mykey "hello"

EXISTS mykey
(integer) 1  # 存在

EXISTS notexist
(integer) 0  # 不存在

# 检查多个键(返回存在的键数量)
EXISTS mykey mykey2 mykey3
(integer) 1  # 只有mykey存在

查看键的类型

REDIS
SET mystring "hello"
TYPE mystring          # string

HSET myhash field "value"
TYPE myhash            # hash

LPUSH mylist "a"
TYPE mylist            # list

SADD myset "a"
TYPE myset             # set

ZADD myzset 1 "a"
TYPE myzset            # zset

TYPE notexist          # none

键的命名规范

良好的键命名让数据管理更清晰。

推荐格式

业务:对象:ID[:属性]

示例

REDIS
# 用户信息
user:1                  # 用户1的基本信息
user:1:profile          # 用户1的详细资料
user:1:settings         # 用户1的设置

# 文章
article:123             # 文章123的内容
article:123:comments    # 文章123的评论列表
article:123:views       # 文章123的浏览数

# 购物车
cart:user:1             # 用户1的购物车

# 会话
session:token:abc123    # 会话token

# 缓存
cache:api:user:1        # API缓存:用户1的信息
cache:page:home         # 页面缓存:首页

# 锁
lock:order:123          # 订单123的锁
▶ 试一试

命名建议

建议 示例 说明
使用冒号分隔 user:1:profile 清晰的层次结构
使用有意义的前缀 cache:, session:, lock: 区分不同用途
保持一致性 user:1, user:2 统一格式
避免过长 u:1:p 太短不清晰,太长占内存
避免特殊字符 user-1 使用连字符或冒号,避免空格等
💡 键的长度: 键名会占用内存,建议在清晰和简洁间平衡。常用键可以短一些。

过期时间

Redis可以为键设置过期时间,到期自动删除。

设置过期时间

REDIS
SET session:token123 "user_data"

# 方式1:EXPIRE(秒)
EXPIRE session:token123 3600    # 1小时后过期

# 方式2:EXPIREAT(时间戳,秒)
EXPIREAT session:token123 1700000000

# 方式3:PEXPIRE(毫秒)
PEXPIRE session:token123 3600000

# 方式4:PEXPIREAT(时间戳,毫秒)
PEXPIREAT session:token123 1700000000000

# 方式5:SET时设置过期时间
SET cache:key "value" EX 60     # 60秒后过期
SET cache:key "value" PX 60000  # 60000毫秒后过期

查看过期时间

REDIS
# TTL:返回剩余生存时间(秒)
TTL session:token123
(integer) 3500  # 还剩3500秒

# PTTL:返回剩余生存时间(毫秒)
PTTL session:token123
(integer) 3500000

# 特殊返回值
TTL noexpire
(integer) -1    # 键存在但没有设置过期时间

TTL notexist
(integer) -2    # 键不存在

取消过期时间

REDIS
# PERSIST:移除过期时间,键变为永久
PERSIST session:token123
(integer) 1  # 成功移除

PERSIST notexist
(integer) 0  # 键不存在

过期时间应用场景

场景 过期时间 示例
会话 30分钟 SET session:token "data" EX 1800
验证码 5分钟 SET code:phone:138xxxx "123456" EX 300
缓存 1小时 SET cache:api:user:1 "data" EX 3600
限流 1分钟 SET limit:user:1 "10" EX 60
分布式锁 10秒 SET lock:resource "locked" NX EX 10
⚠️ 注意: 过期时间精度为毫秒,但实际删除可能有延迟(惰性删除 + 定期删除)。

键的重命名

RENAME:重命名键

REDIS
SET oldkey "value"

RENAME oldkey newkey
OK

GET newkey
"value"

GET oldkey
(nil)  # oldkey已不存在
⚠️ 注意: 如果newkey已存在,RENAME会覆盖它!

RENAMENX:仅当新键不存在时重命名

REDIS
SET key1 "value1"
SET key2 "value2"

RENAMENX key1 key2
(integer) 0  # key2已存在,重命名失败

GET key1
"value1"  # key1仍然存在

GET key2
"value2"  # key2未被覆盖

键的迁移

MOVE:移动键到其他数据库

REDIS
# 在DB 0
SET mykey "value"

# 移动到DB 1
MOVE mykey 1
(integer) 1  # 成功

# 切换到DB 1
SELECT 1
OK

GET mykey
"value"
⚠️ 注意: MOVE在集群模式下不可用。

DUMP + RESTORE:序列化和反序列化

REDIS
# 序列化键
SET mykey "hello"
DUMP mykey
# 返回序列化后的二进制数据

# 反序列化到新键
RESTORE newkey 0 "\x00\x05hello\t\x00\xf5\xbd\xba\xab\xdc\xa6\xdec"
OK

MIGRATE:迁移键到其他Redis实例

REDIS
# 将mykey迁移到192.168.1.100:6379
MIGRATE 192.168.1.100 6379 mykey 0 5000
OK

# 参数说明
# MIGRATE host port key destination-db timeout

键的排序

SORT命令可以对列表、集合、有序集合进行排序。

基本排序

REDIS
# 列表排序
LPUSH mylist 3 1 4 1 5 9 2 6
SORT mylist
# 1) "1"
# 2) "1"
# 3) "2"
# 4) "3"
# 5) "4"
# 6) "5"
# 7) "6"
# 8) "9"

# 降序排序
SORT mylist DESC
# 1) "9"
# 2) "6"
# 3) "5"
# ...

# 集合排序
SADD myset 5 2 8 1 9
SORT myset
# 1) "1"
# 2) "2"
# 3) "5"
# 4) "8"
# 5) "9"

按外部值排序

REDIS
# 学生ID列表
LPUSH students "student1" "student2" "student3"

# 学生分数
SET student1:score 85
SET student2:score 92
SET student3:score 78

# 按分数排序
SORT students BY *:score
# 1) "student3"  # 78分
# 2) "student1"  # 85分
# 3) "student2"  # 92分

# 获取外部值
SORT students BY *:score GET *:score
# 1) "78"
# 2) "85"
# 3) "92"

保存排序结果

REDIS
# 排序并保存到新键
SORT mylist DESC STORE sorted_list
(integer) 8

LRANGE sorted_list 0 -1
# 1) "9"
# 2) "6"
# ...

查找键

KEYS:查找匹配的键

REDIS
# 设置一些测试数据
SET user:1 "Alice"
SET user:2 "Bob"
SET user:3 "Charlie"
SET product:1 "iPhone"
SET product:2 "iPad"

# 查找所有键
KEYS *
# 1) "user:1"
# 2) "user:2"
# 3) "user:3"
# 4) "product:1"
# 5) "product:2"

# 查找匹配模式的键
KEYS user:*
# 1) "user:1"
# 2) "user:2"
# 3) "user:3"

KEYS *:1
# 1) "user:1"
# 2) "product:1"

KEYS user:[1-2]
# 1) "user:1"
# 2) "user:2"
⚠️ 警告: KEYS会扫描整个数据库,数据量大时非常慢,生产环境禁用

SCAN:迭代查找键(推荐)

SCAN是KEYS的安全替代,使用游标迭代。

REDIS
# 开始迭代,返回游标和键列表
SCAN 0
1) "5"          # 下一次使用的游标
2) 1) "user:1"
   2) "user:2"

# 继续迭代
SCAN 5
1) "0"          # 游标为0表示迭代结束
2) 1) "user:3"
   2) "product:1"

# 匹配模式
SCAN 0 MATCH user:*
1) "3"
2) 1) "user:1"
   2) "user:2"

# 指定每次返回的数量
SCAN 0 COUNT 100

SCAN家族命令

REDIS
# 迭代集合元素
SSCAN myset 0

# 迭代哈希字段
HSCAN myhash 0

# 迭代有序集合元素
ZSCAN myzset 0
💡 SCAN的优势: 不阻塞服务器,可以分批处理大量键。

键空间通知

Redis可以通知客户端键的变化事件。

配置键空间通知

REDIS
# 查看配置
CONFIG GET notify-keyspace-events
1) "notify-keyspace-events"
2) ""  # 默认关闭

# 开启所有通知
CONFIG SET notify-keyspace-events AKE
OK

通知类型

字符 通知类型 说明
K Keyspace 键空间通知(keyspace@
E Keyevent 键事件通知(keyevent@
A All 所有通知(等同于KE$glsh)
$ String 字符串命令
l List 列表命令
s Set 集合命令
h Hash 哈希命令
z Sorted Set 有序集合命令
x Expired 过期事件
e Evicted 驱逐事件(内存淘汰)

订阅通知

REDIS
# 订阅键空间通知(键的所有事件)
SUBSCRIBE __keyspace@0__:mykey

# 订阅键事件通知(某个事件的所有键)
SUBSCRIBE __keyevent@0__:set

示例:监听过期键

REDIS
# 配置:开启过期通知
CONFIG SET notify-keyspace-events Ex
OK

# 客户端1:订阅过期事件
SUBSCRIBE __keyevent@0__:expired

# 客户端2:设置带过期时间的键
SET temp "value" EX 5

# 客户端1收到消息:
# 1) "message"
# 2) "__keyevent@0__:expired"
# 3) "temp"  # 过期的键名
▶ 试一试

键的信息

OBJECT命令

REDIS
SET mykey "hello"

# 查看键的内部编码
OBJECT ENCODING mykey
"embstr"

# 查看引用计数
OBJECT REFCOUNT mykey
(integer) 1

# 查看空闲时间(秒)
OBJECT IDLETIME mykey
(integer) 10

MEMORY命令(Redis 4.0+)

REDIS
SET mykey "hello world hello world hello world"

# 查看键占用的内存
MEMORY USAGE mykey
(integer) 56  # 字节数

# 查看键的内存分配详情
MEMORY STATS

STRLEN:获取字符串长度

REDIS
SET mykey "Hello Redis"
STRLEN mykey
(integer) 11

批量操作

批量设置

REDIS
MSET key1 "value1" key2 "value2" key3 "value3"
OK

批量获取

REDIS
MGET key1 key2 key3
1) "value1"
2) "value2"
3) "value3"

# 包含不存在的键
MGET key1 key2 notexist key3
1) "value1"
2) "value2"
3) (nil)
4) "value3"

批量删除

REDIS
# 删除多个键
DEL key1 key2 key3
(integer) 3

❓ 常见问题

Q KEYS命令为什么慢?
A KEYS需要扫描整个数据库,时间复杂度O(N)。数据量大时会阻塞Redis。使用SCAN代替。
Q 过期键什么时候被删除?
A Redis使用惰性删除 + 定期删除。访问键时检查是否过期,后台定期随机检查部分键。
Q 如何批量删除匹配的键?
A

BASH
redis-cli --scan --pattern "prefix:*" | xargs redis-cli DEL

Q:键名最长能有多少字符? A:理论上无限制,但建议不要太长(占用内存)。

Q 如何统计某种类型的键数量?
A 没有直接命令,需要用SCAN遍历并用TYPE判断。

📖 小节

  • 键的基本操作:SET、GET、DEL、EXISTS、TYPE
  • 键命名规范:使用冒号分隔,有意义的前缀
  • 过期时间:EXPIRE、TTL、PERSIST
  • 键查找:KEYS(慎用)、SCAN(推荐)
  • 键迁移:MOVE、MIGRATE、DUMP/RESTORE
  • 键排序:SORT命令
  • 键空间通知:监听键的变化事件

📝 作业

  1. 命名练习: 为电商网站设计键命名规范(用户、商品、订单、购物车)
  2. 过期练习: 设置一个带过期时间的键,用TTL查看剩余时间,等待过期后验证
  3. SCAN练习: 创建100个键,使用SCAN遍历所有键
  4. 批量操作: 使用MSET批量设置10个键,使用MGET批量获取

下一课

下一课我们将学习 Redis 字符串(上),深入学习字符串的基本操作。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏