生产环境首选 redis-plus-plus,它基于 hiredis 封装,支持同步/异步、连接池、SSL、Pipeline 和事务,头文件即用,CMake 集成简单,需确保已安装 hiredis 依赖并显式配置超时与密码等参数。

用哪个C++ Redis客户端库最靠谱
生产环境首选 redis-plus-plus(原 sw/redis),它基于 hiredis 封装,支持同步/异步、连接池、SSL、Pipeline 和事务,头文件即用,CMake 集成简单。别碰那些只有一两个 commit 的小众库,连 SCAN 迭代器都没实现全的容易卡死在生产环境。
安装方式(推荐 v1.3.4+):
git clone https://github.com/sewenew/redis-plus-plus.git cd redis-plus-plus && mkdir build && cd build cmake .. && make && sudo make install
注意:必须确保系统已装 hiredis(Ubuntu 上 sudo apt install libhiredis-dev),否则编译报错 fatal error: hiredis/hiredis.h: No such file or directory。
连接Redis时怎么避免阻塞和超时失败
默认构造的 Redis 对象不带超时,DNS 解析慢或网络抖动时会卡住十几秒。必须显式配置 ConnectionOptions:
立即学习“C++免费学习笔记(深入)”;
ConnectionOptions options; options.host = "127.0.0.1"; options.port = 6379; options.connect_timeout = std::chrono::milliseconds(100); options.socket_timeout = std::chrono::milliseconds(500);
关键点:
-
connect_timeout控制建连阶段耗时,设太短可能连不上局域网 Redis;设太长会让服务启动变慢 -
socket_timeout是读写超时,不是命令执行时间——Redis 执行KEYS *卡住 5 秒,这个超时照样触发 - 如果 Redis 开了密码,一定要加
options.password = "mypass",否则认证失败返回空响应,get("key")直接抛Error异常
string/set/hash 操作怎么写才不出错
API 设计是「命令名驼峰 + 参数直传」,但类型约束很严格,比如 set 的 value 必须是 StringView 或 std::string,传 int 会静默转成地址值存进去:
redis.set("counter", 123); // ❌ 存的是内存地址,取出来是乱码
redis.set("counter", "123"); // ✅ 字符串字面量
redis.set("counter", std::to_string(123)); // ✅ 安全转换
常用操作对照:
- 存 JSON:
redis.set("user:1001", json_str),取出来后自己用nlohmann::json::parse() - 批量 set:
redis.mset({{"k1","v1"},{"k2","v2"}}),注意是std::vector<std::pair<StringView, StringView>> - hash 操作:
redis.hset("user:1001", "name", "Alice"),字段名和值都不可为nullptr - 不存在才设:
redis.set("key", "val", std::chrono::seconds(30), SetMode::NX)
如何安全地复用连接而不是每次 new 一个
频繁创建/销毁 Redis 实例会导致连接数暴涨、TIME_WAIT 堆积,正确做法是全局单例或依赖注入一个共享实例:
static Redis redis_instance([]{
ConnectionOptions opts = {/*...*/};
return Redis(opts);
}());
但更推荐用连接池(RedisPool),尤其在多线程 Web 服务中:
ConnectionPoolOptions pool_opts; pool_opts.size = 8; // 最大连接数 RedisPool pool(options, pool_opts); // 每次用:auto redis = pool.pop(); ... pool.push(redis);
注意:连接池里的 Redis 实例不是线程安全的,不能跨线程共享同一个实例;pop() 出来的对象必须 push() 回去,否则连接泄漏——没调 push 的线程退出时,连接直接被析构,池大小永久减少。
真正难处理的是连接断开后的自动重连逻辑,redis-plus-plus 不自动重连,得自己捕获 Error 异常后重建连接池,这部分得结合业务重试策略来写,不是库能兜底的。


















