一、当集合遇见Redis
Redis作为高性能内存数据库,其Set(集合)数据类型凭借天然去重、高效交集运算等特性,在标签系统、共同好友等场景大放异彩。而StackExchange.Redis作为.NET生态最成熟的Redis客户端,其优雅的API设计让操作集合如虎添翼。今天我们就通过真实代码示例,手把手教你玩转这套组合拳!
二、环境搭建速成指南
1. 必要装备清单
# NuGet安装命令(技术栈:StackExchange.Redis 2.6.90)
Install-Package StackExchange.Redis
2. 连接初始化
using StackExchange.Redis;
using System.Text.Json;
// 创建单例连接(生产环境建议使用连接池)
var conn = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase redisDb = conn.GetDatabase();
三、集合操作
1. 基础招式:增删改查
// 添加元素到集合(支持批量操作)
redisDb.SetAdd("user:1001:tags", new RedisValue[] { "C#", "Redis", "Dotnet" });
// 删除指定元素
bool isDeleted = redisDb.SetRemove("user:1001:tags", "Java");
// 获取所有成员(注意:结果无序!)
RedisValue[] allTags = redisDb.SetMembers("user:1001:tags");
Console.WriteLine($"用户标签:{string.Join(",", allTags)}");
// 判断元素是否存在
bool exists = redisDb.SetContains("user:1001:tags", "Redis");
2. 高阶心法:集合运算
// 计算并集(多个集合合并)
RedisKey[] groupKeys = { "group:A:members", "group:B:members" };
redisDb.SetCombineAndStore(SetOperation.Union, "total_members", groupKeys);
// 获取交集(共同好友场景)
RedisValue[] commonFriends = redisDb.SetCombine(
SetOperation.Intersect,
new RedisKey[] { "user:1001:friends", "user:1002:friends" }
);
// 差集运算(A有B无的元素)
var uniqueElements = redisDb.SetCombine(
SetOperation.Difference,
new RedisKey[] { "product:2023:views", "product:2024:views" }
);
3. 实用技巧:随机与计数
// 获取随机元素(抽奖场景)
RedisValue luckyMember = redisDb.SetRandomMember("activity:lucky_draw");
// 获取集合基数(元素总数)
long totalCount = redisDb.SetLength("daily_active_users");
// 弹出随机元素(破坏性读取)
RedisValue poppedItem = redisDb.SetPop("pending_tasks");
四、典型业务场景剖析
场景1:电商商品标签系统
// 给商品打标签
redisDb.SetAdd("product:888:tags", "手机");
redisDb.SetAdd("product:888:tags", "5G");
// 通过标签筛选商品
var phoneProducts = redisDb.SetMembers("tag:手机:products");
场景2:社交共同好友
// 存储用户好友关系
redisDb.SetAdd("user:1001:friends", new[] { 2001, 2003, 2005 });
redisDb.SetAdd("user:1002:friends", new[] { 2003, 2005, 2007 });
// 获取共同好友(高性能计算)
var common = redisDb.SetCombine(SetOperation.Intersect,
new RedisKey[] { "user:1001:friends", "user:1002:friends" });
五、技术选型双刃剑
优势亮点:
- 毫秒级集合运算(10万级数据求交集仅需3ms)
- 自动去重节省存储空间
- 原子操作保证数据一致性
- 原生支持分布式集群
潜在短板:
- 无序存储不适合需要顺序的场景
- 超大集合(百万级)性能下降明显
- 不支持二级索引查询
六、避坑指南与最佳实践
- 元素序列化陷阱:
// 错误示范:直接存储对象
var user = new User{Id=1001};
redisDb.SetAdd("users", user); // 导致存储类型错误!
// 正确做法:序列化为字符串
redisDb.SetAdd("users", JsonSerializer.Serialize(user));
- 连接管理三不要:
- 不要频繁创建/销毁连接
- 不要忘记配置AbortOnConnectFail
- 不要在多线程中共享ConnectionMultiplexer实例
- 性能优化技巧:
- 批量操作使用RedisValue[]代替循环
- 定期清理过期集合
- 对超大集合采用分片策略(例:user:1001:tags:shard1)
七、总结与展望
通过本文的实战演练,我们掌握了使用StackExchange.Redis操作Redis集合的核心技巧。这种组合在需要快速去重、关系运算的场景表现卓越,但在面对复杂查询时仍需配合其他数据结构。随着RedisJSON等模块的普及,集合类型与其他数据结构的配合使用将成为新的探索方向。