hiredis需手动管理连接、内存和字符串生命周期,redis-plus-plus提供RAII和异步支持但依赖Boost/线程库;连接失败优先排查Redis服务、防火墙和bind配置;多线程下hiredis非线程安全,redis-plus-plus线程安全但需合理配置连接池与超时。

用 hiredis 同步连接 Redis 并执行 SET/GET
直接上手最常用的 C++ Redis 客户端是 hiredis,它轻量、稳定、无依赖,但注意:它本身是 C 库,C++ 项目里得手动处理字符串生命周期和错误码,不是开箱即用的“智能对象”。
常见错误现象:redisConnect() 返回 NULL 却没检查,后续调用 redisCommand() 直接崩溃;或传入的 key/value 是栈上局部 std::string::c_str(),命令还没发出去字符串就析构了。
- 必须先调用
redisConnect("127.0.0.1", 6379),检查返回值是否为NULL或ctx->err是否非零 -
redisCommand()返回的是redisReply*,每次调用后必须用freeReplyObject()释放,否则内存泄漏 - 如果 value 来自
std::string,确保传给redisCommand()的指针指向的内容在命令执行完前有效(推荐用c_str()+ 确保 string 对象生命周期足够长) - 示例片段:
redisContext *c = redisConnect("127.0.0.1", 6379); if (!c || c->err) { fprintf(stderr, "Connection error: %s\n", c ? c->errstr : "Unknown"); return; } redisReply *r = (redisReply*)redisCommand(c, "SET %s %s", "mykey", "hello"); if (r && r->type == REDIS_REPLY_STATUS && strcmp(r->str, "OK") == 0) { printf("SET success\n"); } freeReplyObject(r); r = (redisReply*)redisCommand(c, "GET %s", "mykey"); if (r && r->type == REDIS_REPLY_STRING) { printf("GET result: %s\n", r->str); } freeReplyObject(r); redisFree(c);
用 redis-plus-plus 异步操作更符合 C++ 习惯
redis-plus-plus 是基于 hiredis 封装的现代 C++ 客户端,支持同步/异步、连接池、自动序列化,但要注意:它依赖 boost.asio(异步模式)或 std::thread(同步模式),编译时需链接对应库,且异步接口返回的是 std::future,不能忽略其状态。
常见错误现象:创建 Redis 对象时不传连接参数,导致运行时报 Connection is not available;或调用 set("k", "v").get() 时没捕获 sw::redis::Error 异常。
立即学习“C++免费学习笔记(深入)”;
- 同步初始化:
sw::redis::Redis redis("tcp://127.0.0.1:6379");,URL 格式必须准确,不支持纯 IP+端口字符串 - 键值类型默认是
std::string,若存int需显式转成字符串,如redis.set("counter", std::to_string(42)) - 异步操作(如
redis.set_async("k", "v"))返回std::future<void></void>或std::future<:string></:string>,必须调用.get()或.wait(),否则任务可能被丢弃 - 连接断开后首次操作会抛
sw::redis::ConnectionError,建议用 try/catch 包裹关键操作
连接失败的三个高频原因和验证方式
连不上不是代码写错,大概率是环境或配置问题。别急着改 C++ 代码,先本地验证 Redis 服务状态。
-
redis-cli -h 127.0.0.1 -p 6379 PING返回PONG?不行就说明服务没起来或端口被占 - 防火墙是否拦截:Linux 上检查
sudo ufw status,Windows 检查 Windows Defender 防火墙出站规则 - Redis 配置文件中
bind是否只绑定了127.0.0.1(默认),远程连接需加0.0.0.0并设protected-mode no(仅测试环境) - 若用 Docker,确认容器内网互通:
docker exec -it your-redis-container ping host.docker.internal(宿主机服务)或检查--network模式
性能与线程安全的关键提醒
hiredis 的 redisContext 不是线程安全的,一个连接对象不能跨线程共用;redis-plus-plus 的 Redis 实例是线程安全的(内部用连接池),但每个实例仍应尽量复用而非频繁构造。
- 高并发场景下,不要为每次请求 new 一个
Redis对象——连接建立开销大,应作为单例或从连接池获取 - 若用
hiredis,多线程需为每个线程分配独立redisContext,或用互斥锁保护单个 context(性能差,不推荐) - 批量操作优先用
pipeline(redis-plus-plus中为pipeline.execute()),比多次set减少网络往返 - 超时设置容易被忽略:
redis-plus-plus初始化时可传ConnectionOptions设置connect_timeout和socket_timeout,否则默认阻塞很久才失败
redis-plus-plus 的异常语义和 RAII 更省心,但上线前务必压测连接池大小和超时配置;而直接用 hiredis 虽底层可控,但每处 freeReplyObject 和空指针检查都得亲手写牢。


















