写点什么

千万用户 3 毫秒内抽奖 100 名如何实现?

作者:知识浅谈
  • 2022 年 8 月 21 日
    吉林
  • 本文字数:897 字

    阅读完需:约 3 分钟

千万用户3毫秒内抽奖100名如何实现?

🍁 作者:知识浅谈,CSDN 签约讲师,CSDN 博客专家,华为云云享专家,阿里云专家博主

📌 擅长领域:全栈工程师、爬虫、ACM 算法

💒 公众号:知识浅谈

🔥 联系方式 vx:zsqtcc


🤞千万用户 3 毫秒内抽奖 100 名如何实现?🤞


正菜来了⛳⛳⛳

🎈场景再现

某 618 活动,零点的时候从关注的用户中抽出 100 个人进行超级某东 e 卡发放,预计全网超过 1000 万用户参加关注抽奖活动,要求 "同一用户不能重复参与,同一用户不允许二次开奖",为了满足要求,请给出解决方案。

🎈解决方案

🍮原始实现方法

- rand() 随机产生一个随机数select * from 关注用户表 order by rand() desc limit,0,100
复制代码


预计千万级别的对技术倒排大概率凉凉。

🍮执行 100 次下边的 sql

效率可以,不过要执行两次 SQL,并发环境下有原子性问题,切不能保证不会重复中奖


offset = SELECT FLOOR(RAND() * COUNT(*)) AS offset from 关注用户表select * from 关注用户表 limit offset,1
复制代码

🍮基于 Redis Set 集合做随机弹出

📐第 1 步:在用户关注直播间在写入 MySQL 关注用户表时额外在 Redis:增加一个 userlist Set 集合,存储用户编号。Redis Seti 可以保证全局唯一,且数据基于 Hash 乱序存储,取出的直接就是随机值。


sadd userlist xxxid
复制代码


预计用户编号长整型,1000 万用户占用空间大概 500MB。100 万 50mb, 1000 万 500MB,不会对内存造成很大压力(redis 虽然怕大 key,但是在内存可控范围内,小 key 很多却不会有什么问题)



📐第 2 步:抽奖的时候,直接使用 spop 弹出随机 100 个用户编号即可,这个操作是原子性的,先弹出再返回,在加上 Redist 命令队列单线程不存在并发问题,这样杜绝了重复获奖的可能。



📐第 3 步:下一步执行 1 次 select ini 语句,提取数据,因为都是通过主键提取,效率快也不存在 in 索引失效问题,但要注意 in 的数量上限是 1000 个,超过 1000 个备选项要拆成多个 in.

🍮摆脱 MySQL,纯 Redis 方案

进阶方案,内存富裕可用因为抽奖结果页面通常只显示用户昵称,我们还可以使用 Rdis 提速,用内存换时间。具体做法是



估算千万用户需要 3G 左右内存,spop 提取速度完全可控制在 3ms 内完成,且不会重复。TIPS:Redis 不怕 Key 多,就怕大 Key.测试结果:




1000 次 pop 执行时间 2565

🍚总结

以上就是千万用户 3 毫秒内抽奖 100 名如何实现的,希望有所帮助。

发布于: 刚刚阅读数: 4
用户头像

知识浅谈

关注

公众号:知识浅谈 2022.06.22 加入

🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云社区专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 💒 公众号:知识浅谈 🔥 联系方式vx:zsqtcc

评论

发布
暂无评论
千万用户3毫秒内抽奖100名如何实现?_8月月更_知识浅谈_InfoQ写作社区