好的,我们来深入探讨 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++ 的高效控制能力,你可以在需要高性能集合操作的场景中构建出强大的解决方案。务必根据实际业务需求和数据规模选择合适的操作和优化策略。
网硕互联帮助中心
![【完整源码+数据集+部署教程】快递盒检测检测系统源码 [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]-网硕互联帮助中心](https://www.wsisp.com/helps/wp-content/uploads/2026/02/20260202054924-69803ae457a04-220x150.jpg)



评论前必须登录!
注册