Ubuntu 22.04 编译安装与实战 redis-plus-plus C++ 客户端
1. 项目概述:为什么选择 redis-plus-plus?
如果你正在用 C++ 开发一个需要高性能数据缓存、消息队列或者会话存储的后端服务,那么 Redis 大概率是你的技术栈选项之一。作为一个 C++ 开发者,直接去解析 Redis 的 RESP 协议或者用裸的 socket 去通信,显然不是明智之举,我们需要一个成熟、高效且符合 C++ 习惯的客户端库。市面上选择不少,比如 hiredis ,它是一个轻量级的 C 库,很多 C++ 封装都基于它。但今天要聊的 redis-plus-plus ,在我看来,是目前 C++ 生态中连接 Redis 的“瑞士军刀”。
简单说, redis-plus-plus 是一个基于 hiredis 的 C++17 客户端库。它的设计哲学很明确:提供类型安全、直观易用、高性能且功能完整的接口。相比于直接使用 hiredis ,它帮你处理了连接池、重连、命令管道(pipelining)、事务、发布订阅等复杂逻辑,让你能像调用本地 STL 容器一样去操作 Redis。项目作者是 sewenew,在 GitHub 上非常活跃,社区和文档也都相当不错。
这次,我们就以 Ubuntu 22.04 LTS 这个目前非常稳定且流行的服务器操作系统为例,从头到尾走一遍 redis-plus-plus 的安装、配置和基础使用。无论你是要在云服务器上部署服务,还是在本地开发环境搭建测试,这套流程都适用。我会把过程中容易踩的坑、关键的配置参数,以及我实际项目中的使用心得都揉进去,目标是让你看完就能在自己的项目里用起来。
2. 环境准备与依赖安装
在开始编译安装 redis-plus-plus 之前,我们需要确保系统环境是干净的,并且所有必要的依赖都已就位。Ubuntu 22.04 默认的软件源已经比较新了,这为我们省去了不少麻烦。
2.1 系统更新与基础工具
首先,打开终端,更新一下包列表并升级现有软件包。这是一个好习惯,能避免一些因基础库版本过旧导致的编译问题。
sudo apt update
sudo apt upgrade -y
接着,安装编译所需的工具链,包括 g++ 、 cmake 和 make 。 redis-plus-plus 使用 CMake 作为构建系统,所以 cmake 是必须的。
sudo apt install -y build-essential cmake pkg-config
注意 :
pkg-config是一个用来帮助在编译时查找库文件和头文件的小工具,虽然redis-plus-plus的 CMake 脚本可能不直接依赖它,但安装上可以避免一些潜在的、其他依赖库的查找问题。
2.2 安装核心依赖:hiredis
redis-plus-plus 底层通信依赖于 hiredis 。虽然它的源码包自带了一个 hiredis 子模块,但为了系统管理的统一性和避免版本冲突,我强烈建议通过系统包管理器安装开发版。
sudo apt install -y libhiredis-dev
安装完成后,你可以通过 dpkg -L libhiredis-dev 查看头文件和库被安装到了哪里(通常是 /usr/include/hiredis 和 /usr/lib/x86_64-linux-gnu/ )。确保它能被找到是后续编译成功的关键。
2.3 可选但推荐的依赖:OpenSSL 和 TLS/SSL 支持
如果你的 Redis 服务器启用了 TLS/SSL 加密连接(特别是在云服务或生产环境中很常见),那么你需要安装 OpenSSL 的开发库。
sudo apt install -y libssl-dev
即使暂时不用 SSL,先安装上也无妨。 redis-plus-plus 在编译时会自动检测是否存在 OpenSSL,并决定是否编译 SSL 支持。有了这个,你的客户端就具备了连接加密 Redis 服务的能力,为未来留好了扩展性。
3. 编译与安装 redis-plus-plus
依赖就绪后,我们就可以开始编译 redis-plus-plus 本身了。这里我推荐从 GitHub 拉取最新的稳定版本源码进行编译,这样能获得最新的特性和修复。
3.1 获取源代码
首先,找一个合适的目录,比如 ~/workspace ,然后克隆仓库。使用 --recursive 参数确保子模块(它自带的 hiredis 备用源码)也被拉取下来。
cd ~
git clone --recursive https://github.com/sewenew/redis-plus-plus.git
cd redis-plus-plus
实操心得 :虽然我们通过系统包安装了
hiredis,但拉取子模块是个好习惯。万一系统版本不兼容,我们可以选择编译并使用源码包内的hiredis。不过,在 Ubuntu 22.04 上,APT 提供的版本通常足够新且稳定。
3.2 创建构建目录并运行 CMake
遵循 CMake 的“外部构建”最佳实践,我们在源码目录外创建一个单独的构建目录。
mkdir build
cd build
接下来是关键的 CMake 配置步骤。这里有几个重要的参数需要关注:
cmake .. -DCMAKE_BUILD_TYPE=Release -DREDIS_PLUS_PLUS_CXX_STANDARD=17 -DREDIS_PLUS_PLUS_BUILD_TEST=OFF
让我解释一下这几个参数:
-DCMAKE_BUILD_TYPE=Release:指定构建类型为发布模式。这会开启编译器优化(如-O3),移除调试信息,生成性能最优的库文件。如果是开发调试,可以设为Debug。-DREDIS_PLUS_PLUS_CXX_STANDARD=17:明确指定使用 C++17 标准。redis-plus-plus需要 C++11 及以上,但使用 C++17 能确保所有现代特性可用,也是作者推荐的标准。-DREDIS_PLUS_PLUS_BUILD_TEST=OFF:禁用测试用例的编译。这能显著加快编译速度,因为我们只需要库文件本身,不需要运行它的单元测试。
如果 CMake 运行成功,你会看到输出中包含了关键的总结信息,例如:
-- Build type: Release
-- C++ standard: 17
-- hiredis lib: /usr/lib/x86_64-linux-gnu/libhiredis.so
-- TLS/SSL support: ON (found OpenSSL)
-- ...
-- Configuring done
-- Generating done
请特别留意 hiredis lib 和 TLS/SSL support 这两行,确认它找到了我们系统安装的 hiredis 并且 SSL 支持已开启。
3.3 编译与安装
配置完成后,使用 make 进行编译。为了加快速度,可以使用 -j 参数指定并行编译的作业数,通常设置为 CPU 核心数。
make -j$(nproc)
编译过程可能需要一两分钟。成功后,就可以将库安装到系统目录了:
sudo make install
默认情况下,这会将头文件安装到 /usr/local/include/sw/ ,将库文件( libredis++.so 和 libredis++.a )安装到 /usr/local/lib/ 。 /usr/local 是 Linux 系统存放本地编译软件的标准位置。
3.4 验证安装与系统配置
安装完成后,我们需要让系统知道新库的位置。
-
更新动态链接库缓存 :运行以下命令,让系统载入
/usr/local/lib下的新库。sudo ldconfig -
验证头文件和库 :你可以快速检查一下文件是否存在。
ls /usr/local/include/sw/redis++/ # 应该看到一堆 .h 头文件 ls /usr/local/lib/libredis++.so # 应该看到共享库文件
至此, redis-plus-plus 库本身就已经在你的 Ubuntu 22.04 系统上安装完毕了。
4. 基础使用:从连接到第一个命令
理论说再多不如动手试一下。我们来创建一个最简单的 C++ 程序,连接 Redis 并执行几个基本命令。
4.1 准备一个测试用的 Redis 服务器
首先,确保你有一个可以连接的 Redis 服务器。如果你还没有,可以在同一台机器上快速安装一个用于测试:
sudo apt install -y redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-server
默认情况下,Redis 服务会监听 127.0.0.1:6379 ,且没有密码。这正好用于我们的本地测试。
4.2 编写第一个 C++ 程序
创建一个新的目录和源文件,例如 ~/test_redispp/ 。
mkdir ~/test_redispp && cd ~/test_redispp
touch test_basic.cpp
用你喜欢的编辑器(如 vim , nano , 或 VSCode)打开 test_basic.cpp ,输入以下代码:
#include <sw/redis++/redis++.h>
#include <iostream>
int main() {
try {
// 1. 创建连接选项,连接到本地默认Redis
sw::redis::ConnectionOptions connection_opts;
connection_opts.host = "127.0.0.1"; // Redis服务器地址
connection_opts.port = 6379; // Redis端口
connection_opts.socket_timeout = std::chrono::milliseconds(200); // 读写超时
// 2. 创建连接池选项(可选,但对于生产环境推荐)
sw::redis::ConnectionPoolOptions pool_opts;
pool_opts.size = 3; // 连接池大小
// 3. 创建Redis客户端对象
sw::redis::Redis redis(connection_opts, pool_opts);
// 4. 执行命令:设置一个键值对
redis.set("my_key", "Hello, redis-plus-plus!");
// 5. 执行命令:获取键值
auto val = redis.get("my_key");
if (val) {
std::cout << "The value of 'my_key' is: " << *val << std::endl;
} else {
std::cout << "'my_key' does not exist." << std::endl;
}
// 6. 执行命令:判断键是否存在
if (redis.exists("my_key")) {
std::cout << "'my_key' exists in Redis." << std::endl;
}
// 7. 执行命令:删除键
redis.del("my_key");
std::cout << "'my_key' has been deleted." << std::endl;
} catch (const sw::redis::Error &e) {
// 捕获所有redis-plus-plus抛出的异常
std::cerr << "Redis error: " << e.what() << std::endl;
return 1;
} catch (const std::exception &e) {
// 捕获其他标准异常
std::cerr << "Standard error: " << e.what() << std::endl;
return 1;
}
return 0;
}
4.3 编译并运行测试程序
现在来编译这个程序。你需要链接 redis++.so 和 hiredis.so 这两个库。
g++ -std=c++17 -o test_basic test_basic.cpp -lredis++ -lhiredis -pthread
参数解析 :
-std=c++17:指定 C++ 语言标准,必须与编译库时的一致。-o test_basic:指定输出可执行文件名。-lredis++ -lhiredis:链接redis-plus-plus和hiredis库。编译器会在默认库路径(如/usr/local/lib,/usr/lib)中查找libredis++.so和libhiredis.so。-pthread:因为redis-plus-plus内部可能使用了线程,所以需要链接 POSIX 线程库。
如果编译成功,运行它:
./test_basic
你应该能看到如下输出:
The value of 'my_key' is: Hello, redis-plus-plus!
'my_key' exists in Redis.
'my_key' has been deleted.
恭喜!你已经成功使用 redis-plus-plus 完成了与 Redis 的第一次交互。这个简单的例子涵盖了连接建立、基本的 SET/GET/EXISTS/DEL 命令,以及异常处理。
5. 核心功能深度解析与实战
掌握了基础连接和命令后,我们来深入探讨 redis-plus-plus 的一些核心特性和高级用法。这些是你在实际项目中必然会用到的。
5.1 连接管理与连接池
在上面的例子中,我们隐式地使用了连接池。 ConnectionPoolOptions 允许你精细控制连接行为。
pool_opts.size:连接池大小。这并非越大越好。设置过大会浪费服务器资源,过小则可能在并发高时成为瓶颈。一个经验值是设置为你的应用服务器线程数或稍多一点。对于我们的测试,3个足够了。pool_opts.wait_timeout:当连接池耗尽时,客户端等待一个可用连接的最长时间。默认是0ms(一直等待)。在生产环境中,建议设置一个合理的超时(如100ms),避免线程被无限期挂起。pool_opts.connection_lifetime:一个连接在池中的最长存活时间。超过这个时间,即使连接是好的,也会被关闭并创建新连接。这有助于缓解一些网络中间件(如代理)或 Redis 服务器端的连接空闲超时问题。可以设置为几分钟到几十分钟。
sw::redis::ConnectionPoolOptions pool_opts;
pool_opts.size = 5;
pool_opts.wait_timeout = std::chrono::milliseconds(100);
pool_opts.connection_lifetime = std::chrono::minutes(10);
注意事项 : Redis 对象是线程安全的吗?是的, sw::redis::Redis 对象是线程安全的,因为它内部通过连接池来管理连接。多个线程可以安全地调用同一个 Redis 对象的方法。但是, Pipeline 和 Transaction 对象不是线程安全的,它们应该在单个线程内创建和使用。
5.2 丰富的数据类型支持
redis-plus-plus 对 Redis 的各种数据类型提供了原生、类型安全的接口,用起来非常直观。
字符串 (String) :
redis.set("counter", "100");
redis.incr("counter"); // 自增,结果变为101
auto num = redis.get<long long>("counter"); // 明确获取为long long类型
哈希 (Hash) :
std::unordered_map<std::string, std::string> user = {{"name", "Alice"}, {"age", "30"}};
redis.hset("user:1000", user.begin(), user.end()); // 批量设置字段
auto name = redis.hget("user:1000", "name"); // 获取单个字段
std::unordered_map<std::string, std::string> all_fields;
redis.hgetall("user:1000", std::inserter(all_fields, all_fields.begin())); // 获取所有字段
列表 (List) :
redis.rpush("task_queue", "task1"); // 右侧推入
redis.rpush("task_queue", {"task2", "task3"}); // 批量推入
auto task = redis.lpop("task_queue"); // 左侧弹出,实现队列
集合 (Set) 与有序集合 (Sorted Set) :
redis.sadd("tags", {"cpp", "redis", "database"});
if (redis.sismember("tags", "cpp")) {
// ... 判断成员是否存在
}
redis.zadd("leaderboard", {{"player1", 100.5}, {"player2", 89.0}}); // 带分数添加
std::vector<std::pair<std::string, double>> top3;
redis.zrevrange("leaderboard", 0, 2, std::back_inserter(top3)); // 获取前三名
地理空间 (Geospatial) :
redis.geoadd("cities", {{13.361389, 38.115556, "Palermo"}, {15.087269, 37.502669, "Catania"}});
auto dist = redis.geodist("cities", "Palermo", "Catania", sw::redis::GeoUnit::KM); // 计算距离
5.3 管道 (Pipeline) 与事务 (Transaction)
这是提升性能的两个利器。
管道 (Pipeline) :将多个命令一次性发送给服务器,减少网络往返延迟 (RTT)。适用于需要连续执行多个不依赖中间结果的命令场景。
auto pipe = redis.pipeline(); // 创建一个管道对象
auto replies = pipe.set("key1", "val1")
.get("key2")
.incr("counter")
.exec(); // 一次性发送所有命令,返回一个回复数组
// replies 是一个 vector<ReplyUPtr>
// 你需要按照命令发送的顺序来解析回复
std::cout << "SET reply: " << replies[0]->str() << std::endl; // 通常是"OK"
if (replies[1]) {
std::cout << "GET reply: " << replies[1]->str() << std::endl;
}
事务 (Transaction) :通过 MULTI / EXEC 确保一系列命令的原子性执行。 redis-plus-plus 的接口让它用起来很像管道。
auto tx = redis.transaction(); // 创建一个事务对象
auto tx_replies = tx.set("tx_key1", "100")
.incr("tx_key1") // 在事务内,这个incr看到的是事务开始时的值吗?不,它看到的是事务队列中的命令顺序。
.get("tx_key1")
.exec();
// 事务内的命令要么全部成功,要么全部失败
// 注意:事务内命令的回复在 EXEC 前不会返回,EXEC 后返回一个数组。
long long final_val = tx_replies[2]->parse<long long>();
std::cout << "Value after transaction: " << final_val << std::endl; // 输出 101
重要区别 :管道是为了性能,不保证原子性;事务是为了原子性,但会消耗更多资源(因为需要等待 EXEC)。你可以将管道和事务结合使用:
auto tx = redis.transaction(true);这个true参数表示在事务中使用管道,能进一步提升事务内命令的网络效率。
5.4 发布订阅 (Pub/Sub)
redis-plus-plus 提供了同步和异步两种方式的发布订阅接口。这里展示同步接口,它更简单直观。
// 订阅者
sw::redis::Subscriber sub = redis.subscriber();
sub.on_message([](std::string channel, std::string msg) {
std::cout << "Received message from channel '" << channel << "': " << msg << std::endl;
});
sub.subscribe("news"); // 订阅频道
sub.subscribe("sports");
// 进入监听循环(通常在一个独立线程中运行)
// 这里为了示例,我们只监听一小段时间
sub.consume_for(std::chrono::seconds(10));
// 在另一个线程或进程中,发布者可以这样做:
redis.publish("news", "Breaking: C++23 is finalized!");
redis.publish("sports", "Game score: 5-3");
注意事项 :同步的 consume() 或 consume_for() 是阻塞调用。在实际应用中,你通常需要在一个专门的线程中运行订阅者的消费循环,以免阻塞主线程。 redis-plus-plus 也提供了基于 std::future 的异步接口,适合集成到事件驱动框架中。
6. 高级配置与生产环境考量
当你的应用从开发测试走向生产环境时,一些配置和最佳实践就显得尤为重要。
6.1 连接加密与认证
密码认证 :如果 Redis 服务器配置了密码(通过 requirepass 指令),你需要在连接选项中设置。
connection_opts.password = "your_strong_password_here"; // 设置密码
TLS/SSL 连接 :如果 Redis 服务器启用了 TLS(例如云数据库服务),你需要配置相关选项。这要求你在编译 redis-plus-plus 时启用了 OpenSSL 支持。
connection_opts.tls.enabled = true; // 启用 TLS
// connection_opts.tls.cacert = "/path/to/ca.crt"; // 如果需要验证服务器证书,指定CA证书路径
// connection_opts.tls.cert = "/path/to/client.crt"; // 如果需要客户端证书
// connection_opts.tls.key = "/path/to/client.key";
6.2 重连与高可用策略
网络是不稳定的。一个健壮的客户端必须具备自动重连能力。
connection_opts.connect_timeout = std::chrono::milliseconds(500); // 连接超时
connection_opts.socket_timeout = std::chrono::milliseconds(200); // 读写超时
// 连接池选项中的重试间隔(默认已有,可调整)
// pool_opts.connection_lifetime 和 pool_opts.wait_timeout 也间接影响连接健康度
redis-plus-plus 底层使用的 hiredis 在连接断开后,当下次执行命令时,会尝试自动重连。但是,在极端高并发下,瞬间大量重连可能对服务器造成压力。更高级的策略是结合 哨兵 (Sentinel) 或 集群 (Cluster) 模式。
6.3 使用 Redis 哨兵模式
对于高可用部署,Redis 哨兵模式是常见选择。 redis-plus-plus 提供了直接连接哨兵获取主节点地址的方式。
sw::redis::ConnectionOptions connection_opts;
connection_opts.type = sw::redis::ConnectionType::SENTINEL; // 指定为哨兵模式
connection_opts.host = "sentinel-host"; // 哨兵服务器地址
connection_opts.port = 26379; // 哨兵端口
connection_opts.password = "sentinel_password_if_any"; // 哨兵密码(如果有)
connection_opts.sentinel_master = "mymaster"; // 主服务器名称,需与哨兵配置一致
// 连接池选项同样适用
sw::redis::Redis redis(connection_opts, pool_opts);
这样创建的 Redis 对象会自动通过哨兵发现当前的主节点,并在主节点切换时自动更新连接。你无需在代码中关心主从切换的细节。
6.4 使用 Redis 集群模式
对于海量数据,Redis 集群是解决方案。 redis-plus-plus 有专门的 RedisCluster 类来处理集群连接。
sw::redis::ConnectionOptions cluster_connection_opts;
cluster_connection_opts.host = "cluster-node-host"; // 集群中任意一个节点地址
cluster_connection_opts.port = 6379;
sw::redis::ConnectionPoolOptions cluster_pool_opts;
cluster_pool_opts.size = 3;
// 创建集群客户端
sw::redis::RedisCluster redis_cluster(cluster_connection_opts, cluster_pool_opts);
// 使用方式与单机 Redis 几乎相同,库会自动处理 key 的槽位计算和路由。
redis_cluster.set("user:{1000}:name", "Alice"); // 注意,key中包含哈希标签{},用于确保相关key落在同一节点
使用集群时,要特别注意 key 的哈希标签 。对于需要跨多个 key 的操作(如事务、Lua脚本),这些 key 必须位于同一个集群节点上,通过 {...} 哈希标签可以控制这一点。
7. 常见问题排查与性能调优
即使一切配置正确,在实际运行中也可能遇到各种问题。这里记录一些我踩过的坑和解决方法。
7.1 编译与链接问题
问题1:编译时找不到 sw/redis++/redis++.h 头文件。
- 原因 :编译器在默认包含路径中找不到头文件。
make install将头文件装在了/usr/local/include下。 - 解决 :确保你的编译命令正确。如果使用 CMake,在
CMakeLists.txt中添加include_directories(/usr/local/include)和link_directories(/usr/local/lib),并使用target_link_libraries(your_target redis++ hiredis pthread)。
问题2:链接时找不到 libredis++.so 。
- 原因 :链接器路径问题或
ldconfig未更新。 - 解决 :
- 运行
sudo ldconfig更新缓存。 - 在编译命令中显式指定库路径:
-L/usr/local/lib -lredis++ -lhiredis。 - 检查库文件是否存在:
ls -la /usr/local/lib/libredis++.so*。
- 运行
问题3:运行时出现 GLIBCXX_3.4.29‘ not found 等动态链接错误。
- 原因 :编译
redis-plus-plus使用的 GCC 版本高于你运行环境中的版本。 - 解决 :在开发和生产环境尽量保持 GCC 版本一致。或者在较低版本的系统上,使用静态链接(编译
redis-plus-plus时加-DREDIS_PLUS_PLUS_BUILD_STATIC=ON,链接时使用-lredis++-static),但静态链接会增大二进制体积。
7.2 运行时连接与性能问题
问题1:连接超时或读写超时。
- 排查 :
- 检查 Redis 服务器是否运行:
redis-cli ping。 - 检查防火墙/安全组规则是否放行了
6379端口。 - 检查
connection_opts中的host、port是否正确。 - 适当增加
connect_timeout和socket_timeout的值,特别是在网络延迟较高的环境中。
- 检查 Redis 服务器是否运行:
- 注意 :超时设置太短会导致频繁超时失败,太长则会在网络故障时导致线程长时间阻塞。需要根据网络状况调整。
问题2: Broken pipe 或 Connection reset by peer 错误。
- 原因 :服务器端主动关闭了连接(可能由于空闲超时、重启或客户端异常)。
- 解决 :
redis-plus-plus的连接池本身具备一定的重连能力。确保设置了合理的pool_opts.connection_lifetime(短于服务器的timeout配置),让连接定期刷新。对于长时间空闲的连接,可以启用 TCP keepalive(需要在系统层面或 hiredis 底层配置,redis-plus-plus接口未直接暴露)。
问题3:在高并发下出现性能瓶颈或连接数过多。
- 调优 :
- 连接池大小 :
pool_opts.size不是越大越好。一个经验法则是设置为应用服务器工作线程数的 1-2 倍。可以通过监控 Redis 的connected_clients指标来调整。 - 使用管道 :对于批量操作,务必使用 Pipeline,能极大减少 RTT,提升吞吐量。
- 避免大 Key 和大 Value :Redis 是单线程的,操作一个大 Key(如包含百万成员的 Hash)会阻塞其他命令。设计数据结构时要进行拆分。
- 合理使用异步接口 :对于非即时响应的操作,可以考虑使用
redis-plus-plus的异步接口(返回std::future),避免阻塞调用线程。
- 连接池大小 :
7.3 内存与资源管理
问题:内存泄漏。
- 排查 :
redis-plus-plus本身经过良好测试,内存管理是可靠的。泄漏通常发生在使用方式上。 - 注意 :
- 确保
Pipeline和Transaction对象在合适的作用域内创建和销毁,不要长时间持有。 - 对于订阅模式,如果在一个长期运行的线程中使用
Subscriber,要确保在程序退出或不再需要时,正确调用sub.unsubscribe()并结束消费循环。 - 使用 Valgrind 等工具进行内存检查:
valgrind --leak-check=full ./your_redis_program。
- 确保
8. 集成到 CMake 项目的最佳实践
在真实的 C++ 项目中,我们很少直接用命令行 g++ 编译,而是使用 CMake 这样的构建系统。下面是一个完整的 CMakeLists.txt 示例,展示如何将 redis-plus-plus 集成到你的项目中。
cmake_minimum_required(VERSION 3.10)
project(MyRedisApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找 redis-plus-plus 库
find_package(redis++ REQUIRED)
# 查找 hiredis 库
find_package(hiredis REQUIRED)
# 如果你的系统安装路径非标准,可以手动指定路径
# include_directories(/usr/local/include)
# link_directories(/usr/local/lib)
add_executable(my_app main.cpp src/redis_client.cpp)
# 链接库
target_link_libraries(my_app
PRIVATE
redis++::redis++
hiredis::hiredis
pthread
)
# 或者,如果 find_package 失败,可以使用 pkg-config(需先安装 pkg-config)
# find_package(PkgConfig REQUIRED)
# pkg_check_modules(REDISPP REQUIRED IMPORTED_TARGET redis++)
# pkg_check_modules(HIREDIS REQUIRED IMPORTED_TARGET hiredis)
# target_link_libraries(my_app PRIVATE PkgConfig::REDISPP PkgConfig::HIREDIS pthread)
为了让 find_package 正常工作, redis-plus-plus 的安装需要生成 CMake 配置文件。幸运的是,我们之前通过 make install 安装的版本(1.3.0 之后)通常已经包含了这些文件,位于 /usr/local/lib/cmake/redis++/ 。如果 CMake 找不到,你可能需要检查该路径是否存在,或者将 CMAKE_PREFIX_PATH 设置为 /usr/local 。
最后,我想分享一个在微服务架构中使用 redis-plus-plus 的心得: 将 Redis 客户端封装成一个单例或依赖注入的服务 。这样可以在整个应用中统一管理连接池配置、重试逻辑和监控指标。例如,你可以创建一个 RedisService 类,在构造函数中初始化 sw::redis::Redis 或 sw::redis::RedisCluster 对象,并提供一系列业务相关的原子操作方法(如 getUserSession 、 cacheProductInfo )。这不仅能提高代码复用性,也使得后续切换 Redis 部署模式(单机->哨兵->集群)或进行 A/B 测试时,变更范围最小化。
更多推荐




所有评论(0)