第三方 Python 库 redis-py + hiredis 的使用
一、背景:为什么 Python 开发者需要关注 Redis 客户端库?
做过 Web 开发的同学,对 Redis 一定不陌生。无论是做缓存、会话管理、消息队列,还是排行榜、计数器,Redis 几乎是后端架构里的"标配组件"。
但问题来了——Python 怎么跟 Redis 打交道?
答案是:通过客户端库。Python 生态里最主流的 Redis 客户端就是redis-py,它是 Redis 官方维护的 Python SDK,几乎所有的 Python 项目操作 Redis 都在用它。
而hiredis,则是另一个经常被提起的名字。很多教程里会告诉你"装上 hiredis 能让 redis-py 跑得更快",但很少有人把两者的关系和原理讲清楚。
这篇文章就来把这件事说透:redis-py 和 hiredis 到底是什么关系?为什么要一起用?怎么用?
二、概念厘清:redis-py 和 hiredis 分别是什么?
2.1 redis-py —— Python 的 Redis “翻译官”
redis-py是 Redis 官方出品的 Python 客户端库,用纯 Python 编写。它的职责很明确:
- 把你在 Python 里写的
r.set('name', 'Tom')翻译成 Redis 能理解的 RESP 协议报文 - 把 Redis 返回的二进制响应解析成 Python 能用的数据类型(bytes、str、int、list 等)
你可以把它想象成一个翻译官:你用 Python 说话,Redis 用 RESP 协议说话,redis-py 负责两边互译。
importredis# 创建连接r=redis.Redis(host='localhost',port=6379,db=0,decode_responses=True)# 操作 Redis 就像操作 Python 字典一样简单r.set('name','Tom')print(r.get('name'))# 输出: Tom2.2 hiredis —— 用 C 写的"高性能翻译引擎"
hiredis是 Redis 官方用C 语言编写的客户端库。它的定位不是给 Python 开发者直接用的,而是作为一个底层引擎。
hiredis 最核心的价值在于它的回复解析器(Reply Parser)——它用 C 实现了一套高效的 RESP 协议解析逻辑,能把 Redis 返回的原始字节流快速解析成结构化数据。
打个比方:
- redis-py 自带的解析器是用 Python 写的,相当于一个普通翻译
- hiredis 的解析器是用 C 写的,相当于一个同声传译设备——速度更快、效率更高
2.3 两者的关系:redis-py 是外壳,hiredis 是加速引擎
关键结论:redis-py 和 hiredis 不是竞争关系,而是合作关系。
redis-py 从 3.x 版本开始就内置了对 hiredis 的支持。当系统中安装了 hiredis(>= 1.0),redis-py 会自动切换使用 hiredis 的 C 语言解析器来处理 Redis 响应,而不需要你修改任何代码。
用一张表来总结:
| 对比维度 | redis-py | hiredis |
|---|---|---|
| 语言 | Python | C |
| 角色 | 完整的 Redis 客户端 SDK | 底层协议解析引擎 |
| 能否独立使用 | 能,开箱即用 | 能,但需要 C 编程 |
| 在 Python 中的作用 | 主角,负责所有 Redis 操作 | 配角,只负责加速响应解析 |
| 是否需要改代码 | — | 不需要,redis-py 自动识别并启用 |
三、方案选择:要不要装 hiredis?
3.1 只用 redis-py(纯 Python 模式)
redis-py 自带一个纯 Python 实现的响应解析器,功能完全够用。如果你的场景是:
- 数据量不大
- 对延迟不敏感
- 不想引入 C 扩展依赖
那么只装 redis-py 就够了:
pipinstallredis3.2 redis-py + hiredis(加速模式)
如果你的场景是:
- 高并发,每秒处理大量 Redis 命令
- 需要解析大量数据(比如
HGETALL一个有几万个 field 的 Hash) - 对响应时间有要求
那就推荐安装 hiredis:
pipinstall"redis[hiredis]"这个命令会同时安装 redis-py 和 hiredis,而且 redis-py 会自动检测并启用hiredis 解析器,无需任何代码改动。
3.3 性能差距有多大?
hiredis 解析器相比纯 Python 解析器,通常能带来2~10 倍的解析速度提升,具体取决于响应数据的大小和复杂度。数据量越大、结构越复杂(比如嵌套的数组),hiredis 的优势越明显。
不过要注意:hiredis 只优化了"响应解析"这一环节。如果你的瓶颈在网络延迟或 Redis 本身的执行速度,装 hiredis 的提升就不会那么显著。
四、环境搭建与配置
4.1 前置条件
- Python 3.12+(本文开发环境)
- Redis 服务端 7.2+(推荐)
- pip 包管理器
4.2 关于 Python 版本的说明
本文的开发环境基于Python 3.12,选择这个版本有几个考量:
Python 3.12 的主要改进
Python 3.12 是一个值得关注的版本,带来了不少实质性的提升:
- 性能优化:CPython 解释器本身的执行效率有了明显提升,整体性能比 3.11 提升约 5%
- 类型提示增强:
typing模块进一步完善,支持更灵活的泛型写法 - 错误信息更友好:报错提示更加精准,调试体验好了不少
- 移除废弃模块:
distutils等老旧模块被正式移除
对 redis-py 的影响
结论:完全兼容,放心使用。
redis-py 6.2.0 要求 Python 3.9+,Python 3.12 完全满足要求。而且 redis-py 的代码风格也在跟进新版 Python 的特性,比如类型注解的写法更规范了。
# 在 Python 3.12 环境下安装 redis-py,没有任何兼容性问题pipinstallredis对 hiredis 的影响
结论:使用 hiredis 2.0+ 版本即可。
hiredis 是 C 扩展包,需要编译后才能在 Python 中使用。Python 3.12 对 C API 做了一些调整(比如移除了一些废弃的 API),所以 hiredis 需要相应更新才能兼容。
好消息是,hiredis 2.0+ 已经适配了 Python 3.12 的 C API 变化,直接安装就行:
pipinstall"redis[hiredis]"如果你之前在旧版本 Python 下安装过 hiredis,升级到 Python 3.12 后建议重新安装:
pipinstall--force-reinstall"redis[hiredis]"版本对应关系速查
| Python 版本 | redis-py 要求 | hiredis 建议版本 | 兼容性 |
|---|---|---|---|
| 3.9 ~ 3.11 | >= 6.2.0 | >= 1.0 | 完全兼容 |
| 3.12+ | >= 6.2.0 | >= 2.0 | 完全兼容(推荐) |
小提示:如果你是新项目,直接用 Python 3.12 + redis-py 最新版 + hiredis 2.0+ 就是最稳的组合。
4.3 启动 Redis
用 Docker 启动一个 Redis 实例最省事:
# Redis 8.0+dockerrun-p6379:6379-itredis:latest# Redis 8.0 以下dockerrun-p6379:6379-itredis/redis-stack:latest4.4 安装 redis-py(两种方式)
方式一:只装 redis-py
pipinstallredis方式二:redis-py + hiredis 加速(推荐)
pipinstall"redis[hiredis]"安装完成后,可以通过以下方式验证 hiredis 是否生效:
importredisprint(redis.__version__)# 查看 redis-py 版本# 检查 hiredis 是否可用try:importhiredisprint(f"hiredis 版本:{hiredis.__version__}")print("hiredis 解析器已启用,性能加速生效!")exceptImportError:print("hiredis 未安装,使用纯 Python 解析器")4.5 建立连接
redis-py 提供了多种连接方式,从简单到复杂依次是:
直接连接
importredis r=redis.Redis(host='localhost',port=6379,db=0)带解码的连接(推荐)
默认情况下,redis-py 返回的是 bytes 类型(如b'Tom')。加上decode_responses=True后,返回的就是 Python 字符串了:
r=redis.Redis(host='localhost',port=6379,db=0,decode_responses=True)r.set('name','Tom')print(r.get('name'))# 输出: Tom(字符串)print(type(r.get('name')))# <class 'str'>使用连接池
在生产环境中,建议使用连接池来管理连接,避免频繁创建和销毁连接的开销:
importredis# 创建连接池pool=redis.ConnectionPool(host='localhost',port=6379,db=0,decode_responses=True,max_connections=20# 最大连接数)# 从连接池获取连接r=redis.Redis(connection_pool=pool)五、实战:redis-py 常用操作
以下示例均基于 redis-py 官方文档,使用decode_responses=True以便输出更直观。
5.1 字符串操作
importredis r=redis.Redis(host='localhost',port=6379,db=0,decode_responses=True)# SET / GETr.set('name','Tom')print(r.get('name'))# Tom# 设置过期时间(秒)r.setex('token',60,'abc123')# 60 秒后自动删除# 自增操作r.set('counter',0)r.incr('counter')r.incr('counter')r.incr('counter')print(r.get('counter'))# 35.2 哈希操作
Hash 是 Redis 中最常用的结构之一,特别适合存储对象:
# 存储用户信息r.hset('user:1001',mapping={'name':'Tom','age':'25','city':'Beijing'})# 获取单个字段print(r.hget('user:1001','name'))# Tom# 获取所有字段print(r.hgetall('user:1001'))# {'name': 'Tom', 'age': '25', 'city': 'Beijing'}5.3 列表操作
# 从右侧推入r.rpush('tasks','task1','task2','task3')# 获取列表长度print(r.llen('tasks'))# 3# 获取指定范围的元素print(r.lrange('tasks',0,-1))# ['task1', 'task2', 'task3']# 从左侧弹出print(r.lpop('tasks'))# task15.4 集合操作
# 添加元素r.sadd('tags:python','web','data','ai')r.sadd('tags:java','web','enterprise','android')# 集合交集(共同标签)print(r.sinter('tags:python','tags:java'))# {'web'}# 集合并集print(r.sunion('tags:python','tags:java'))# {'web', 'data', 'ai', 'enterprise', 'android'}5.5 Pipeline:批量操作的利器
当你需要一次性执行多条命令时,Pipeline 能显著减少网络往返次数:
# 不用 Pipeline:3 次网络往返r.set('a',1)r.set('b',2)r.set('c',3)# 使用 Pipeline:1 次网络往返pipe=r.pipeline()pipe.set('a',1)pipe.set('b',2)pipe.set('c',3)results=pipe.execute()print(results)# [True, True, True]Pipeline 的原理很简单:它把多条命令打包在一起,一次性发送给 Redis,然后一次性接收所有响应。命令数量越多,Pipeline 的优势越明显。
5.6 Pub/Sub:发布订阅
# 创建一个独立的连接用于订阅pubsub=r.pubsub()# 订阅频道pubsub.subscribe('notifications')# 在另一个进程/线程中发布消息# r.publish('notifications', 'Hello, everyone!')# 监听消息formessageinpubsub.listen():ifmessage['type']=='message':print(f"收到消息:{message['data']}")六、深入理解:redis-py 如何自动启用 hiredis?
这是很多开发者好奇的地方——redis-py 是怎么"感知"到 hiredis 的存在的?
原理其实不复杂。redis-py 在初始化时会做一次检测:
- 尝试
import hiredis - 如果导入成功,且版本 >= 1.0,就使用 hiredis 的 C 语言解析器
- 如果导入失败,就退回到纯 Python 解析器
这个过程对用户完全透明,你不需要写任何额外代码。
redis-py 的官方文档是这样说的:
For faster performance, install redis with hiredis support, this provides a compiled response parser, andfor most casesrequires zero code changes. By default, if hiredis >= 1.0 is available, redis-py will attempt to use it for response parsing.
翻译过来就是:装上 hiredis,大多数情况下零代码改动,redis-py 自动启用它。
那什么时候需要手动控制?
极少数情况下,你可能想强制使用纯 Python 解析器(比如调试协议问题)。这时候可以在创建连接时显式指定:
importredis# 强制使用纯 Python 解析器(不推荐在生产环境使用)r=redis.Redis(host='localhost',port=6379,db=0)但在实际项目中,几乎没有理由拒绝 hiredis——它是一个免费的性能提升,没有副作用。
七、版本兼容性速查
在使用之前,确认一下版本兼容性,避免踩坑:
redis-py 版本与 Python 版本
| redis-py 版本 | Python 要求 |
|---|---|
| 5.0 | Python 3.7(最后支持) |
| 5.1 ~ 6.1 | Python 3.8+ |
| 6.2+ | Python 3.9+ |
redis-py 版本与 Redis 服务端版本
| redis-py 版本 | 支持的 Redis 版本 |
|---|---|
| 3.5.3 | <= 6.2 |
| >= 4.5.0 | 5.0 ~ 7.0 |
| >= 5.0.0 | 5.0 ~ 7.4 |
| >= 6.0.0 | 7.2 ~ 当前 |
hiredis 版本要求
redis-py 要求hiredis >= 1.0,低于此版本不会被自动启用。当前 hiredis 的稳定版是 1.x 系列,直接pip install hiredis装到的就是满足要求的版本。
八、常见问题与注意事项
Q1:装了 hiredis 之后,代码需要改吗?
不需要。这是 redis-py 设计的初衷——hiredis 是一个透明的加速层,对上层 API 没有任何影响。
Q2:hiredis 装不上怎么办?
hiredis 是一个 C 扩展包,安装时需要编译。如果你在 Windows 上遇到编译错误:
# 确保安装了 Visual C++ Build Tools# 或者使用预编译的 wheelpipinstallhiredis --only-binary=:all:在 Linux/macOS 上一般不会有问题,系统自带的 GCC/Clang 就能编译。
Q3:redis-py 的 RESP3 协议支持是什么?
从 redis-py 5.0 开始支持 RESP3 协议(Redis 6.0 引入的新协议)。RESP3 相比 RESP2 支持更多数据类型(如布尔值、双精度浮点数、Map 等)。
redis-py 8.0 之后默认使用 RESP3 传输,但为了兼容性,响应格式仍然保持 RESP2 的风格。如果你是新项目,可以显式启用:
r=redis.Redis(host='localhost',port=6379,db=0,legacy_responses=False)Q4:连接池的最大连接数怎么设置?
一般的经验公式:
max_connections = 并发线程数 + 预留余量比如你有 10 个工作线程,设置 15~20 就够了。设太大会浪费 Redis 端的连接资源。
九、总结
回到文章开头的问题:redis-py 和 hiredis 到底是什么关系?
用一句话概括:
redis-py 是 Python 操作 Redis 的"主力",hiredis 是给它加装的"涡轮增压"。
几个核心要点:
- redis-py是完整的 Python Redis 客户端,能独立使用,覆盖所有 Redis 命令
- hiredis是 C 语言实现的高效协议解析器,不直接给 Python 开发者用,而是作为底层引擎
- 两者结合使用时,redis-py 负责上层 API,hiredis 负责底层解析加速
- 安装方式:
pip install "redis[hiredis]",零代码改动即可获得性能提升 - hiredis 只加速响应解析环节,如果瓶颈在网络或 Redis 本身,效果有限
最佳实践建议
| 场景 | 建议 |
|---|---|
| 学习 / 原型开发 | 只装 redis-py 就够了 |
| 生产环境 / 高并发 | 强烈推荐 redis-py + hiredis |
| 需要 RESP3 特性 | redis-py 5.0+,推荐搭配 hiredis |
| Windows 开发环境 | 优先用--only-binary安装 hiredis |
十、参考文档
- redis-py 官方仓库:https://github.com/redis/redis-py
- redis-py 官方文档:https://redis.readthedocs.io/en/stable/
- hiredis 官方仓库:https://github.com/redis/hiredis
- Redis 官方命令文档:https://redis.io/commands
- RESP3 协议规范:https://github.com/antirez/RESP3/blob/master/spec.md
- Redis University 免费课程:https://redis.io/learn/university
写在最后:技术选型这件事,不是"越新越好"或"越快越好",而是"适合的才是最好的"。redis-py + hiredis 的组合,本质上就是在"开发便利性"和"运行性能"之间找到了一个很好的平衡点。希望这篇文章能帮你把这个知识点串起来,下次遇到 Redis 性能优化的时候,多一个可选方案。