Hiredis 是 Redis 官方推薦的極簡 C 客戶端庫,無依賴、事件驅動友好。本文系統整理同步 API、異步 API、流水線、發布訂閱、錯誤處理、內存管理等核心用法,並給出生產環境最佳實踐模式。
make make install # 默認 /usr/local make install PREFIX=~/myredis # 自定義路徑
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c->err) { fprintf(stderr, "Error: %s\n", c->errstr); redisFree(c); return; }
// ... 業務邏輯 ...
redisFree(c); // 釋放上下文
redisReply *r = redisCommand(c, "SET key %s", value); // 字符串參數 redisReply *r = redisCommand(c, "SET key %b", data, len); // 二進制數據 %b redisReply *r = redisCommand(c, "GET key");
| 類型常量 | 字段 | 用途 |
|---|---|---|
| REDIS_REPLY_STATUS | str, len | OK/ERROR 等狀態回覆 |
| REDIS_REPLY_ERROR | str, len | 錯誤信息 |
| REDIS_REPLY_INTEGER | integer | 整數回覆 (INCR 等) |
| REDIS_REPLY_NIL | — | 不存在 (GET 無 key) |
| REDIS_REPLY_STRING | str, len | 字符串/二進制數據 |
| REDIS_REPLY_ARRAY | elements, element[] | 數組 (LRANGE/KEYS 等),元素為 redisReply* |
if (r->type == REDIS_REPLY_ARRAY) {
for (size_t i = 0; i < r->elements; i++)
printf("元素 %zu: %s\n", i, r->element[i]->str);
}
freeReplyObject(r); // **必須釋放**,否則內存洩漏
redisAppendCommand(c, "SET k1 v1"); redisAppendCommand(c, "GET k1"); redisReply *r; redisGetReply(c, (void**)&r); freeReplyObject(r); // SET 回覆 redisGetReply(c, (void**)&r); freeReplyObject(r); // GET 回覆
redisReply *r = redisCommand(c, "SUBSCRIBE chan");
freeReplyObject(r); // 訂閱確認回覆
while (redisGetReply(c, (void**)&r) == REDIS_OK) {
// r->element[0]: "message"/"subscribe"/"unsubscribe"
// r->element[1]: 頻道名
// r->element[2]: 消息內容 (message 類型時)
freeReplyObject(r);
}
redisAsyncContext *ac = redisAsyncConnect("127.0.0.1", 6379);
if (ac->err) { /* handle */ }
redisAsyncSetConnectCallback(ac, on_connect);
redisAsyncSetDisconnectCallback(ac, on_disconnect);
redisAsyncCommand(ac, on_set_cb, NULL, "SET key val");
redisAsyncCommand(ac, on_get_cb, NULL, "GET key");
// 事件循環驅動 (libevent/libev/ae 等)
// 需定期調用 redisAsyncHandleRead/Write
| 常量 | 含義 |
|---|---|
| REDIS_OK | 成功 |
| REDIS_ERR_IO | 系統 I/O 錯誤,查 errno |
| REDIS_ERR_EOF | 服務器關閉連接 |
| REDIS_ERR_PROTOCOL | 協議解析錯誤 |
| REDIS_ERR_OTHER | 其他 |
所有錯誤可通過 `c->errstr` 獲取描述字符串。
redisReader *rd = redisReaderCreate();
redisReaderFeed(rd, buf, len); // 喂入網絡數據
redisReply *r;
while (redisReaderGetReply(rd, (void**)&r) == REDIS_OK) {
// 處理 r
freeReplyObject(r);
}
redisReaderFree(rd);