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 验证安装与系统配置

安装完成后,我们需要让系统知道新库的位置。

  1. 更新动态链接库缓存 :运行以下命令,让系统载入 /usr/local/lib 下的新库。

    sudo ldconfig
    
  2. 验证头文件和库 :你可以快速检查一下文件是否存在。

    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 未更新。
  • 解决
    1. 运行 sudo ldconfig 更新缓存。
    2. 在编译命令中显式指定库路径: -L/usr/local/lib -lredis++ -lhiredis
    3. 检查库文件是否存在: 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:连接超时或读写超时。

  • 排查
    1. 检查 Redis 服务器是否运行: redis-cli ping
    2. 检查防火墙/安全组规则是否放行了 6379 端口。
    3. 检查 connection_opts 中的 host port 是否正确。
    4. 适当增加 connect_timeout socket_timeout 的值,特别是在网络延迟较高的环境中。
  • 注意 :超时设置太短会导致频繁超时失败,太长则会在网络故障时导致线程长时间阻塞。需要根据网络状况调整。

问题2: Broken pipe Connection reset by peer 错误。

  • 原因 :服务器端主动关闭了连接(可能由于空闲超时、重启或客户端异常)。
  • 解决 redis-plus-plus 的连接池本身具备一定的重连能力。确保设置了合理的 pool_opts.connection_lifetime (短于服务器的 timeout 配置),让连接定期刷新。对于长时间空闲的连接,可以启用 TCP keepalive(需要在系统层面或 hiredis 底层配置, redis-plus-plus 接口未直接暴露)。

问题3:在高并发下出现性能瓶颈或连接数过多。

  • 调优
    1. 连接池大小 pool_opts.size 不是越大越好。一个经验法则是设置为应用服务器工作线程数的 1-2 倍。可以通过监控 Redis 的 connected_clients 指标来调整。
    2. 使用管道 :对于批量操作,务必使用 Pipeline,能极大减少 RTT,提升吞吐量。
    3. 避免大 Key 和大 Value :Redis 是单线程的,操作一个大 Key(如包含百万成员的 Hash)会阻塞其他命令。设计数据结构时要进行拆分。
    4. 合理使用异步接口 :对于非即时响应的操作,可以考虑使用 redis-plus-plus 的异步接口(返回 std::future ),避免阻塞调用线程。

7.3 内存与资源管理

问题:内存泄漏。

  • 排查 redis-plus-plus 本身经过良好测试,内存管理是可靠的。泄漏通常发生在使用方式上。
  • 注意
    1. 确保 Pipeline Transaction 对象在合适的作用域内创建和销毁,不要长时间持有。
    2. 对于订阅模式,如果在一个长期运行的线程中使用 Subscriber ,要确保在程序退出或不再需要时,正确调用 sub.unsubscribe() 并结束消费循环。
    3. 使用 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 测试时,变更范围最小化。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