news 2026/9/13 6:09:00

Redis 解锁:C++ 实战深度探索 Set 数据类型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis 解锁:C++ 实战深度探索 Set 数据类型

你的标题是“Redis 解锁:C++ 实战深度探索 Set 数据类型”,看起来像是想深入探讨 Redis 的Set数据类型在 C++ 中的实战用法,同时可能把“解锁”理解为“解锁分布式锁”的意思(因为 Redis 分布式锁和 SET 命令关系非常密切),或者单纯想全面掌握 Set 类型。

下面我把两个方向都给你讲清楚,并重点用redis-plus-plus(目前最流行的 C++ Redis 客户端)来写实战代码。

1. Redis Set 数据类型核心特性与典型用法

Redis 的 Set 是无序、不重复的字符串集合,底层实现有两种:

  • intset(小集合 + 全是整数时)
  • hashtable(ziplist 编码已废弃,新版用 dict)

常用命令(时间复杂度几乎都是 O(1) 或 O(N) 很小):

命令作用时间复杂度示例
SADD添加一个或多个元素O(1)SADD myset “apple” “banana”
SREM删除元素O(1)SREM myset “apple”
SISMEMBER判断元素是否存在O(1)SISMEMBER myset “apple”
SCARD获取集合元素个数O(1)SCARD myset
SMEMBERS获取所有元素O(N)SMEMBERS myset
SRANDMEMBER随机返回一个/多个元素O(1) / O(N)SRANDMEMBER myset 3
SPOP随机弹出并删除元素O(1)SPOP myset
SUNION并集O(N)SUNION set1 set2
SINTER交集O(N)SINTER set1 set2
SDIFF差集O(N)SDIFF set1 set2

典型业务场景

  • 抽奖系统(随机抽取用户)
  • 标签系统(用户打标签,去重)
  • 共同好友、共同关注
  • 访问用户去重(UV 统计)
  • 黑名单 / 白名单
  • 秒杀商品库存校验(但更常用 string 或 lua)

2. C++ 中使用 redis-plus-plus 操作 Set(推荐方式)

先安装 redis-plus-plus(基于 hiredis,线程安全,支持连接池)

# 假设你用 vcpkg 或自己编译vcpkginstallredis-plus-plus

基本连接与 Set 操作示例

#include<sw/redis++/redis++.h>#include<iostream>#include<vector>#include<string>usingnamespacesw::redis;intmain(){try{// 单节点连接(推荐使用连接池)ConnectionOptions opts;opts.host="127.0.0.1";opts.port=6379;// opts.password = "yourpass"; // 如有密码// 连接池(生产推荐)ConnectionPoolOptions pool_opts;pool_opts.size=16;// 连接数pool_opts.wait_timeout=std::chrono::milliseconds(100);pool_opts.connection_timeout=std::chrono::seconds(5);autoredis=Redis(RedisURI("tcp://127.0.0.1:6379"),pool_opts);// --------------------- Set 操作 ---------------------std::string key="myset:fruits";// 清空测试数据(慎用生产环境)redis.del(key);// SADD 添加元素(支持批量)longlongcnt=redis.sadd(key,{"apple","banana","orange","apple"});// apple 只加一次std::cout<<"Added "<<cnt<<" unique elements\n";// 输出 3// SISMEMBER 判断存在if(redis.sismember(key,"banana")){std::cout<<"banana exists\n";}// SCARD 元素个数std::cout<<"Size: "<<*redis.scard(key)<<"\n";// 3// SMEMBERS 获取全部(小心大集合)std::vector<std::string>members;redis.smembers(key,std::back_inserter(members));std::cout<<"All members: ";for(constauto&m:members)std::cout<<m<<" ";std::cout<<"\n";// SRANDMEMBER 随机取(不删除)autorand_one=redis.srandmember(key);if(rand_one)std::cout<<"Random: "<<*rand_one<<"\n";// SPOP 随机弹出并删除autopopped=redis.spop(key);if(popped)std::cout<<"Popped: "<<*popped<<"\n";// SREM 删除redis.srem(key,"orange");// 集合运算示例redis.sadd("set:a",{"1","2","3","4"});redis.sadd("set:b",{"3","4","5","6"});std::vector<std::string>inter;redis.sinter({"set:a","set:b"},std::back_inserter(inter));std::cout<<"Intersection: ";for(auto&v:inter)std::cout<<v<<" ";// 3 4std::cout<<"\n";}catch(constError&e){std::cerr<<"Redis error: "<<e.what()<<std::endl;return1;}return0;}

3. Redis 分布式锁才是“解锁”最经典的场景(SET + NX + PX)

Redis 官方推荐的单节点分布式锁就是用SET命令(不是 Set 类型,而是 String 类型):

SET lock:order:12345 "uuid-xxx-clientA" NX PX 30000
  • NX:不存在才设置(加锁)
  • PX:毫秒级过期(防死锁)
  • value 必须唯一(通常是 UUID + 客户端标识)

C++ 实现简单版分布式锁(非 Redlock)

