云计算百科
云计算领域专业知识百科平台

Redis SET与C++实战:高效集合操作

好的,我们来深入探讨 Redis 中的 SET 数据类型及其在 C++ 中的实战应用。Redis 的 SET 是一个无序的、元素唯一的集合,非常适合处理需要去重、成员关系判断或集合运算的场景。

1. Redis SET 核心特性回顾

  • 无序性 (Unordered): 元素存储顺序不固定。
  • 唯一性 (Unique): 每个元素在集合中只能出现一次。
  • 高效操作: 支持添加、删除、判断成员存在性、集合运算(交集、并集、差集)等操作,时间复杂度通常为 $O(1)$ 或 $O(N)$(N 为集合大小或参与运算的集合大小)。
  • 二进制安全: 元素可以是字符串(包括二进制数据)。
  • 最大成员数: $2^{32} – 1$(约 40 亿个)。

2. C++ 客户端库选择 (以 hiredis 为例)

hiredis 是 Redis 官方推荐的轻量级 C 客户端库。C++ 应用中可以直接使用,或者封装成更 C++ 风格的接口。这里我们主要使用 hiredis 的同步 API。

#include <hiredis/hiredis.h>
#include <iostream>
#include <vector>
#include <string>

// 简单封装一个连接类 (简化版,实际应用中需处理连接池、错误等)
class RedisClient {
public:
RedisClient(const char* host = "127.0.0.1", int port = 6379) {
context_ = redisConnect(host, port);
if (context_ == nullptr || context_->err) {
throw std::runtime_error("Redis connection error");
}
}
~RedisClient() {
redisFree(context_);
}
redisContext* context() { return context_; }
private:
redisContext* context_;
};

3. C++ 实战:SET 操作深度解析

3.1 基础操作 (SADD, SREM, SMEMBERS, SISMEMBER)

void basicSetOperations(RedisClient& client) {
redisContext* ctx = client.context();

// SADD: 向集合添加一个或多个成员
redisReply* reply = (redisReply*)redisCommand(ctx, "SADD myset member1 member2 member3");
if (reply == nullptr || reply->type == REDIS_REPLY_ERROR) {
std::cerr << "SADD error" << std::endl;
} else {
std::cout << "SADD added " << reply->integer << " members." << std::endl;
}
freeReplyObject(reply);

// SMEMBERS: 获取集合所有成员 (注意:大数据集慎用,可能阻塞)
reply = (redisReply*)redisCommand(ctx, "SMEMBERS myset");
if (reply && reply->type == REDIS_REPLY_ARRAY) {
std::cout << "Members of myset: ";
for (size_t i = 0; i < reply->elements; ++i) {
std::cout << reply->element[i]->str << " ";
}
std::cout << std::endl;
}
freeReplyObject(reply);

// SISMEMBER: 检查成员是否存在
reply = (redisReply*)redisCommand(ctx, "SISMEMBER myset member2");
if (reply && reply->type == REDIS_REPLY_INTEGER) {
std::cout << "member2 exists? " << (reply->integer == 1 ? "Yes" : "No") << std::endl;
}
freeReplyObject(reply);

// SREM: 移除一个或多个成员
reply = (redisReply*)redisCommand(ctx, "SREM myset member1");
if (reply) {
std::cout << "Removed " << reply->integer << " members." << std::endl;
}
freeReplyObject(reply);
}

3.2 集合运算 (SINTER, SUNION, SDIFF)

void setAlgebra(RedisClient& client) {
redisContext* ctx = client.context();

// 准备两个集合
redisCommand(ctx, "SADD setA a b c d");
redisCommand(ctx, "SADD setB c d e f");

// SINTER: 交集 (同时存在于 setA 和 setB 的元素)
redisReply* reply = (redisReply*)redisCommand(ctx, "SINTER setA setB");
if (reply && reply->type == REDIS_REPLY_ARRAY) {
std::cout << "Intersection (SINTER): ";
for (size_t i = 0; i < reply->elements; ++i) {
std::cout << reply->element[i]->str << " ";
}
std::cout << std::endl;
}
freeReplyObject(reply);

// SUNION: 并集 (存在于 setA 或 setB 或两者中的元素)
reply = (redisReply*)redisCommand(ctx, "SUNION setA setB");
// … 处理并集结果
freeReplyObject(reply);

// SDIFF: 差集 (存在于 setA 但不存在于 setB 的元素)
reply = (redisReply*)redisCommand(ctx, "SDIFF setA setB");
// … 处理差集结果
freeReplyObject(reply);
}

