get 用于读取 redis 中指定 key 对应的字符串(string)值。它是 redis 最常用的读取命令之一,常用于获取缓存数据、配置项、计数结果以及序列化后的对象。
本文基于 redis string 数据类型介绍 get。redis 命令本身不区分大小写,因此 get、get 和 get 的效果相同;文档统一使用大写形式。
一、命令概览
1. 基本语法
get key
参数说明:
key:要读取的 key 名称。- 返回值:key 存在时返回对应的字符串值;key 不存在时返回空值(在 resp2 中通常显示为
(nil))。
2. 最简单的示例
先写入一个字符串值:
set username alice
读取该值:
get username
返回:
"alice"
二、get 的返回结果
1. key 存在且类型正确
set site:name "redis 教程" get site:name
返回:
"redis 教程"
2. key 不存在
get not-exists
返回:
(nil)
应用程序通常会将这个结果转换为 null、nil 或 none。需要注意,空值和空字符串不是同一个结果:
set empty-value "" get empty-value
该 key 存在,但返回的是空字符串,而不是不存在。
3. key 的类型不是 string
get 只能读取 string 类型的 key。如果目标 key 存储的是 list、hash、set、sorted set 等其他数据类型,redis 会返回 wrongtype 错误。
例如:
hset user:1001 name alice get user:1001
返回类似:
(error) wrongtype operation against a key holding the wrong kind of value
此时应根据实际类型使用对应命令,例如 hash 使用 hget 或 hgetall,list 使用 lrange。
可以先使用 type 检查 key 类型:
type user:1001
三、get 适合存储什么数据
redis string 不仅可以保存普通文本,也可以保存以下内容:
1. 普通文本
set message "hello redis" get message
2. 数字字符串
redis 将数字也作为字符串保存,但支持使用 incr、decr 等命令进行整数运算:
set page:view:count 100 get page:view:count incr page:view:count get page:view:count
最后返回:
"101"
get 本身不会执行数值计算,也不会保证值一定是合法数字。
3. json 字符串
应用程序可以将对象序列化为 json 后保存:
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:
get user:1001:name
mget 一次读取多个 key:
mget user:1001:name user:1001:age user:1001:city
当需要读取多个相互独立的字符串 key 时,优先考虑 mget,可以减少客户端与 redis 之间的网络往返次数。不存在的 key 在结果中对应空值。
2. get 与 getdel
getdel 会读取值并删除 key:
getdel one-time-token
如果只需要读取而不删除,应使用 get。
3. get 与 getex
getex 会读取值,并且可以同时设置、更新或移除过期时间:
getex session:1001 ex 3600
如果只读取值且不改变过期属性,应使用 get。
4. get 与 getset
getset 会设置新值,同时返回旧值。该命令在较新 redis 版本中已标记为弃用,通常建议使用带 get 选项的 set:
set status new get
只读取旧值时,仍然使用 get。
5. get 与 hget
string 和 hash 是不同的数据类型:
set user:name alice get user:name
hset user:1001 name alice hget user:1001 name
对 hash 使用 get 会产生 wrongtype 错误。
五、get 与过期时间
get 只读取值,不会自动延长或缩短 key 的过期时间,也不会移除过期时间。
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 会返回空值:
set short-lived value ex 1 get short-lived
等待过期后再次读取:
get short-lived
返回 (nil)。
六、事务、pipeline 与并发场景
1. 在事务中读取
可以将 get 放入事务队列:
multi get username get user:1001:name exec
exec 执行后会返回各个 get 命令对应的结果。
2. 使用 pipeline 批量读取
客户端需要读取多个 key 时,可以使用 pipeline 或 mget。对于单纯的多个 string key 读取,mget 通常更直接;如果批处理中还包含其他命令,则可以考虑 pipeline。
3. 读取后再判断再写入
下面这种流程不是原子操作:
get key
根据结果判断
set key value
多个客户端同时执行时可能产生竞态条件。如果需求是“仅当 key 不存在时写入”,应使用:
set key value nx
如果需要对数值进行并发递增,应使用 incr,不要使用 get 后在应用程序中计算再 set。
七、在常见客户端中的使用方式
1. redis-cli
redis-cli set greeting "hello redis" redis-cli get greeting
连接指定服务器后执行:
redis-cli -h 127.0.0.1 -p 6379 -a your-password get greeting
生产环境中不建议直接将密码写在命令行参数中,以免密码出现在进程列表或命令历史中;应根据 redis 版本和客户端能力使用更安全的认证方式。
2. python(redis-py)
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)
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)
try (jedis jedis = new jedis("localhost", 6379)) {
jedis.set("greeting", "hello redis");
string value = jedis.get("greeting");
system.out.println(value);
}
不同客户端对不存在 key 的返回值处理方式可能不同,但通常会映射为 null 或对应语言的空值。
八、典型使用场景
1. 读取缓存
get cache:user:1001
应用程序读取到空值时,通常需要从数据库加载数据,再使用 set 写入缓存。
2. 读取会话数据
get session:4f8a9c
会话数据通常配合过期时间使用,避免无效会话长期占用内存。
3. 读取配置
get config:feature:new-checkout
读取配置时,需要在应用程序中约定值的格式,例如 true、false、版本号或 json 文本。
4. 读取分布式锁的标识
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 是否包含不可见字符、前后空格或大小写差异。
可以使用以下命令辅助检查:
exists key ttl key type key
问题 2:返回 wrongtype
执行:
type key
如果结果不是 string,就使用对应数据类型的读取命令。例如:
hget key field lrange key 0 -1 smembers key zrange key 0 -1 withscores
问题 3:客户端读取到 bytes
这是客户端的编码配置问题,不是 redis get 的错误。可以在客户端开启自动解码,或根据实际字符集将 bytes 转换为字符串。
十一、完整练习
下面的示例演示从写入、读取、检查类型到检查过期时间的完整流程:
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 的值:
get key
使用时重点注意三点:
- key 不存在时返回空值,空字符串则表示 key 存在但内容为空。
- key 类型必须是 string,否则会返回 wrongtype 错误。
- get 是只读操作,不会修改值,也不会改变 key 的过期属性。
到此这篇关于redis中get命令的实现的文章就介绍到这了,更多相关redis get命令内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论