c++怎么操作redis数据库_c++ hiredis库连接与命令执行【实战】

15次阅读

使用 hiredis 同步连接 Redis 需调用 redisConnectWithTimeout 设置超时(单位为 struct timeval),连接后必须检查 context->err;执行命令需按 redisReply->type 分支安全处理并调用 freeReplyObject 释放;二进制数据须用 redisCommandArgv;context 非线程安全且无自动重连,需手动管理连接与 reply 生命周期。

c++怎么操作redis数据库_c++ hiredis库连接与命令执行【实战】

怎么用 hiredisredis 服务(同步模式)

hiredis 默认是同步阻塞的,连接失败或网络卡住会直接 hang 住线程。所以第一步必须设好超时,否则生产环境容易出问题。

  • redisConnect 不支持超时,得用 redisConnectWithTimeout
  • 超时单位是 Struct timeval,不是毫秒——{1, 500000} 表示 1.5 秒
  • 连接后务必检查 context->err,不能只看指针是否为空(比如认证失败时指针非空但 err 非零)
struct timeval timeout = {1, 500000}; redisContext *c = redisConnectWithTimeout("127.0.0.1", 6379, timeout); if (c == nullptr || c->err) {     if (c) {         fprintf(stderr, "Redis connection error: %sn", c->errstr);         redisFree(c);     }     return -1; }

怎么执行 SET/GET 命令并安全取返回值

hiredis 的 redisCommand 返回的是 redisReply*,但它的结构不是扁平的,类型判断和字段访问必须严格按 reply->type 分支处理,否则容易段错误或读错内存。

  • REDIS_REPLY_STRING 才有 strlenREDIS_REPLY_Integer 要用 integer 字段
  • REDIS_REPLY_NIL 表示 key 不存在,此时 str == nullptr,不能直接 strlen
  • 所有 redisReply* 必须用 freeReplyObject 释放,不释放会内存泄漏
redisReply *reply = (redisReply*)redisCommand(c, "SET mykey 'hello'"); if (reply && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0) {     printf("SET successn"); } freeReplyObject(reply);  reply = (redisReply*)redisCommand(c, "GET mykey"); if (reply) {     if (reply->type == REDIS_REPLY_STRING) {         printf("GET result: %.*sn", (int)reply->len, reply->str);     } else if (reply->type == REDIS_REPLY_NIL) {         printf("key not existsn");     } } freeReplyObject(reply);

怎么处理批量命令和二进制安全数据

Redis 原生支持二进制 key/value,但 C 字符串习惯用 截断,直接传 char* 会丢数据。hiredis 提供了带长度参数的接口,必须用它们。

  • 避免用 redisCommand(c, "SET %b %b", key, key_len, val, val_len) 这种格式化方式——它内部仍走 sprintf,对二进制不安全
  • 改用 redisCommandArgv,手动构造 redisArgv 数组,每个元素带 len
  • 批量操作别硬写多个 redisCommand,用 pipeline(即连续发命令+一次收回复)提升吞吐
const char *argv[4]; size_t argvlen[4]; argv[0] = "MSET"; argvlen[0] = 4; argv[1] = "key1"; argvlen[1] = 4; argv[2] = "val1"; argvlen[2] = 4; argv[3] = "key2"; argvlen[3] = 4; // 注意:MSET 后面要成对出现,这里只是示意结构 redisReply *r = (redisReply*)redisCommandArgv(c, 4, argv, argvlen);

为什么程序跑一会儿就卡死或崩溃

最常见的三个原因:连接未重连、reply 未释放、多线程共用 context。hiredis 的 redisContext 不是线程安全的,且没有自动重连机制。

立即学习C++免费学习笔记(深入)”;

  • 每次发命令前,检查 c->fd != -1c->err == 0,任一不成立就得 redisFree + 重连
  • 所有 redisCommand 调用后,无论成功失败,都必须 freeReplyObject(包括返回 nullptr 的情况)
  • 多线程场景下,每个线程必须有自己的 redisContext,或者用连接池管理(不能简单全局单例)

连接断开后 redisCommand 可能返回 nullptr,但 context 还活着,继续用会导致未定义行为——这个点最容易被忽略。

text=ZqhQzanResources