Redis六大常见命令详解:从set/get到过期策略的全方位解析
目录
1.前言
插播一条消息~
2.正文
2.1set和get
2.1.1set 命令
2.1.2get 命令
2.2六种全局命令
2.2.1keys
2.2.2exists
2.2.3del
2.2.4expire和pexpire
Redis 过期策略流程
2.2.5ttl
2.2.6type
3.小结
1.前言
在现代后端开发体系中,Redis 作为高性能的内存数据库中间件,凭借其亚毫秒级响应速度与丰富的数据结构支持,已成为解决高并发读写、缓存穿透防护、分布式锁实现等核心场景的关键技术组件。其在电商秒杀、实时排行榜、会话存储等业务场景中的广泛应用,凸显了掌握其命令体系对于后端工程师的必要性。
开发者在实践中常面临两类核心挑战:一是命令参数体系复杂导致的使用混淆,例如 SET
命令的 NX
/XX
选项与过期时间参数的组合逻辑;二是生产环境下的误操作风险,如 FLUSHALL
命令的无限制执行可能引发数据灾难性丢失。这些问题直接影响系统稳定性与开发效率,亟需系统化的知识梳理与实践指导。
本文将通过结构化学习路径,帮助读者实现从命令语法掌握到工程化实践落地的能力跃迁,系统性提升 Redis 技术栈的应用水平。
插播一条消息~
🔍十年经验淬炼 · 系统化AI学习平台推荐
系统化学习AI平台https://www.captainbed.cn/scy/
- 📚 完整知识体系:从数学基础 → 工业级项目(人脸识别/自动驾驶/GANs),内容由浅入深
- 💻 实战为王:每小节配套可运行代码案例(提供完整源码)
- 🎯 零基础友好:用生活案例讲解算法,无需担心数学/编程基础
🚀 特别适合
- 想系统补强AI知识的开发者
- 转型人工智能领域的从业者
- 需要项目经验的学生
2.正文
2.1set和get
set
和 get
是 Redis 中最基础的键值对操作命令,分别用于设置和获取键值对数据,是日常开发中使用频率最高的命令之一。
命令作用
set
命令负责向 Redis 中存储键值对,支持设置过期时间及条件性操作;get
命令则用于读取指定键对应的 value 值,是数据查询的基础操作。两者配合使用可实现简单的键值存储与读取功能。
语法解析与参数详解
2.1.1set 命令
基础语法:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
该命令通过可选参数扩展了基础功能,核心参数包括过期时间设置(EX
/PX
)和条件性设置(NX
/XX
),具体说明如下:
EX seconds
:以秒为单位设置键的过期时间,到期后键会自动删除。适用于需要缓存自动失效的场景,如临时会话数据存储。PX milliseconds
:以毫秒为单位设置过期时间,提供比EX
更高精度的时效控制,适合对过期时间敏感的高频操作场景。NX
:仅当键不存在时才执行设置操作,返回OK
;若键已存在则返回nil
。这一特性使其成为分布式锁实现的核心基础,可避免多个进程重复设置同一资源锁。XX
:仅当键已存在时才执行设置操作,常用于更新已有键值的场景,确保操作不会意外创建新键。
注意:
NX
和XX
为互斥参数,不可同时使用;EX
与PX
也不可同时指定,需根据精度需求选择其一。
返回值:
- 成功设置时返回
OK
; - 若
NX
/XX
条件不满足(如NX
时键已存在),返回nil
。
2.1.2get 命令
基础语法:
GET key
返回值:
- 若键存在,返回对应的 value(字符串类型);
- 若键不存在或已过期,返回
nil
。
示例验证
通过实际命令演示 set
和 get
的使用效果:
set 命令示例:
# 场景1:设置带过期时间的用户信息(3600秒后自动过期)
SET user:100 "zhangsan" EX 3600
# 返回:OK # 场景2:分布式锁场景(仅当锁键不存在时获取锁)
SET lock:order:1001 "locked" NX PX 5000
# 若 lock:order:1001 不存在,返回 OK;否则返回 nil # 场景3:更新已存在的购物车数据(仅当 cart:200 存在时执行)
SET cart:200 "book,pen" XX
# 若 cart:200 存在,返回 OK;否则返回 nil
get 命令示例:
# 获取存在的键值
GET user:100
# 返回:"zhangsan" # 获取不存在的键
GET none_exist_key
# 返回:nil # 获取已过期的键(假设 user:100 已过期)
GET user:100
# 返回:nil
参数总结表
为更清晰对比 set
命令参数的差异,以 下表格汇总各参数的含义与典型应用场景:
参数 | 含义 | 使用场景示例 |
---|---|---|
EX seconds | 设置过期时间(秒级精度) | 用户会话缓存(如 30 分钟过期) |
PX milliseconds | 设置过期时间(毫秒级精度) | 高频交易的临时锁(如 500ms 超时) |
NX | 仅键不存在时设置 | 分布式锁获取(避免重复加锁) |
XX | 仅键存在时设置 | 订单状态更新(确保订单已创建) |
2.2六种全局命令
2.2.1keys
keys
命令是 Redis 中用于查找符合指定模式键的核心命令,其通过支持多种通配符实现灵活的键匹配功能。该命令在日常开发与调试中较为常用,但在生产环境需谨慎使用以避免性能风险。
通配符类型及示例:
通配符 | 含义 | 示例 | 说明 |
---|---|---|---|
? | 匹配单个字符 | KEYS user:? | 匹配 user:0、user:a 等(单个字符占位) |
* | 匹配任意个字符(包括 0 个) | KEYS article:* | 匹配 article:123、article:abc 等 |
[abc] | 匹配括号内任意单个字符 | KEYS tag:[123] | 匹配 tag:1、tag:2、tag:3 |
[^e] | 匹配不在括号内的单个字符 | KEYS name:[^e] | 匹配 name:a、name:b 等(排除 name:e) |
[a-b] | 匹配指定范围的单个字符 | KEYS order:[0-9] | 匹配 order:0 到 order:9 |
生产环境风险警示:
keys *
命令会对 Redis 全库键进行遍历,其实现方式是阻塞主线程直至完成所有键的扫描。在百万级以上键的场景中,该操作可能导致 Redis 服务卡顿甚至超时,直接影响业务可用性。禁止在生产环境使用keys *
或其他匹配模式过大的keys
命
替代方案推荐使用 SCAN
命令,其通过游标分批迭代的方式获取键,可有效避免阻塞。例如,如需遍历所有以 article:
为前缀的键,可执行:
SCAN 0 MATCH article:* COUNT 100
该命令从游标 0
开始,每次返回最多 100 个匹配键,并返回下一次迭代的游标,直至游标为 0
表示遍历完成。此方式可在业务低峰期执行,降低对正常服务的影响。
2.2.2exists
EXISTS
命令是 Redis 中用于判断一个或多个键是否存在的核心操作命令,其功能定位是提供键状态的快速校验机制,在缓存管理、数据一致性维护等场景中具有基础支撑作用。
语法格式
该命令支持单键或多键检查,基本语法为:
EXISTS key [key ...]
其中 key
为待检查的键名,支持同时传入多个键名(用空格分隔)进行批量检查。
返回值解析
EXISTS
命令的返回值为 整数类型,表示在指定的键列表中实际存在的键的数量,这一设计区别于传统布尔值返回逻辑,为批量操作提供了更丰富的状态信息。具体表现为:
- 当检查单个键时,若键存在返回
1
,不存在返回0
- 当检查多个键时,返回值为存在的键的总数
代码示例
> SET cart:100 "items"
OK> EXISTS cart:100
(integer) 1> EXISTS order:999
(integer) 0> SET user:100 "John Doe"
OK> SET product:200 "Book"
OK> EXISTS user:100 product:200 category:30
(integer) 2
通过以下场景可直观理解返回值特性:
- 检查存在的单键:
EXISTS cart:100
→ 返回1
(表示购物车 ID 100 的键存在) - 检查不存在的单键:
EXISTS order:999
→ 返回0
(表示订单 ID 999 的键不存在) - 检查多个键:
EXISTS user:100 product:200 category:30
→ 若前两个键存在、第三个不存在,则返回2
> EXISTS product:100 stock:100 discount:100
(integer) 3
关键特性:EXISTS
命令的返回值设计使其在批量场景中具备高效性,一次调用即可获取多个键的存在状态,避免了多次单键检查带来的网络往返开销。例如在电商商品详情页渲染前,可通过 EXISTS product:100 stock:100 discount:100
批量验证商品基础数据、库存及折扣信息的缓存是否存在,显著提升系统响应速度。
业务实用价值
在实际生产环境中,EXISTS
命令的典型应用包括:
- 缓存穿透防护:在查询数据库前,通过
EXISTS
检查缓存键是否存在,若不存在则直接返回空结果,避免无效数据库查询 - 分布式锁实现:在尝试获取锁前,通过
EXISTS lock:resource
检查锁键状态,减少SETNX
等命令的无效调用 - 数据生命周期管理:定期通过
EXISTS
批量检查过期键的实际存在状态,辅助优化缓存淘汰策略
需注意的是,EXISTS
命令对已过期但尚未被删除(如处于惰性删除阶段)的键会返回 0
,因其逻辑上已不属于有效存在的键。这一特性确保了命令返回结果与键的实际可用状态保持一致,为业务决策提供可靠依据。
2.2.3del
DEL
命令是 Redis 中用于删除键的核心操作命令,其功能为永久性移除指定的一个或多个键。该命令的语法格式为 DEL key [key ...]
,其中 key
为待删除的键名,支持同时传入多个键进行批量删除。命令的返回值为整数类型,表示成功删除的键的数量——若指定键存在且被删除,则计数加 1;若键不存在,则不纳入计数。例如,执行 DEL user:100
时,若键 user:100
存在,返回值为 1;执行 DEL none_key
时,因键不存在,返回值为 0。
在性能层面,DEL
命令的时间复杂度为 O(N),其中 N 为被删除键的数量。对于单个键的删除操作(N=1),其执行耗时通常在微秒级(约 0.1μs),对 Redis 主线程的阻塞几乎可忽略不计;但当 N 显著增大时(如删除 10 万级键),命令执行时间将线性增长,可能导致主线程阻塞数百毫秒甚至秒级,直接影响 Redis 服务的响应可用性。这种阻塞源于 Redis 的单线程模型——所有命令串行执行,长时间运行的 DEL
操作会阻塞后续命令的处理,引发请求堆积和超时问题。
风险提示:在生产环境中,应绝对避免对大量键执行一次性 DEL
操作。例如,删除包含 10 万个元素的集合键(如 SET
或 HASH
)时,Redis 需要遍历并释放所有元素内存,此过程可能持续数百毫秒,导致集群节点短暂不可用,进而引发业务超时或重试风暴。
针对大量键删除场景,生产实践中推荐采用分批增量删除策略,核心思路是通过 SCAN
命令遍历目标键空间,将大规模删除任务拆分为多个小批次执行,以控制单次操作的阻塞时长。具体实现步骤如下:
- 使用
SCAN
命令增量遍历匹配特定模式的键(如user:*
),每次返回少量结果(如 100 个键); - 对每批返回的键执行
DEL
删除; - 循环执行上述过程,直至遍历完所有目标键。
以下为基于 Redis 命令行的分批删除示例代码:
# 初始化游标为 0,用于 SCAN 命令的迭代遍历
cursor=0
# 循环执行扫描与删除,直至游标返回 0(表示遍历完成)
while [ $cursor -ne 0 ] || [ -z "$cursor" ]; do# 执行 SCAN 命令:从当前游标开始,匹配 user:* 模式的键,每次尝试返回 100 个结果# 注意:COUNT 参数仅为提示值,实际返回数量可能因键分布波动scan_result=$(redis-cli SCAN $cursor MATCH user:* COUNT 100)# 提取返回结果中的新游标(第一部分)和键列表(剩余部分)cursor=$(echo "$scan_result" | awk '{print $1}')keys=$(echo "$scan_result" | awk '{$1=""; print $0}')# 若存在待删除键,则执行 DEL 命令批量删除if [ -n "$keys" ]; thenredis-cli DEL $keysecho "Deleted keys: $keys"fi
done
echo "All matching keys have been processed."
此外,若业务允许,建议将大批量删除操作安排在业务低峰期执行,以进一步降低对服务可用性的影响。对于极端场景(如需要删除数百万级键),还可结合 UNLINK
命令(Redis 4.0+)——该命令通过异步释放内存的方式减少主线程阻塞,但需注意其内存回收延迟可能导致短暂的内存占用上升。
2.2.4expire和pexpire
EXPIRE 和 PEXPIRE 是 Redis 中用于设置键生存时间(Time-To-Live, TTL)的核心命令,二者均用于指定键在一段时间后自动过期并被删除,主要差异体现在时间单位上。EXPIRE 以秒为单位,PEXPIRE 以毫秒为单位,通过精确控制键的生命周期,可有效管理内存资源并实现缓存自动失效等场景。
基本用法与代码示例
# 设置一个键
> SET session:100 "user:john"
OK# 设置过期时间为 1800 秒 = 30 分钟
> EXPIRE session:100 1800
(integer) 1# 查询键的剩余生存时间(单位:秒)
> TTL session:100
(integer) 1799 # 可能略有变化
# 设置一个缓存键
> SET cache:200 "data_result"
OK# 设置过期时间为 5000 毫秒 = 5 秒
> PEXPIRE cache:200 5000
(integer) 1# 查询键的剩余生存时间(单位:毫秒)
> PTTL cache:200
(integer) 4998 # 可能略有变化
- EXPIRE:语法为
EXPIRE key seconds
,用于将键key
的生存时间设置为seconds
秒。例如,执行EXPIRE session:100 1800
可将会话键session:100
的过期时间设为 1800 秒(即 30 分钟),30 分钟后该键将自动失效。 - PEXPIRE:语法为
PEXPIRE key milliseconds
,用于将键key
的生存时间设置为milliseconds
毫秒。例如,执行PEXPIRE cache:200 5000
可将缓存键cache:200
的过期时间设为 5000 毫秒(即 5 秒),5 秒后该键将被自动删除。
Redis 过期策略流程
Redis 采用 定期删除 与 惰性删除 相结合的过期键删除策略,以平衡内存释放效率与性能开销。其工作流程如下:
过期策略详解
1. 定期删除模块
核心机制:Redis 内置一个定时任务,每隔 100ms 随机抽取部分设置了过期时间的键进行检查,若键已过期则立即删除。该机制通过限制每次检查的键数量(默认不超过 20 个)和频率(100ms 间隔),避免对主线程性能造成显著影响。
时间间隔设置的权衡:
- 过短间隔(如 10ms):会导致频繁的键检查操作,增加 CPU 占用率,尤其在键数量庞大时可能引发性能瓶颈。
- 过长间隔(如 1s):过期键无法及时删除,可能导致内存中堆积大量无效数据,长期运行可能引发内存泄漏风险。
2. 惰性删除模块
核心机制:当客户端通过 GET
等命令访问某个键时,Redis 会先检查该键是否已过期。若过期,则立即删除该键并返回 nil
;若未过期,则正常返回键值。此机制确保只有被访问的过期键才会被处理,避免了对未访问键的无效检查。
优缺点对比
定期删除
- 优点:主动释放过期键占用的内存,减少无效数据堆积,适合内存敏感场景。
- 缺点:即使键已过期,若未被随机选中检查,仍会暂存内存;且定期检查本身存在 CPU 性能开销。
惰性删除
- 优点:仅在键被访问时才进行过期检查,无额外性能开销,适合读操作频率低的场景。
- 缺点:被动释放内存,若过期键长期未被访问,会导致内存资源浪费,甚至引发“内存泄漏”假象。
内存与性能的平衡逻辑
Redis 通过 定期删除主动清理+惰性删除被动兜底 的组合策略,实现了内存管理与性能的动态平衡:
- 定期删除 负责批量“清扫”过期键,避免内存占用无限增长;
- 惰性删除 确保过期键在被访问时立即被清理,避免无效数据返回给客户端。、
这种设计既降低了单一策略的局限性,又使得 Redis 在高并发场景下能同时兼顾内存利用率与响应速度。实际应用中,可通过调整 hz
配置(默认 10,即每秒执行 10 次定期检查)进一步优化定期删除的频率,以适应不同业务的性能需求。
2.2.5ttl
Redis 的 ttl 命令用于查询指定键的剩余生存时间(Time To Live),即键在多久后会被自动删除。该命令是 Redis 键生命周期管理的核心工具之一,通过返回值可直观判断键的当前状态,为缓存策略优化、资源回收等场景提供关键依据。
命令作用
ttl 命令的基本语法为 TTL key
,其中 key
为目标键名。执行后,命令会返回键的剩余生存时间(单位:秒),若键不存在或已过期则返回特定标识值。该命令无需额外参数,执行效率极高,时间复杂度为 O(1),适合高频调用场景。
返回值解析
ttl 命令的返回值分为三种情况,具体含义及示例如下:
1. 返回 -1:键存在且未设置过期时间
当键被创建但未通过 EXPIRE
、PEXPIRE
等命令设置过期时间时,ttl 命令返回 -1,表示键为永久有效状态。
# 创建键但不设置过期时间
SET user:100 age 20
# 查看剩余生存时间
TTL user:100 # 返回 -1
2. 返回正数:键存在且剩余生存时间为指定秒数
若键已设置过期时间且未过期,ttl 命令返回当前剩余的秒数(实际值可能因 Redis 内部精度或命令执行延迟略有波动)。
# 为键设置 3600 秒(1 小时)过期时间
EXPIRE user:100 3600
# 立即查看剩余时间(约为 3599 秒,因命令执行耗时产生微小偏差)
TTL user:100 # 返回 3599(具体值以实际执行为准)
3. 返回 -2:键不存在或已过期
当键不存在,或键已过期并被 Redis 自动删除(或通过 DEL
命令手动删除)时,ttl 命令返回 -2。
# 等待键过期(或手动删除键)
DEL user:100
# 查看已删除键的剩余生存时间
TTL user:100 # 返回 -2
ttl 命令返回值速查表:
- -1:键永久有效(无过期时间)
- -2:键不存在或已过期
- 正数(如 3599):键剩余生存时间(秒)
2.2.6type
在 Redis 中,TYPE 命令用于判断指定键对应的数据结构类型,是确保后续操作合法性的基础前提。由于 Redis 支持多种数据结构(如字符串、列表、哈希等),且不同结构对应专属操作命令(例如列表需使用 LPUSH/LPOP,哈希需使用 HSET/HGET),通过 TYPE 命令可预先确认键的类型,避免因对错误类型键执行命令而导致的操作失败或数据异常。
命令语法与返回值解析
TYPE 命令的语法格式简洁,具体为:
TYPE key
其中 key
为目标键名。该命令会返回键所对应数据结构的类型标识,常见返回值及对应数据结构如下表所示:
返回值 | 对应数据结构 | 典型操作命令示例 |
---|---|---|
string | 字符串 | SET、GET、APPEND |
list | 列表 | LPUSH、LRANGE、RPOP |
set | 集合 | SADD、SMEMBERS、SREM |
hash | 哈希表 | HSET、HGET、HKEYS |
zset | 有序集合 | ZADD、ZRANGE、ZREM |
none | 键不存在 | - |
实践示例与效果验证
通过具体操作可直观理解 TYPE 命令的作用:
1. 字符串类型键验证
首先使用 SET 命令创建字符串键,再通过 TYPE 命令检测其类型:
127.0.0.1:6379> SET str:key "hello"
OK
127.0.0.1:6379> TYPE str:key
string
结果返回 string
,表明 str:key
为字符串类型,后续可安全使用字符串相关命令(如 GET、APPEND)。
2. 列表类型键验证
使用 LPUSH 创建列表键后,TYPE 命令返回对应类型标识:
127.0.0.1:6379> LPUSH list:key 1 2
(integer) 2
127.0.0.1:6379> TYPE list:key
list
返回 list
确认该键为列表类型,此时可执行 LPOP、LRANGE 等列表操作。
3. 不存在键的处理
若键未被创建,TYPE 命令将返回 none
:
127.0.0.1:6379> TYPE none:key
none
这提示当前键不存在,需先通过对应命令初始化数据结构。
生产环境中的关键价值
在多数据结构共存的复杂场景中(例如一个 Redis 实例同时存储用户会话(字符串)、商品列表(列表)、用户标签(集合)等),TYPE 命令是避免操作冲突的重要工具。例如,若误将哈希键当作字符串键执行 SET 命令,Redis 会直接覆盖原哈希结构,导致数据丢失;而通过 TYPE 命令预先校验,可有效规避此类风险。
注意事项:TYPE 命令仅返回顶层数据结构类型,无法识别嵌套结构(如列表中存储的字符串值)。此外,对于 Redis 5.0 新增的 Stream 类型,TYPE 命令返回
stream
,需注意与其他结构的区分。
通过 TYPE 命令的合理应用,开发者可构建更健壮的 Redis 操作逻辑,确保数据操作的准确性与安全性。
3.小结
本章系统梳理了Redis命令体系的核心内容,涵盖基础操作与生产实践要点。在核心命令层面,set与get作为键值存储的基石,支持键值对的快速写入与读取,是构建缓存层的基础操作;全局命令则提供了集群级别的管理能力,其中keys命令支持按模式匹配查找键,exists用于判断键的存在性,del实现键的删除,配合type获取值类型、expire设置过期时间、ttl查询剩余生存时间等命令,共同构成了Redis数据管理的完整工具链。
生产环境中,命令使用需严守性能红线。
禁止在生产实例执行<code>keys </code>命令,该操作会遍历全库键,在百万级数据量下导致Redis主线程阻塞数百毫秒,引发服务超时;谨慎使用批量<code>del</code>操作,当删除超过1000个键时,建议采用<code>unlink</code>异步删除或分批删除策略,避免长时间阻塞事件循环*。
今天的分享到这里就结束咯,喜欢的小伙伴多多点赞支持加关注,你的支持就是我最大的鼓励~