activity-redis
SKILL.md
活动Redis存储开发指南
帮助你使用活动框架的 Redis 存储系统设计数据结构、管理状态和实现排行榜等功能。
🤖 AI 执行指令
当用户调用此 skill 时,根据需求提供 Redis 存储相关的指导和代码示例。
使用场景判断
- 设计数据结构 → 提供数据类型选型建议和键命名方案
- 使用客户端 → 提供 actredis 工厂方法和操作示例
- 实现排行榜 → 提供 Sorted Set + 时间加权方案
- 处理并发 → 提供分布式锁和 Pipeline 用法
存储层架构
actstore (高层抽象,直接操作)
↓
actredis (客户端框架,按活动绑定)
↓
db.ActiveRedis (底层 Redis 连接池)
actredis 客户端工厂
按活动 ID 创建带自动功能的客户端:
client := actredis.GetActHash(actId, "user_data", "用户数据")
// 自动添加 actId 前缀
// 自动设置活动结束时过期
// 自动指标追踪
支持的数据类型
| 工厂方法 | Redis类型 | 典型用途 |
|---|---|---|
GetActString |
String | 计数器、简单值 |
GetActHash |
Hash | 用户状态、多字段数据 |
GetActList |
List | 操作日志、历史记录 |
GetActSet |
Set | 去重集合 |
GetActZSet |
Sorted Set | 排行榜 |
GetActBitMap |
Bitmap | 布尔标记 |
GetActPipeLine |
Pipeline | 批量操作 |
键命名规范
act:{actId}:{module}:{entity}:{uid}:{suffix}
示例
| 键 | 用途 |
|---|---|
act:1001:farm:daily_chips:123:20250227 |
用户每日碎片 |
act:1001:sign:state:789 |
签到状态 |
act:1001:rank:score:789 |
排名分数 |
act_chan:topic:send_gift |
事件队列 |
act_chan:defer_queue:act:1001:task |
延迟任务 |
版本化 Key
新一期活动通过更新版本号实现数据隔离,避免手动清理旧数据:
key := actinfo.WrapKeyWithVersion("act:1001:farm:data")
// 输出: "act:1001:farm:data:v2" (版本号来自活动配置)
TTL 管理
| 周期类型 | 默认TTL | 说明 |
|---|---|---|
| 活动周期 (Total) | 15 天 | 活动结束后保留 |
| 每日 (Daily) | 3 天 | 日重置数据 |
| 每周 (Weekly) | 3 周 | 周重置数据 |
| 每月 (Monthly) | 3 个月 | 月重置数据 |
| 每小时 (Hourly) | 3 小时 | 小时重置数据 |
actredis 客户端会自动根据活动结束时间设置 TTL。
常用数据结构选型
| Redis 类型 | 典型用途 | 示例场景 |
|---|---|---|
| Hash | 用户状态/统计 | 签到记录、任务进度、属性值 |
| String/Int | 计数器 | 每日次数、累计消费 |
| List | 操作日志 | 交易记录、操作历史 |
| Set | 去重集合 | 已参与用户、已领取奖励 |
| Sorted Set | 排行榜 | 用户分数排名(支持时间加权) |
| Bitmap | 布尔标记 | 每日登录、任务完成标记 |
时间加权排名
同分时先达到的用户排名更靠前:
score := actredis.GetTimeScoreByActId(actId, rawScore)
// 将原始分数与时间戳结合,确保同分先到先排前
分布式锁
防止并发操作导致数据不一致:
result := actutil.TryLockUidOnce(actId, uid)
if !result.Success {
return error // 获取锁失败,拒绝操作
}
defer result.Unlock() // 确保释放锁
// 安全地执行并发敏感操作
使用场景
- 保底逻辑(必须加锁防止并发触发)
- 奖励领取(防止重复领取)
- 购买操作(防止超卖)
Pipeline 批量操作
减少网络往返,提高性能:
pipe := actredis.GetActPipeLine(actId)
pipe.HIncrBy(key1, field1, 1)
pipe.ZAdd(key2, score, member)
results, err := pipe.Exec()
使用场景
- 一次性读取多个用户数据
- 批量更新多个 Redis key
- 事件处理中的多步骤写入
典型使用场景
场景 1:设计活动数据结构
/activity-redis 我要做一个签到活动,帮我设计Redis数据结构
我会提供键命名方案、数据类型选择和操作代码。
场景 2:实现排行榜
/activity-redis 怎么实现一个消费排行榜?同分先到先排前
我会提供 Sorted Set + 时间加权的完整实现。
场景 3:处理并发问题
/activity-redis 保底逻辑怎么防止并发触发?
我会提供分布式锁的使用方法和注意事项。