微信红包的架构设计简介

@来源于QCon某高可用架构群整理,整理朱玉华。

背景:有某个朋友在朋友圈咨询微信红包的架构,于是乎有了下面的文字(有误请提出,谢谢)

概况:2014年微信红包使用数据库硬抗整个流量,2015年使用cache抗流量。

    1. 微信的金额什么时候算? 
      答:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储。。 
      采取实时计算金额的考虑:预算需要占存储,实时效率很高,预算才效率低。
    2. 实时性:为什么明明抢到红包,点开后发现没有? 
      答:2014年的红包一点开就知道金额,分两次操作,先抢到金额,然后再转账。 
      2015年的红包的拆和抢是分离的,需要点两次,因此会出现抢到红包了,但点开后告知红包已经被领完的状况。进入到第一个页面不代表抢到,只表示当时红包还有。
    3. 分配:红包里的金额怎么算?为什么出现各个红包金额相差很大? 
      答:随机,额度在0.01和剩余平均值*2之间。 
      例如:发100块钱,总共10个红包,那么平均值是10块钱一个,那么发出来的红包的额度在0.01元~20元之间波动。 
      当前面3个红包总共被领了40块钱时,剩下60块钱,总共7个红包,那么这7个红包的额度在:0.01~(60/7*2)=17.14之间。 
      注意:这里的算法是每被抢一个后,剩下的会再次执行上面的这样的算法(Tim老师也觉得上述算法太复杂,不知基于什么样的考虑)。

      这样算下去,会超过最开始的全部金额,因此到了最后面如果不够这么算,那么会采取如下算法:保证剩余用户能拿到最低1分钱即可。

      如果前面的人手气不好,那么后面的余额越多,红包额度也就越多,因此实际概率一样的。

    4. 红包的设计 
      答:微信从财付通拉取金额数据郭莱,生成个数/红包类型/金额放到redis集群里,app端将红包ID的请求放入请求队列中,如果发现超过红包的个数,直接返回。根据红包的裸祭处理成功得到令牌请求,则由财付通进行一致性调用,通过像比特币一样,两边保存交易记录,交易后交给第三方服务审计,如果交易过程中出现不一致就强制回归。
    5. 发性处理:红包如何计算被抢完? 
      答:cache会抵抗无效请求,将无效的请求过滤掉,实际进入到后台的量不大。cache记录红包个数,原子操作进行个数递减,到0表示被抢光。财付通按照20万笔每秒入账准备,但实际还不到8万每秒。
    6. 通如何保持8w每秒的写入? 
      答:多主sharding,水平扩展机器。
    7. 据容量多少? 
      答:一个红包只占一条记录,有效期只有几天,因此不需要太多空间。
    8. 询红包分配,压力大不? 
      答:抢到红包的人数和红包都在一条cache记录上,没有太大的查询压力。
    9. 一个红包一个队列? 
      答:没有队列,一个红包一条数据,数据上有一个计数器字段。
    10. 有没有从数据上证明每个红包的概率是不是均等? 
      答:不是绝对均等,就是一个简单的拍脑袋算法。
    11. 拍脑袋算法,会不会出现两个最佳? 
      答:会出现金额一样的,但是手气最佳只有一个,先抢到的那个最佳。
    12. 每领一个红包就更新数据么? 
      答:每抢到一个红包,就cas更新剩余金额和红包个数。
    13. 红包如何入库入账? 
      数据库会累加已经领取的个数与金额,插入一条领取记录。入账则是后台异步操作。
    14. 入帐出错怎么办?比如红包个数没了,但余额还有? 
      答:最后会有一个take all操作。另外还有一个对账来保障。

最近看了一篇文章,讲微信红包随机算法的。感觉很不错,所以自己实现了下,并进行了简单测试。

算法

算法很简单,不是提前算好,而是抢红包时计算:

红包里的金额怎么算?为什么出现各个红包金额相差很大?
答:随机,额度在0.01和剩余平均值*2之间。

实现

实现上述算法的逻辑主要是:

public static double getRandomMoney(RedPackage _redPackage) {
    // remainSize 剩余的红包数量
    // remainMoney 剩余的钱
    if (_redPackage.remainSize == 1) {
        _redPackage.remainSize--;
        return (double) Math.round(_redPackage.remainMoney * 100) / 100;
    }
    Random r     = new Random();
    double min   = 0.01; //
    double max   = _redPackage.remainMoney / _redPackage.remainSize * 2;
    double money = r.nextDouble() * max;
    money = money <= min ? 0.01: money;
    money = Math.floor(money * 100) / 100;
    _redPackage.remainSize--;
    _redPackage.remainMoney -= money;
    return money;
}

LeftMoneyPackage数据结构如下:

class RedPackage {
    int    remainSize;
    double remainMoney;
}

测试时初始化相关数据是:

static void init() {
    redPackage.remainSize  = 30;
    redPackage.remainMoney = 500;
}

测试结果

单词测试随机红包

以上面的初始化数据(30人抢500块),执行了两次,结果如下:

// 第一次
15.69    21.18    24.11    30.85    0.74    20.85    2.96    13.43    11.12    24.87    1.86    19.62    5.97    29.33    3.05    26.94    18.69    34.47    9.4    29.83    5.17    24.67    17.09    29.96    6.77    5.79    0.34    23.89    40.44    0.92

// 第二次
10.44    18.01    17.01    21.07    11.87    4.78    30.14    32.05    16.68    20.34    12.94    27.98    9.31    17.97    12.93    28.75    12.1    12.77    7.54    10.87    4.16    25.36    26.89    5.73    11.59    23.91    17.77    15.85    23.42    9.77

