Redis GET 命令详细教程
GET 用于读取 Redis 中指定 Key 对应的字符串(String)值。它是 Redis 最常用的读取命令之一,常用于获取缓存数据、配置项、计数结果以及序列化后的对象。
本文基于 Redis String 数据类型介绍
GET。Redis 命令本身不区分大小写,因此GET、get和Get的效果相同;文档统一使用大写形式。
资料合集:https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338
一、命令概览
1. 基本语法
redis
GET key
参数说明:
key:要读取的 Key 名称。- 返回值:Key 存在时返回对应的字符串值;Key 不存在时返回空值(在 RESP2 中通常显示为
(nil))。
2. 最简单的示例
先写入一个字符串值:
redis
SET username alice
读取该值:
redis
GET username
返回:
text
"alice"
二、GET 的返回结果
1. Key 存在且类型正确
redis
SET site:name "Redis 教程"
GET site:name
返回:
text
"Redis 教程"
2. Key 不存在
redis
GET not-exists
返回:
text
(nil)
应用程序通常会将这个结果转换为 null、nil 或 None。需要注意,空值和空字符串不是同一个结果:
redis
SET empty-value ""
GET empty-value
该 Key 存在,但返回的是空字符串,而不是不存在。
3. Key 的类型不是 String
GET 只能读取 String 类型的 Key。如果目标 Key 存储的是 List、Hash、Set、Sorted Set 等其他数据类型,Redis 会返回 WRONGTYPE 错误。
例如:
redis
HSET user:1001 name Alice
GET user:1001
返回类似:
text
(error) WRONGTYPE Operation against a key holding the wrong kind of value
此时应根据实际类型使用对应命令,例如 Hash 使用 HGET 或 HGETALL,List 使用 LRANGE。
可以先使用 TYPE 检查 Key 类型:
redis
TYPE user:1001
三、GET 适合存储什么数据
Redis String 不仅可以保存普通文本,也可以保存以下内容:
1. 普通文本
redis
SET message "Hello Redis"
GET message
2. 数字字符串
Redis 将数字也作为字符串保存,但支持使用 INCR、DECR 等命令进行整数运算:
redis
SET page:view:count 100
GET page:view:count
INCR page:view:count
GET page:view:count
最后返回:
text
"101"
GET 本身不会执行数值计算,也不会保证值一定是合法数字。
3. JSON 字符串
应用程序可以将对象序列化为 JSON 后保存:
redis
SET user:1001 '{"id":1001,"name":"Alice","active":true}'
GET user:1001
返回的是完整 JSON 文本。Redis 不会自动解析 JSON;解析工作需要由客户端程序完成。如果使用 RedisJSON 模块,则应使用模块提供的 JSON 命令进行结构化访问。
4. 二进制数据
Redis String 可以保存二进制安全的数据,但在命令行中直接查看时可能无法直观显示。应用程序应通过支持二进制的 Redis 客户端读取和处理。
四、GET 与相关命令的区别
1. GET 与 MGET
GET 一次读取一个 Key:
redis
GET user:1001:name
MGET 一次读取多个 Key:
redis
MGET user:1001:name user:1001:age user:1001:city
当需要读取多个相互独立的字符串 Key 时,优先考虑 MGET,可以减少客户端与 Redis 之间的网络往返次数。不存在的 Key 在结果中对应空值。
2. GET 与 GETDEL
GETDEL 会读取值并删除 Key:
redis
GETDEL one-time-token
如果只需要读取而不删除,应使用 GET。
3. GET 与 GETEX
GETEX 会读取值,并且可以同时设置、更新或移除过期时间:
redis
GETEX session:1001 EX 3600
如果只读取值且不改变过期属性,应使用 GET。
4. GET 与 GETSET
GETSET 会设置新值,同时返回旧值。该命令在较新 Redis 版本中已标记为弃用,通常建议使用带 GET 选项的 SET:
redis
SET status new GET
只读取旧值时,仍然使用 GET。
5. GET 与 HGET
String 和 Hash 是不同的数据类型:
redis
SET user:name Alice
GET user:name
redis
HSET user:1001 name Alice
HGET user:1001 name
对 Hash 使用 GET 会产生 WRONGTYPE 错误。
五、GET 与过期时间
GET 只读取值,不会自动延长或缩短 Key 的过期时间,也不会移除过期时间。
redis
SET cache:product:1 "product data" EX 300
GET cache:product:1
TTL cache:product:1
执行 GET 后,TTL 仍由 Redis 按原规则递减。需要查看过期时间,可以使用:
TTL key:以秒为单位查看剩余时间。PTTL key:以毫秒为单位查看剩余时间。
Key 过期后,GET 会返回空值:
redis
SET short-lived value EX 1
GET short-lived
等待过期后再次读取:
redis
GET short-lived
返回 (nil)。
六、事务、Pipeline 与并发场景
1. 在事务中读取
可以将 GET 放入事务队列:
redis
MULTI
GET username
GET user:1001:name
EXEC
EXEC 执行后会返回各个 GET 命令对应的结果。
2. 使用 Pipeline 批量读取
客户端需要读取多个 Key 时,可以使用 Pipeline 或 MGET。对于单纯的多个 String Key 读取,MGET 通常更直接;如果批处理中还包含其他命令,则可以考虑 Pipeline。
3. 读取后再判断再写入
下面这种流程不是原子操作:
text
GET key
根据结果判断
SET key value
多个客户端同时执行时可能产生竞态条件。如果需求是"仅当 Key 不存在时写入",应使用:
redis
SET key value NX
如果需要对数值进行并发递增,应使用 INCR,不要使用 GET 后在应用程序中计算再 SET。
七、在常见客户端中的使用方式
1. redis-cli
bash
redis-cli SET greeting "Hello Redis"
redis-cli GET greeting
连接指定服务器后执行:
bash
redis-cli -h 127.0.0.1 -p 6379 -a your-password GET greeting
生产环境中不建议直接将密码写在命令行参数中,以免密码出现在进程列表或命令历史中;应根据 Redis 版本和客户端能力使用更安全的认证方式。
2. Python(redis-py)
python
import redis
client = redis.Redis(host="localhost", port=6379, decode_responses=True)
client.set("greeting", "Hello Redis")
value = client.get("greeting")
print(value) # Hello Redis
如果未设置 decode_responses=True,读取结果通常是 bytes,例如 b"Hello Redis",需要应用程序自行解码。
3. Node.js(node-redis)
javascript
import { createClient } from "redis";
const client = createClient();
await client.connect();
await client.set("greeting", "Hello Redis");
const value = await client.get("greeting");
console.log(value); // Hello Redis
await client.quit();
4. Java(Jedis)
java
try (Jedis jedis = new Jedis("localhost", 6379)) {
jedis.set("greeting", "Hello Redis");
String value = jedis.get("greeting");
System.out.println(value);
}
不同客户端对不存在 Key 的返回值处理方式可能不同,但通常会映射为 null 或对应语言的空值。
八、典型使用场景
1. 读取缓存
redis
GET cache:user:1001
应用程序读取到空值时,通常需要从数据库加载数据,再使用 SET 写入缓存。
2. 读取会话数据
redis
GET session:4f8a9c
会话数据通常配合过期时间使用,避免无效会话长期占用内存。
3. 读取配置
redis
GET config:feature:new-checkout
读取配置时,需要在应用程序中约定值的格式,例如 true、false、版本号或 JSON 文本。
4. 读取分布式锁的标识
redis
GET lock:order:1001
读取锁值只能用于观察或校验。释放锁时不能仅凭 GET 结果再执行 DEL,否则可能误删其他客户端后来获得的锁。应使用 Lua 脚本将"比较锁值"和"删除 Key"作为原子操作完成。
九、性能与使用建议
GET是 O(1) 操作,读取单个 String Key 的时间复杂度通常为 O(1)。- 避免在高延迟网络环境中循环执行大量单 Key
GET,批量读取时优先使用MGET或 Pipeline。 - 不要使用
GET读取由其他数据类型保存的 Key,先确认数据模型和 Key 类型。 - 缓存数据应设置合理的过期时间,避免无期限 Key 持续占用内存。
- 不要把密码、令牌等敏感数据直接输出到日志或命令行历史中。
- 大字符串会占用较多内存,并增加网络传输成本;需要时应拆分数据或采用更合适的数据结构。
- 不要把
GET后的结果当作绝对最新状态。在主从复制、集群或缓存场景中,应结合业务一致性要求选择合适的读取节点和策略。
十、常见问题排查
问题 1:GET 返回 (nil)
按以下顺序检查:
- Key 名称是否拼写正确。
- 当前连接的 Redis 主机、端口和数据库编号是否正确。
- Key 是否已经过期或被删除。
- 写入和读取是否使用了不同的 Redis 实例或逻辑数据库。
- Key 是否包含不可见字符、前后空格或大小写差异。
可以使用以下命令辅助检查:
redis
EXISTS key
TTL key
TYPE key
问题 2:返回 WRONGTYPE
执行:
redis
TYPE key
如果结果不是 string,就使用对应数据类型的读取命令。例如:
redis
HGET key field
LRANGE key 0 -1
SMEMBERS key
ZRANGE key 0 -1 WITHSCORES
问题 3:客户端读取到 bytes
这是客户端的编码配置问题,不是 Redis GET 的错误。可以在客户端开启自动解码,或根据实际字符集将 bytes 转换为字符串。
十一、完整练习
下面的示例演示从写入、读取、检查类型到检查过期时间的完整流程:
redis
DEL product:1001
SET product:1001 '{"id":1001,"name":"Keyboard","price":199}' EX 600
GET product:1001
TYPE product:1001
TTL product:1001
预期结果:
GET product:1001返回 JSON 字符串。TYPE product:1001返回string。TTL product:1001返回不超过600的剩余秒数。
十二、命令速查表
| 需求 | 命令 |
|---|---|
| 读取一个字符串值 | GET key |
| 读取多个字符串值 | MGET key1 key2 ... |
| 读取并删除 | GETDEL key |
| 读取并设置过期属性 | GETEX key ... |
| 读取并替换旧值 | SET key value GET |
| 查看 Key 类型 | TYPE key |
| 判断 Key 是否存在 | EXISTS key |
| 查看剩余过期时间(秒) | TTL key |
| 查看剩余过期时间(毫秒) | PTTL key |
总结
GET 的核心作用是读取 String 类型 Key 的值:
redis
GET key
使用时重点注意三点:
- Key 不存在时返回空值,空字符串则表示 Key 存在但内容为空。
- Key 类型必须是 String,否则会返回 WRONGTYPE 错误。
GET是只读操作,不会修改值,也不会改变 Key 的过期属性。