文章标题:游戏周周乐幸运码生成系统的创新探究
文章内容:作者: vivo 互联网服务器团队- Zhang Jing
本文以游戏周周乐的幸运码为切入点,针对其生成过程中涉及的随机性、唯一性及高并发等特点,设计了一种基于号段+子码的创新架构。该方案不仅在生成速度上表现突出,还显著提升了存储效率,同时降低了扩容成本,为类似的号码生成系统提供了设计上的新思路和启发。
一、业务背景
用户能够通过达成相关任务来获取周周乐的幸运码,幸运码有着这样的投放规则:
- 基础投放量:每一期会有100万注独一无二且不重复的6位数字幸运码投放。
- 动态扩容机制:当参与人数超过预期时,能够实时追加100万注幸运码。
二、幸运码特性
依据背景情况,幸运码需具备以下特性:
- 随机性:发给每个用户的幸运码都是随机产生的,而且同一个用户获取的多个幸运码也是随机生成的。
- 唯一性:每一组的幸运码中,各个幸运码都是独一无二的。
- 范围性:幸运码被严格限制在000000到999999这个区间内。
- 高并发:幸运码的生成与发放需要支持高并发,至少要达到300QPS。
- 可追加:在当期活动非常火爆时,能够临时追加一组幸运码库存。
三、方案选型
由于幸运码严格限定在6位数字范围(000000 - 999999),传统的雪花算法因为生成超长ID(64位二进制)且依赖时间戳递增特性,不太能直接适用。接下来会对比三种方案:实时随机生成模式、预生成库存模式以及号段+子码模式,会依据生成速度、存储效率、扩容成本这三个核心指标进行系统评估,从而选出最优的解决方案。
3.1 方案一:实时随机生成模式
实现逻辑
- 生成随机数。
- 查询数据库看是否存在该随机数。
- 若不存在则将其存入数据库,完成幸运码发放;若存在则重新执行第一步。
缺陷分析
- 随着库存的消耗,碰撞概率会不断上升。
- 数据库IO压力会随着并发量线性增长。
- 不满足高并发场景的性能要求。
3.2 方案二:预生成库存模式
实现逻辑
采用预先生成幸运码的方式:离线生成100万个幸运码,把它们随机打乱后写入数据库,每个幸运码对应一个从1开始自增的序列号,并且用Redis记录幸运码序列号的索引,初始值设为1。
发放步骤
- 从Redis查询幸运码序列号索引。
- 利用该索引查询幸运码并完成发放。
- 递增Redis的序列号索引,保证序列号索引关联的是下一个可发放的幸运码。
缺陷分析
- 存储空间浪费:未发放的号码会占用存储。
- 扩容效率低下:追加库存需要重新预生成。
3.3 方案三:号段+子码模式
采用号段+子码机制:
- 号段管理:把10^6个号码划分成1000个号段(号段值为0 - 999)。
- 子码管理:每个号段维护1000个可用子码(子码值为0 - 999)。
- 生成规则:幸运码 = 随机号段1000 + 随机子码(例如:129358 = 1291000 + 358)。
3.4 方案对比
综合幸运码生成速度、存储效率、扩容成本等指标,最终采用了号段+子码模式来生成幸运码。
四、关键技术实现
4.1 号段分层机制
把100万注幸运码划分成1000个号段(每段1000注),每个号段由两部分组成:
- 号段ID:号段ID是唯一不重复的整数,范围在0到999之间。
- 子码串:是1000位字符串,用“01”标记使用状态,0表示未使用,1表示已使用,初始全为0。
幸运码生成公式为:幸运码 = 号段ID * 1000 + 子码位置。此设计既保留了生成幸运码的随机性(号段ID随机+子码随机),又通过子码的类比特位存储方式提高了存储效率。
4.2 分布式并发控制
4.2.1 多级缓存策略
Redis存储可用号段集合,要是号段的子码用完了,该号段就会从Redis集合中剔除,同时本地缓存会预加载可用号段,保证发码时能更高效地获取候选号段。
4.2.2 高效锁抢占策略
系统给每个号段分配分布式锁,发码时从本地缓存随机获取15个候选号段,遍历获取号段时把等待锁的超时时间设为30ms,确保号段被占用时能快速遍历到下一个号段(根据实际场景统计,等待锁的情况很少,一般最多遍历到第二个号段就能成功抢占)。一旦成功获取号段的分布式锁,就随机获取该号段下的可用子码。
4.2.3 动态库存策略
追加库存时,只需要创建一组新的幸运码号段并写入Redis,后续发放时获取该组的可用号段生成幸运码,从性能和存储空间上比预生成方式好很多。
4.3 幸运码发放
发放步骤
- 随机获取至多15个可用号段。
- 遍历号段。
- 抢占号段的分布式锁。
- 若号段的分布式锁抢占成功,就随机获取号段中可用的子码,再根据号段和子码生成幸运码。
- 若号段的分布式锁抢占失败,就遍历下一个号段,重复上述步骤。
五、总结
(1)双重随机保障
- 一级随机:号段选择随机(0 - 999)。
- 二级随机:子码选择随机(0 - 999)。
通过号段随机和子码随机的方式保证生成的幸运码完全随机。
(2)数据唯一性
通过号段唯一和号段内的子码唯一保证生成的幸运码全局唯一。
(3)弹性扩展能力
扩容耗时只需秒级别,存储空间相比预生成方案节省80%。
(4)高性能发放
通过多重缓存及高效号段抢占策略大幅提高幸运码生成效率,实测QPS>300,平均响应时间<15ms。
本设计方案通过创新的号段+子码管理机制,在保证号码随机性和唯一性的同时,实现了高并发场景下的稳定服务能力,为类似号码生成系统的设计提供了可复用的架构范式。
文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/13053.html