- 包几个红包,发红包的总金额
- 塞钱进红包,弹出支付的界面,支付完之后就会被发到 群里
- 抢
- 拆红包,才是真正的抢红包
红包金额怎么分配
- 每个人至少抢到1分钱
- 人数抢到的金额之和就应该是红包的总金额
- 一个人抢的红包不应该极度的大,例如发了100,有一个人抢了99.5
红包金额预分配
假设100元,5个人抢,怎么抢,每个人应该多少钱?因为肯定是微服务的架构,第一时间想到的肯定是分布式锁,但是在这么高的并发下,分布式锁一定会严重影响性能。
我们可以在支付红包的时候,就把每个人的金额都算出来,然后放入队列中。抢的时候从队列中取就可以了,就不存在并发的问题了。
hash的作用是,我们抢完红包之后,要看每个人抢了多少钱,比方说ls抢了3元,zs抢了4元,
rp是red package,188是红包的id
- 基于红包预分配方式结合Redis无锁原子化操作规避并发争抢
微信的红包并不是这么做的,因为发的红包的量实在是太大了,而这些红包的信息又都是存放在redis中的,也就是是存放在内存中的,内存的价值是非常昂贵的,成本太大。
所以对于海量的这种场景,采用这种预分配的方案是不合适的。
微信红包内部实现
- 红包总金额 红包个数 版本
- 100元 5个 1
假设现在两个人同时抢红包,就算同时抢也总归有一个人先算出,一个人后算出金额,假如第一个人先算出金额,例如10块钱,那么就会变为
- 90元 4个 2
他俩同时抢到的时候,拿到的版本都是1,但是第一个请求已经更新完数据并且把版本更新为2了,第二个请求更新的时候检查版本是不是1,结果发现不是1,那么第二个请求就不能更新了
此时第二个请求就得重新拿版本2的数据重新计算
CAS有点像乐观锁,它不像悲观锁那样,会阻塞,所有线程都需要排队等待,CAS不需要阻塞等待,如果线程没有抢到就重新计算一次就好了。
- CAS有可能会导致CPU比较高,因为它在不断的进行重试,解决方案是让它稍微休眠一会儿,例如休眠100ms再重新尝试
微信内部不是通过redis来实现的,因为redis内部是没有CAS操作的,
微信内部自研的一个类似于redis的缓存框架叫ckv,它在内部通过一些手段实现了缓存级别的CAS方案。该框架没有开源
。
redis搭配lua命令
lua脚本解释
参数是红包金额,红包个数
- 获取红包总金额和个数
1.1 如果总金额等于0,则直接返回
1.2 如果大于0,则采用2倍均值算法计算金额 - 更新红包总金额和红包个数
- 将谁抢的红包,抢到了多少钱放入HASH中
lua脚本在执行lua脚本的时候是具备原子性的。不可分割的。
就是说如果有多个人同时调用这个方法,在redis中是单线程串行执行
的。不存在三个人同时执行lua的脚本。不存在并发安全问题。
这种方式不会比分布式锁高很多,但总归是要高一些的
如果使用分布式锁的话,会和redis交互多次,如果量很大的话,耗费的性能就非常多了。
基于redis集群支撑每秒百万红包并发
微信在春晚期间发红包的峰值是70w/s,
redis单机抗几万的并发撑死了,
我们用集群解决这个问题,一个节点假设抗2w的并发,如果有10个节点,理论上是可以抗20w的并发的。
数据库表设计
这儿的内容和上面的内容不是出自同一个地方
红包信息表
- id
- total_amount 红包总金额
- total_packet 红包个数
- left_packet 剩余红包个数
- left_amount 剩余红包金额
- expire_time 红包过期时间
红包记录表
- id
- amount
- userid
- packet_id
我认为的核心字段,实际上视频老师的表中还有很多字段,
部分内容引用自:
https://www.bilibili.com/video/BV14y4y1J7Pn?p=8&vd_source=64c73c596c59837e620fed47fa27ada7
https://www.bilibili.com/video/BV1Hz4y1g7y2/?spm_id_from=333.337.search-card.all.click&vd_source=64c73c596c59837e620fed47fa27ada7
我不主张以组织的方式来实现员工的自我解放,而是倡导员工自觉自愿,自我娱乐,自己承担费用的方式来组织和参与各种活动。公司不予任何补贴,凡是补贴的,只要不再补贴了,这项活动就死亡了。“青春之歌”是一个好的名字,一歌、二歌……五歌……,各具特色,吸引不同性格与生活取向的人。其实就是各种俱乐部。员工在这些活动中,锻炼了自己,舒缓了压力,也进行了有效的沟通,消除自闭、自傲……。只要这些活动不议论政治,不触犯法律,不违反道德规范,我们不去干预。一旦有违规,我们可以对有关员工免除其行政职务,以及辞退等方式来解决。总之释放员工的郁闷,应通过多种途径和管道来解决,靠组织是无能为力的。
任正非:要快乐地度过充满困难的一生