第三方 Python 库 redis-py + hiredis 的使用

第三方 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 负责两边互译。

python 复制代码
import redis

# 创建连接
r = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)

# 操作 Redis 就像操作 Python 字典一样简单
r.set('name', 'Tom')
print(r.get('name'))  # 输出: Tom

2.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 就够了:

bash 复制代码
pip install redis

3.2 redis-py + hiredis(加速模式)

如果你的场景是:

  • 高并发,每秒处理大量 Redis 命令
  • 需要解析大量数据(比如 HGETALL 一个有几万个 field 的 Hash)
  • 对响应时间有要求

那就推荐安装 hiredis:

bash 复制代码
pip install "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 的特性,比如类型注解的写法更规范了。

bash 复制代码
# 在 Python 3.12 环境下安装 redis-py,没有任何兼容性问题
pip install redis
对 hiredis 的影响

结论:使用 hiredis 2.0+ 版本即可。

hiredis 是 C 扩展包,需要编译后才能在 Python 中使用。Python 3.12 对 C API 做了一些调整(比如移除了一些废弃的 API),所以 hiredis 需要相应更新才能兼容。

好消息是,hiredis 2.0+ 已经适配了 Python 3.12 的 C API 变化,直接安装就行:

bash 复制代码
pip install "redis[hiredis]"

如果你之前在旧版本 Python 下安装过 hiredis,升级到 Python 3.12 后建议重新安装:

bash 复制代码
pip install --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 实例最省事:

bash 复制代码
# Redis 8.0+
docker run -p 6379:6379 -it redis:latest

# Redis 8.0 以下
docker run -p 6379:6379 -it redis/redis-stack:latest

4.4 安装 redis-py(两种方式)

方式一:只装 redis-py

bash 复制代码
pip install redis

方式二:redis-py + hiredis 加速(推荐)

bash 复制代码
pip install "redis[hiredis]"

安装完成后,可以通过以下方式验证 hiredis 是否生效:

python 复制代码
import redis
print(redis.__version__)  # 查看 redis-py 版本

# 检查 hiredis 是否可用
try:
    import hiredis
    print(f"hiredis 版本: {hiredis.__version__}")
    print("hiredis 解析器已启用,性能加速生效!")
except ImportError:
    print("hiredis 未安装,使用纯 Python 解析器")

4.5 建立连接

redis-py 提供了多种连接方式,从简单到复杂依次是:

直接连接
python 复制代码
import redis

r = redis.Redis(host='localhost', port=6379, db=0)
带解码的连接(推荐)

默认情况下,redis-py 返回的是 bytes 类型(如 b'Tom')。加上 decode_responses=True 后,返回的就是 Python 字符串了:

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'>
使用连接池

在生产环境中,建议使用连接池来管理连接,避免频繁创建和销毁连接的开销:

python 复制代码
import redis

# 创建连接池
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 字符串操作

python 复制代码
import redis

r = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)

# SET / GET
r.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'))      # 3

5.2 哈希操作

Hash 是 Redis 中最常用的结构之一,特别适合存储对象:

python 复制代码
# 存储用户信息
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 列表操作

python 复制代码
# 从右侧推入
r.rpush('tasks', 'task1', 'task2', 'task3')

# 获取列表长度
print(r.llen('tasks'))   # 3

# 获取指定范围的元素
print(r.lrange('tasks', 0, -1))   # ['task1', 'task2', 'task3']

# 从左侧弹出
print(r.lpop('tasks'))   # task1

5.4 集合操作

python 复制代码
# 添加元素
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 能显著减少网络往返次数:

python 复制代码
# 不用 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:发布订阅

python 复制代码
# 创建一个独立的连接用于订阅
pubsub = r.pubsub()

# 订阅频道
pubsub.subscribe('notifications')

# 在另一个进程/线程中发布消息
# r.publish('notifications', 'Hello, everyone!')

# 监听消息
for message in pubsub.listen():
    if message['type'] == 'message':
        print(f"收到消息: {message['data']}")

六、深入理解:redis-py 如何自动启用 hiredis?

这是很多开发者好奇的地方------redis-py 是怎么"感知"到 hiredis 的存在的?

原理其实不复杂。redis-py 在初始化时会做一次检测:

  1. 尝试 import hiredis
  2. 如果导入成功,且版本 >= 1.0,就使用 hiredis 的 C 语言解析器
  3. 如果导入失败,就退回到纯 Python 解析器

这个过程对用户完全透明,你不需要写任何额外代码。

redis-py 的官方文档是这样说的:

For faster performance, install redis with hiredis support, this provides a compiled response parser, and for most cases requires 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 解析器(比如调试协议问题)。这时候可以在创建连接时显式指定:

python 复制代码
import redis

# 强制使用纯 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 上遇到编译错误:

bash 复制代码
# 确保安装了 Visual C++ Build Tools
# 或者使用预编译的 wheel
pip install hiredis --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 的风格。如果你是新项目,可以显式启用:

python 复制代码
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 是给它加装的"涡轮增压"。

几个核心要点:

  1. redis-py 是完整的 Python Redis 客户端,能独立使用,覆盖所有 Redis 命令
  2. hiredis 是 C 语言实现的高效协议解析器,不直接给 Python 开发者用,而是作为底层引擎
  3. 两者结合使用时,redis-py 负责上层 API,hiredis 负责底层解析加速
  4. 安装方式:pip install "redis[hiredis]",零代码改动即可获得性能提升
  5. hiredis 只加速响应解析环节,如果瓶颈在网络或 Redis 本身,效果有限

最佳实践建议

场景 建议
学习 / 原型开发 只装 redis-py 就够了
生产环境 / 高并发 强烈推荐 redis-py + hiredis
需要 RESP3 特性 redis-py 5.0+,推荐搭配 hiredis
Windows 开发环境 优先用 --only-binary 安装 hiredis

十、参考文档

  1. redis-py 官方仓库https://github.com/redis/redis-py
  2. redis-py 官方文档https://redis.readthedocs.io/en/stable/
  3. hiredis 官方仓库https://github.com/redis/hiredis
  4. Redis 官方命令文档https://redis.io/commands
  5. RESP3 协议规范https://github.com/antirez/RESP3/blob/master/spec.md
  6. Redis University 免费课程https://redis.io/learn/university

写在最后:技术选型这件事,不是"越新越好"或"越快越好",而是"适合的才是最好的"。redis-py + hiredis 的组合,本质上就是在"开发便利性"和"运行性能"之间找到了一个很好的平衡点。希望这篇文章能帮你把这个知识点串起来,下次遇到 Redis 性能优化的时候,多一个可选方案。

相关推荐
jingling5551 小时前
go | 环境安装和快速入门
开发语言·后端·golang
yuan199971 小时前
欧拉梁静力与屈曲计算的 MATLAB 实现(有限差分法 + 解析解)
开发语言·算法·matlab
llxxyy卢2 小时前
polar夏季赛部分题目
开发语言·python
闵孚龙2 小时前
PyTorch 系列 之 nn.Module:所有模型的骨架
人工智能·pytorch·python
AI玫瑰助手2 小时前
Python模块:from...import...导入指定内容
开发语言·python·信息可视化
石山代码2 小时前
JavaScript 进阶核心知识点
开发语言·javascript·ecmascript
小森林之主2 小时前
Python re 模块速查:从实战对比中掌握正则表达式
python·正则表达式·性能测试·re模块·编程实战
FL16238631292 小时前
[cmake]基于C++使用纯opencv部署ppocrv5v6的onnx模型
开发语言·c++·opencv