http://my.tv.sohu.com/us/442092364/698249292.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTI5Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249079.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTA3OS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249343.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249502.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTUwMi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249356.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM1Ni5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249358.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM1OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249516.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTUxNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249365.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM2NS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249432.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQzMi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249436.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249446.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQ0Ni5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249388.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM4OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249541.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU0MS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249544.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU0NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249638.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTYzOC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249704.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcwNC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249647.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTY0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249708.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcwOC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249712.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcxMi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249484.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQ4NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249723.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcyMy5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249574.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU3NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249577.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU3Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249580.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU4MC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249784.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTc4NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250017.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDAxNy5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250110.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDExMC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249878.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTg3OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250043.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250044.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA0NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250136.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDEzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250055.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA1NS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250143.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDE0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250062.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250067.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA2Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250204.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDIwNC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249998.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTk5OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250081.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA4MS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250160.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDE2MC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250091.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA5MS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250321.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDMyMS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250100.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDEwMC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250182.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDE4Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250236.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDIzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250337.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDMzNy5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250243.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDI0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250348.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDM0OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250506.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDUwNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250354.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDM1NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250256.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDI1Ni5zaHRtbA==.html  

3.3 高级技巧与优化
  • SSCAN 代替 SMEMBERS: 对于大型集合,使用 SMEMBERS 一次性获取所有成员可能导致服务器阻塞和客户端内存溢出。应使用 SSCAN 进行增量迭代。 void safeScanSet(RedisClient& client, const std::string& key) {
    redisContext* ctx = client.context();
    size_t cursor = 0;
    do {
    redisReply* reply = (redisReply*)redisCommand(ctx, "SSCAN %s %zu", key.c_str(), cursor);
    if (reply == nullptr || reply->type != REDIS_REPLY_ARRAY || reply->elements != 2) {
    // 错误处理
    break;
    }
    // 解析新的游标
    redisReply* cursor_reply = reply->element[0];
    cursor = std::stoul(cursor_reply->str);
    // 解析元素数组
    redisReply* elements_reply = reply->element[1];
    for (size_t i = 0; i < elements_reply->elements; ++i) {
    std::cout << elements_reply->element[i]->str << " ";
    }
    freeReplyObject(reply);
    } while (cursor != 0); // 游标为 0 表示迭代结束
    }

  • 原子性与事务 (MULTI/EXEC): 如果需要确保一系列 SET 操作的原子性(如添加成员后立即检查大小),可以使用 MULTI 开启事务,发送命令队列,然后用 EXEC 执行。
  • 管道 (Pipelining): 将多个命令一次性发送到服务器,减少网络往返次数,显著提升批量操作的性能。 void pipelineSetAdd(RedisClient& client, const std::string& key, const std::vector<std::string>& members) {
    redisContext* ctx = client.context();
    // 开启管道模式
    redisAppendCommand(ctx, "MULTI");
    for (const auto& member : members) {
    redisAppendCommand(ctx, "SADD %s %s", key.c_str(), member.c_str());
    }
    redisAppendCommand(ctx, "EXEC");

    // 发送并获取所有回复 (忽略中间回复,只关注 EXEC 的回复)
    redisReply* multiReply, *execReply;
    redisGetReply(ctx, (void**)&multiReply); // MULTI 的 OK
    freeReplyObject(multiReply);
    for (size_t i = 0; i < members.size(); ++i) {
    redisGetReply(ctx, (void**)&multiReply); // 每个 SADD 的 QUEUED
    freeReplyObject(multiReply);
    }
    redisGetReply(ctx, (void**)&execReply); // EXEC 的结果数组
    if (execReply && execReply->type == REDIS_REPLY_ARRAY) {
    // 处理每个 SADD 的结果 (execReply->elements == members.size())
    }
    freeReplyObject(execReply);
    }

  • SET 实现分布式锁 (简易版): 利用 SET 的 NX (不存在才设置) 和 PX (设置过期时间) 选项可以实现一个基础的分布式锁。 bool tryAcquireLock(RedisClient& client, const std::string& lockKey, const std::string& lockValue, int expireMs) {
    redisContext* ctx = client.context();
    // SET lockKey lockValue NX PX expireMs
    redisReply* reply = (redisReply*)redisCommand(ctx, "SET %s %s NX PX %d", lockKey.c_str(), lockValue.c_str(), expireMs);
    if (reply == nullptr || reply->type == REDIS_REPLY_ERROR) {
    freeReplyObject(reply);
    return false;
    }
    bool acquired = (reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0);
    freeReplyObject(reply);
    return acquired;
    }
    // 释放锁 (需确保释放的是自己持有的锁,通常用 Lua 脚本保证原子性)

    http://my.tv.sohu.com/us/442092364/698249292.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTI5Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249079.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTA3OS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249343.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249502.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTUwMi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249356.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM1Ni5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249358.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM1OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249516.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTUxNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249365.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM2NS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249432.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQzMi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249436.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249446.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQ0Ni5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249388.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTM4OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249541.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU0MS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249544.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU0NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249638.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTYzOC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249704.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcwNC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249647.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTY0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249708.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcwOC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249712.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcxMi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249484.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTQ4NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249723.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTcyMy5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249574.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU3NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249577.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU3Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249580.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTU4MC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249784.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTc4NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250017.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDAxNy5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250110.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDExMC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249878.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTg3OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250043.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250044.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA0NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250136.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDEzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250055.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA1NS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250143.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDE0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250062.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250067.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA2Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250204.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDIwNC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698249998.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI0OTk5OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250081.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA4MS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250160.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDE2MC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250091.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDA5MS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250321.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDMyMS5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250100.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDEwMC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250182.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDE4Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250236.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDIzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250337.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDMzNy5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250243.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDI0My5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250348.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDM0OC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250506.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDUwNi5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250354.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDM1NC5zaHRtbA==.html http://my.tv.sohu.com/us/442092364/698250256.shtml https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5ODI1MDI1Ni5zaHRtbA==.html  

    注意:生产环境分布式锁需考虑更复杂的场景(如锁续期、安全释放),建议使用 Redlock 算法或成熟库。