#include<sw/redis++/redis++.h>#include<string>#include<random>#include<chrono>#include<thread>classSimpleRedisLock{private:Redis&_redis;std::string _lock_key;std::string _lock_value;std::chrono::milliseconds _expire_ms;public:SimpleRedisLock(Redis&r,conststd::string&key,intexpire_seconds=30):_redis(r),_lock_key(key),_expire_ms(std::chrono::seconds(expire_seconds)){}booltry_lock(){// 生成唯一 value(简单示例,可用 uuid 库)std::random_device rd;std::mt19937gen(rd());std::uniform_int_distribution<>dis(10000000,99999999);_lock_value="client-"+std::to_string(dis(gen));autoreply=_redis.set(_lock_key,_lock_value,std::chrono::duration_cast<std::chrono::milliseconds>(_expire_ms),UpdateType::ONLY_IF_NOT_EXIST);// 等价 NXreturnreply&&*reply;// true 表示加锁成功}boolunlock(){// 安全解锁:用 Lua 脚本保证原子性staticconstchar*lua_script=R"( if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end )";autores=_redis.eval<longlong>(lua_script,{_lock_key},{_lock_value});returnres&&*res==1;}~SimpleRedisLock(){unlock();// 析构自动尝试释放(视业务可去掉)}};// 使用示例voidprocess_order(Redis&redis){SimpleRedisLocklock(redis,"lock:order:12345",30);if(!lock.try_lock()){std::cout<<"获取锁失败\n";return;}std::cout<<"获得锁,开始处理订单...\n";std::this_thread::sleep_for(std::chrono::seconds(5));// 模拟业务lock.unlock();std::cout<<"订单处理完成,已释放锁\n";}

更安全的做法

  • 用 redis-plus-plus 自带的Redlock(多节点)
  • 或引入Redisson的思想,用更完善的续期机制(watchdog)
// redis-plus-plus 内置 Redlock 用法(需多个 master 节点)autoredlock=Redlock({node1,node2,node3,node4,node5});if(redlock.lock("my-resource",std::chrono::seconds(30))){// 业务redlock.unlock();}

总结对比

需求推荐数据类型核心命令C++ 库支持度
去重、标签、抽奖SetSADD / SPOP / SRANDMEMBER非常好
分布式锁(单节点)StringSET NX PX优秀
高可用分布式锁StringRedlock 算法redis++ 支持
排行榜Sorted SetZADD / ZRANGE-

如果你真正想问的是Set 类型的深度实战,还是分布式锁的 C++ 实现,可以再补充具体场景,我可以继续给你更细致的代码或优化方案(Lua 续期、Redlock 完整实现、 fencing token 等)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 0:18:51

从文本到语音:Fish Speech 1.5在内容创作中的应用案例

从文本到语音&#xff1a;Fish Speech 1.5在内容创作中的应用案例 1. 为什么内容创作者需要关注Fish Speech 1.5&#xff1f; 你是否遇到过这些场景&#xff1a; 为短视频配旁白&#xff0c;反复录音十几遍仍不满意&#xff1b;制作双语课程&#xff0c;找配音员成本高、周期…

作者头像 李华
网站建设 2026/8/22 9:02:45

腾讯混元模型部署避坑:vllm启动常见问题解决方案

腾讯混元模型部署避坑&#xff1a;vllm启动常见问题解决方案 本文聚焦Hunyuan-MT-7B镜像在vLLMOpen WebUI组合下的实际部署过程&#xff0c;不讲原理、不堆参数&#xff0c;只说你启动时真正会卡住的5个关键问题和对应解法 1. 启动失败第一关&#xff1a;显存报错“CUDA out of…

作者头像 李华
网站建设 2026/9/6 0:22:04

DeepSeek-OCR-2小白入门:3步完成文档结构化提取

DeepSeek-OCR-2小白入门&#xff1a;3步完成文档结构化提取 你是不是也经历过这样的尴尬&#xff1f;手头有一叠纸质合同、扫描版标书、PDF版财报&#xff0c;想把里面的关键信息——比如标题层级、段落逻辑、表格数据——原样搬到Word或Notion里&#xff0c;结果用传统OCR一扫…

作者头像 李华
网站建设 2026/9/3 6:35:03

Z-Image-Turbo实测:6B小模型竟有如此惊人的绘画细节

Z-Image-Turbo实测&#xff1a;6B小模型竟有如此惊人的绘画细节 最近在测试各种开源文生图模型时&#xff0c;一个名为“Z-Image-Turbo”的6B参数小模型引起了我的注意。说实话&#xff0c;一开始我对它没抱太大期望——毕竟现在动辄几十亿、上百亿参数的大模型才是主流&#…

作者头像 李华
网站建设 2026/9/9 14:56:01

Magma多模态智能体在企业中的落地实践:金融行业案例

Magma多模态智能体在企业中的落地实践&#xff1a;金融行业案例 1. 引言 在金融行业数字化转型的浪潮中&#xff0c;人工智能技术正以前所未有的速度重塑业务模式和服务体验。传统金融机构面临着海量数据处理、风险管控、客户服务等多重挑战&#xff0c;而多模态AI智能体的出…

作者头像 李华
网站建设 2026/9/13 2:14:00

Ollama+translategemma-12b-it:轻量级翻译模型部署实录

Ollamatranslategemma-12b-it&#xff1a;轻量级翻译模型部署实录 1. 引言&#xff1a;为什么选择轻量级翻译模型&#xff1f; 在日常工作和学习中&#xff0c;我们经常需要处理多语言内容。无论是阅读外文资料、与海外客户沟通&#xff0c;还是处理国际化业务&#xff0c;一…

作者头像 李华