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

举报
知识浅谈 发表于 2022/08/21 09:31:44 2022/08/21
【摘要】 千万用户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名如何实现的。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。