4. 典型应用场景

  • 用户标签/兴趣: 每个用户的标签存储在一个 SET 中。可以方便地进行标签添加、删除、判断用户是否有某标签 (SISMEMBER),计算共同兴趣 (SINTER)。
  • 社交关系: 存储用户的关注列表 (SET)、粉丝列表 (SET)。计算共同关注 (SINTER),可能认识的人 (SDIFF/SUNION 结合)。
  • 抽奖/唯一参与: 记录已参与活动的用户 ID (SET),确保用户不重复参与 (SADD 的返回值判断)。
  • 数据去重 (初级): 记录已处理过的数据 ID (SET),避免重复处理。注意内存消耗,超大集合需谨慎。
  • 权限/白名单: 存储拥有某项权限的用户或 IP (SET),快速检查 (SISMEMBER)。

5. 注意事项

  • 内存消耗: SET 采用哈希表或整数集合编码。成员较多且不是整数时,内存占用可能较大。需监控 info memory。
  • 大 Key 问题: 包含数百万成员的 SET 会影响操作性能(如 SINTER、SMEMBERS)和持久化效率。考虑拆分、使用 SSCAN 或迁移到更适合的结构。
  • 网络开销: C++ 应用与 Redis 的通信存在网络延迟。批量操作 (Pipeline) 和合理的数据结构设计至关重要。
  • 客户端选择: hiredis 是基础,也可考虑更高级的 C++ 封装库(如 cpp_redis),它们可能提供更友好的异步接口、连接池管理。
  • 线程安全: redisContext 不是线程安全的。在多线程环境中,应为每个线程创建独立连接或使用连接池。

通过结合 Redis SET 的强大功能和 C++ 的高效控制能力,你可以在需要高性能集合操作的场景中构建出强大的解决方案。务必根据实际业务需求和数据规模选择合适的操作和优化策略。

赞(0)
未经允许不得转载:网硕互联帮助中心 » Redis SET与C++实战:高效集合操作
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!