hiredis: 一个轻量级、高性能的 C 语言 Redis 客户端库
目录
1.简介
2.安装和配置
2.1.源码编译安装(通用方法)
2.2.包管理器安装(特定系统)
2.3.Windows 安装
3.常用的函数及功能
3.1.连接管理函数
3.2.命令执行函数
3.3.异步操作函数
3.4.回复处理函数
3.5.错误处理
3.6.连接池与线程安全
4.编译与链接
5.常见用法
6.应用场景
7.注意事项
1.简介
hiredis 是一个轻量级、高性能的 C 语言 Redis 客户端库,用于与 Redis 数据库进行通信。它提供了简洁的 API,支持同步 / 异步操作、管道(pipelining)、事务(transactions)等特性,被广泛应用于需要与 Redis 交互的 C/C++ 项目中。
下载地址:https://github.com/redis/hiredis
它的核心特征有:
- 轻量级:仅包含几个源文件和头文件,无外部依赖,易于集成。
- 高性能:基于非阻塞 I/O,支持批量操作(管道)和异步回调。
- 完整的 Redis 协议实现:支持所有 Redis 命令和数据类型。
- 线程安全:通过连接池或每个线程独立连接实现线程安全。
- 异步事件驱动:可与 libevent、libev 等事件库集成,适合高并发场景。
2.安装和配置
2.1.源码编译安装(通用方法)
步骤 1:获取源码
git clone https://github.com/redis/hiredis.git
cd hiredis
步骤 2:编译与安装
make # 编译库
make test # (可选)运行测试
sudo make install # 安装到系统目录(默认:/usr/local/lib 和 /usr/local/include)
步骤 3:更新动态链接库缓存(Linux 系统)
sudo ldconfig
2.2.包管理器安装(特定系统)
1.Ubuntu/Debian
sudo apt-get install libhiredis-dev
2.CentOS/RHEL
sudo yum install hiredis-devel
3.macOS (via Homebrew)
brew install hiredis
2.3.Windows 安装
方法 1:使用 vcpkg(推荐)
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install hiredis
方法 2:手动编译(MinGW/MSYS2)
1.安装 MSYS2 并更新:
pacman -Syu
2.安装编译工具链和依赖:
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake
3.编译 hiredis:
git clone https://github.com/redis/hiredis.git
cd hiredis
make CC=x86_64-w64-mingw32-gcc
方法 3:CMake编译
参考:Windows下通过CMake编译hiredis及应用_hiredis windows-CSDN博客
3.常用的函数及功能
Hiredis 提供了一系列用于与 Redis 服务器通信的函数,主要分为连接管理、命令执行、异步操作和辅助工具四大类。以下是常用函数及其功能的详细介绍:
3.1.连接管理函数
redisConnect:
创建同步连接到 Redis 服务器。
//函数声明
redisContext *redisConnect(const char *ip, int port);//示例
redisContext *ctx = redisConnect("127.0.0.1", 6379);
if (ctx->err) {printf("Connection error: %s\n", ctx->errstr);
}
redisConnectWithTimeout:
创建同步连接并设置超时时间。
redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval timeout);
redisFree:
释放 Redis 连接上下文。
void redisFree(redisContext *c);
3.2.命令执行函数
redisCommand:
执行 Redis 命令并返回结果。
//函数声明
redisReply *redisCommand(redisContext *c, const char *format, ...);//示例
redisReply *reply = redisCommand(ctx, "SET key %s", "value");
if (reply->type == REDIS_REPLY_STATUS) {printf("SET result: %s\n", reply->str);
}
freeReplyObject(reply); // 释放回复对象
redisCommandArgv:
以参数数组形式执行 Redis 命令(避免字符串格式化问题)。
//函数声明
redisReply *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);//示例
const char *argv[3] = {"SET", "key", "value"};
size_t argvlen[3] = {3, 3, 5};
redisReply *reply = redisCommandArgv(ctx, 3, argv, argvlen);
redisAppendCommand:
将命令添加到输出缓冲区(用于管道)。
int redisAppendCommand(redisContext *c, const char *format, ...);
redisGetReply:
从输入缓冲区获取命令回复(用于管道)。
int redisGetReply(redisContext *c, void **reply);
3.3.异步操作函数
redisAsyncConnect:
创建异步连接到 Redis 服务器。
redisAsyncContext *redisAsyncConnect(const char *ip, int port);
redisAsyncSetConnectCallback:
设置连接成功 / 失败的回调函数。
void redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
redisAsyncCommand:
异步执行 Redis 命令。
//函数声明
int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);//示例
void getCallback(redisAsyncContext *ac, void *r, void *privdata) {redisReply *reply = r;printf("GET result: %s\n", reply->str);
}redisAsyncCommand(ac, getCallback, NULL, "GET key");
redisAsyncDisconnect:
断开异步连接。
void redisAsyncDisconnect(redisAsyncContext *ac);
3.4.回复处理函数
freeReplyObject:
释放 Redis 回复对象,防止内存泄漏。
void freeReplyObject(void *reply);
3.5.错误处理
redisContext.err
和 redisContext.errstr:
检查连接错误和错误信息。
if (ctx->err) {printf("Error: %s\n", ctx->errstr);
}
3.6.连接池与线程安全
Hiredis 本身不是线程安全的,但可通过以下方式实现线程安全:
1)每个线程独立连接:为每个线程创建单独的 redisContext
。
2)连接池:管理多个 redisContext
实例,线程需要时从池中获取。
4.编译与链接
编译时需链接 hiredis 库:
gcc your_file.c -o your_program -lhiredis
5.常见用法
1.同步连接与命令执行
#include <hiredis/hiredis.h>int main() {// 连接到 Redis 服务器redisContext *ctx = redisConnect("127.0.0.1", 6379);if (ctx == NULL || ctx->err) {printf("Connection error: %s\n", ctx ? ctx->errstr : "NULL");return 1;}// 执行命令(SET key value)redisReply *reply = redisCommand(ctx, "SET %s %s", "key", "value");if (reply) {freeReplyObject(reply); // 释放回复对象}// 执行命令(GET key)reply = redisCommand(ctx, "GET %s", "key");if (reply && reply->type == REDIS_REPLY_STRING) {printf("GET key: %s\n", reply->str);freeReplyObject(reply);}// 断开连接redisFree(ctx);return 0;
}
2.管道(Pipelining)
批量发送命令以减少网络往返:
redisAppendCommand(ctx, "SET key1 value1");
redisAppendCommand(ctx, "SET key2 value2");
redisAppendCommand(ctx, "GET key1");
redisAppendCommand(ctx, "GET key2");// 获取所有回复
redisReply *reply;
redisGetReply(ctx, (void**)&reply); freeReplyObject(reply);
redisGetReply(ctx, (void**)&reply); freeReplyObject(reply);
redisGetReply(ctx, (void**)&reply); printf("key1: %s\n", reply->str); freeReplyObject(reply);
redisGetReply(ctx, (void**)&reply); printf("key2: %s\n", reply->str); freeReplyObject(reply);
3.异步操作(基于 libevent)
#include <hiredis/async.h>
#include <hiredis/adapters/libevent.h>// 回调函数
void getCallback(redisAsyncContext *ac, void *r, void *privdata) {redisReply *reply = r;if (reply == NULL) return;printf("GET result: %s\n", reply->str);
}int main() {struct event_base *base = event_base_new();redisAsyncContext *ac = redisAsyncConnect("127.0.0.1", 6379);// 设置事件循环redisLibeventAttach(ac, base);// 设置连接回调redisAsyncSetConnectCallback(ac, connectCallback);redisAsyncSetDisconnectCallback(ac, disconnectCallback);// 异步执行命令redisAsyncCommand(ac, getCallback, NULL, "GET key");// 启动事件循环event_base_dispatch(base);// 清理资源redisAsyncFree(ac);event_base_free(base);return 0;
}
6.应用场景
- 缓存系统:作为 Redis 客户端,实现数据缓存。
- 实时统计:利用 Redis 的原子操作实现计数器、排行榜等。
- 消息队列:结合 Redis 的
LIST
或STREAM
实现消息队列。 - 分布式锁:使用 Redis 的
SETNX
或SET ... NX
实现分布式锁。
7.注意事项
1.内存管理:每次调用 redisCommand()
或 redisGetReply()
后,需通过 freeReplyObject()
释放回复对象。
2.线程安全:redisContext
非线程安全,多线程环境需为每个线程创建独立连接或使用连接池。
3.异步回调:异步模式下,回调函数会在事件循环线程中执行,需注意线程安全。
掌握hiredis的接口函数后,你可以根据项目需求选择同步或异步方式与 Redis 服务器交互,实现缓存、消息队列等功能。