把一个 Python 字典传给
Redis,并不等于把原生对象搬进另一块内存。应用需要先决定如何编码、选择什么
Redis 数据结构,以及读取后如何还原类型。
理解这三层关系,比记住“Redis 能存哪些 Python 类型”更有用。
Key 是字节串,Value
有数据结构
Redis 的 key
是二进制安全的字符串,可以包含任意字节。它并不要求应用中的变量必须是
Python str,客户端还可以接受字节等支持的输入。
常见的五种基础数据结构如下;这不是 Redis
全部能力的穷尽列表。其他类型与功能是否可用,应查看部署版本。Redis
数据类型
| 类型 | 保存什么 | 典型操作 |
|---|---|---|
| String | 字节串、编码后的数字或序列化内容 | SET、GET、INCR |
| List | 有序且可重复的字符串序列 | LPUSH、RPUSH、LRANGE |
| Set | 不重复的字符串成员 | SADD、SISMEMBER |
| Hash | 字段到值的映射 | HSET、HGET、HINCRBY |
| Sorted Set | 带分数的唯一成员 | ZADD、ZRANGE |
不要把“String 能保存任意字节”扩大为“每种 Value
都只是任意序列化字节”。List、Hash 等有自己的结构和命令约束。
一个可读写的示例
下面需要已运行的本地 Redis 与 redis-py 客户端:
python -m pip install redis
import json
import redis
client = redis.Redis(host="localhost", port=6379, decode_responses=True)
client.set("study:demo:name", "Alice")
client.set("study:demo:age", 25)
client.set("study:demo:active", "1")
print(client.get("study:demo:name"))
print(int(client.get("study:demo:age")))
print(client.get("study:demo:active") == "1")
profile = {"name": "Alice", "preferences": {"language": "zh"}}
client.set("study:demo:profile", json.dumps(profile), ex=3600)
restored = json.loads(client.get("study:demo:profile"))
print(restored["preferences"]["language"])
decode_responses=True 让文本响应解码为字符串,不会自动把
"25"
变成整数。布尔值也应采用明确的编码约定,不要依赖客户端隐式转换。
示例写入会保留在本地数据库中;复杂内容使用 JSON String
时,更新内部字段通常需要读出、修改、再写回。
Hash 与 JSON String 如何选择
经常单独更新用户年龄、积分等字段时,Hash 更直接:
client.hset("study:demo:user:1", mapping={"name": "Alice", "age": 25})
client.hincrby("study:demo:user:1", "age", 1)
print(client.hgetall("study:demo:user:1"))
如果每次都是读取和替换完整的嵌套对象,JSON 序列化后存为 String
往往更简单。若需要对嵌套路径做服务端操作,可以检查部署是否支持 JSON
数据类型,而不能断言 Redis 一律不支持嵌套 JSON。Redis
JSON
不要在同一个 key 上交替使用 String 与 Hash。已经用 SET
创建的 key,再直接执行 HSET 会发生类型冲突。
列表、集合与元组
RPUSH key a b c
从右侧按顺序追加;LPUSH key a b c
会逐个从左侧插入,最终顺序是 c、b、a。两者不是保持顺序的等价写法。
Python 集合可以逐个成员写入 Redis Set。Python
列表若包含嵌套字典,则不能直接把它当作普通字符串列表传入,需要为每个元素制定序列化方案,或保存整个
JSON。
元组通过 JSON 编码后通常成为数组,反序列化回 Python 时得到
list,不会自动恢复 tuple 的类型和不可变语义。
在工程中补上生命周期
缓存除了值,还需要过期策略。例子里的 ex=3600
表示一小时后过期;真实 TTL 应由业务新鲜度决定。
单条 INCR 或 HINCRBY 是原子操作,但“读取
JSON—修改—写回”由多条操作构成,可能覆盖并发更新。需要根据需求采用事务、乐观锁或服务端原子逻辑。
在 RAG 中,可以分别缓存查询改写、检索结果和生成结果,并让 key
包含知识库版本及模型配置。缓存命中只表示找到了已有值,并不自动证明该值仍适用于当前权限和数据版本。