目錄
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 服務器交互,實現緩存、消息隊列等功能。