对应图表如下:

还有一张:

多次均值

可以看到,这个算法可以让大家抢到的红包面额在概率上是大致均匀的。



微信红包的架构设计简介

时间: 2024-12-14 18:04:25

微信红包的架构设计简介的相关文章

微信红包的架构设计简介{转}

转自https://www.zybuluo.com/yulin718/note/93148 背景:有某个朋友在朋友圈咨询微信红包的架构,于是乎有了下面的文字(有误请提出,谢谢) 概况:2014年微信红包使用数据库硬抗整个流量,2015年使用cache抗流量. 微信的金额什么时候算? 答:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储.. 采取实时计算金额的考虑:预算需要占存储,实时效率很高,预算才效率低. 实时性:为什么明明抢到红包,点开后发现没有? 答:2

微信序列号生成器架构设计及演变

微信序列号生成器架构设计及演变

微信开发之架构设计

微信作为一款app,提供了友好的用户体验,在开发微信应用时,我们应该尽可能得让自己的网页像webapp一样.用户使用我们的网页,就好像在使用微信内置的app,这样用户才会喜欢我们的网站. 本文将讲解微信开发的前期准备,包括微信开发上的一些坑.架构上的设计.接口上需要注意的地方,全部来自自己的开发经验,如有不对,请指正. 微信开发的坑 1.微信授权 微信中涉及到了OAuth2.0网页授权,正因为这样,我理所当然的用这个接口来读取用户的基本信息,包括头像.用户名等,因为之前了解过淘宝的公众平台,大家

第53课:Hive 第一课:Hive的价值、Hive的架构设计简介

一. Hive的历史价值 1, 大数据因Hadoop而知名,而Hadoop又因Hive而实用.Hive是Hadoop上的Killer Application,Hive是Hadoop上的数据仓库,同时Hive兼具有数据仓库中的存储和查询引擎.而Spark SQL是一个更加出色和高级的查询引擎,并不提供存储功能.所以Spark SQL无法取代Hive,在现在企业级应用中Spark SQL+Hive成为了业界使用的大数据最为高效和流行的趋势. 2,Hive是Facebook推出的,主要是为了让不懂ja

微信红包随机算法

最近看了一篇文章,讲微信红包随机算法的.感觉很不错,所以自己实现了下,并进行了简单测试. 算法 算法很简单,不是提前算好,而是抢红包时计算: 红包里的金额怎么算?为什么出现各个红包金额相差很大?答:随机,额度在0.01和剩余平均值*2之间. 实现 实现上述算法的逻辑主要是: public static double getRandomMoney(RedPackage _redPackage) { // remainSize 剩余的红包数量 // remainMoney 剩余的钱 if (_red

微信红包金额分配的算法 http://timyang.net/architecture/wechat-red-packet/

虽然春节已经过去一段时间,但不少微信群里面依旧乐此不疲的在玩发红包活动,用户自发的将最初的一个春节拜年的场景功能慢慢演化成一个长尾功能. 用户在微信中抢红包时分成抢包和拆包两个操作.抢包决定红包是否还有剩余金额,但如果行动不够迅速,在拆包阶段可能红包已经被其他用户抢走的情况. 红包的金额是在什么时候算? 据某架构群腾讯财付通专家反馈,红包的金额是拆的时候实时计算,而不是预先分配,实时计算基于内存,不需要额外存储空间,并且实时计算效率也很高.每次拆红包时,系统取0.01到剩余平均值*2之间作为红包

【转】微信红包随机算法初探

最近看了一篇文章,讲微信红包随机算法的.感觉很不错,所以自己实现了下,并进行了简单测试. 算法 算法很简单,不是提前算好,而是抢红包时计算: 红包里的金额怎么算?为什么出现各个红包金额相差很大?答:随机,额度在0.01和剩余平均值*2之间. 实现 实现上述算法的逻辑主要是: public static double getRandomMoney(RedPackage _redPackage) { // remainSize 剩余的红包数量 // remainMoney 剩余的钱 if (_red

架构设计杂谈001-软件开发人员的成长之路

软件开发人员的成长路线-1 从技术方面来看,基本上就三条主要路线: 1.纯技术路线: 高级开发人员 →系统设计人员→架构师→资深技术专家/资深架构师 2.技术管理路线: 研发型技术管理高级开发人员→ 系统设计人员→架构师 →技术管理人员→CTO/技术副总 项目型技术管理高级开发人员 →系统设计人员/ Team Leader →技术经理/技术总监 3.创业路线:高级开发人员→ 系统设计人员 →架构师 → 创业→当老板 ●架构师--软件开发人员的必经之路 软件开发人员的成长路线-2 转行或转技术周边

架构设计杂谈004——架构师

什么是架构设师        架构师是:负责系统架构设计的人.团队或组织 架构师主要干什么 ●架构师是技术领导,领导并负责架构设计,负责做决策 ●架构师可以是团队或组织,这个时候通常会有首席架构师 ●架构师必须掌握足够的技术知识 ●架构师必须掌握足够的架构设计技能 ●架构师必须具备很好的编程能力,实际参与架构原型的设计和开发实现 ●架构师必须深入理解业务及业务领域知识,让架构更好支持业务目标 ●架构师应该具备很好的沟通能力,讲解架构.指导开发.协调冲突等 ●架构师必须了解软件过程,为项目全流程提