tips
tips copied to clipboard
2017-01-19 如果让你设计支付宝五福系统的存储,你会怎么设计?
大家踊跃推荐话题
抽福的概率随机,五个福的概率也不一样,为了加更多好友。可以这样玩,第一次抽到的福,以后出现的概率更大。
一个五位数字,每一位0或1 好像就可以存下了。
首先,抽福结果应该先入缓存,只存储抽中福字的记录,算法规则肯定也在缓存里面。每个人可抽中福字总数和下一个抽中福字的概率都由算法决定,据我自己的体会,应该每人每天能扫到3个左右。
1、扫描福字,这里涉及到识别算法,具体怎么识别的,没想明白,还望专业人员讲解。这里涉及到高可用和高并发; 2、根据各自算法,判断是否给福,给什么福; 3、给了福字,就该考虑怎么存储了,由于用户会经常性的查看福字收集情况,所以读操作很多,同时,写操作也是实时存在的,如扫福字得福,请求朋友或者发送给朋友。这种情况的话,加缓存是必须的,但是也存在频繁修改缓存的情况,请求或者赠送也涉及到事务问题,与交易类似,加一减一问题。数据存储特点,参与人数多,数据存储数量大,存储信息小。 我自己想到的是用redis集群存储,并且需要分表,分库得看情况,实现读写分离。入库也是必要的,其实还要大数据处理,分析用户行为,为以后类似活动提供依据。
个人愚见,期待大神给出专业思路。
@chendw 一位代表一种福。这一位可以记录你的福是怎么得到的,是朋友给的,还是自己扫出来的。
对这块不是很清楚底层实现,简单说下看法: 一、数据结构部分: 1、主数据结构考虑采用nosql,key+map,内容采用json格式,包括6个字段 状态位:是否期满,然后是5福,如果多月1可以分享给其他人,如果等于1,刚好,否则可从其他处获取。 2、直接关联关系数据结构:记录福的来源,福的去处。 3、间接关联关系数据结构:如个人信息、群组信息、外围嘟嘟嘟功能等。 二、数据存储: 数据可考虑按群组分布式存储,或按区域分布式存储,具体还需分析数据本身。未集满5福的用户数据存储在数据库中,已满的同步至hadoop中。 三、数据查询及计算: 集福过程中,基于数据库+流计算。 满福后,基于hadoop查询及计算。
可以用比特币的技术来实现,区块链,把福当成数字货币,送出去的福(数字的钱)也就实现了去中心化的唯一性,其它的只需要结合大数据架构,与关系数据实现。
采用redis集群(热)+ MySQL分库分表(落地)方式 福字存储: fid、跟福相关的属性,如广告信息 用户与福字关系:uid、fid
Redis HashMap Structure:
+---------+----------+-------------+
| | F_A | "1" |
| userId | F_B | "1 |
| | F_C | "2" |
+--------------------+-------------+
可以把它抽象成资源池,资源数是固定的,每次发放数是固定的,让这么多用户去抢这个福,就相当于消耗这个资源;比如敬业福100万个,将她分成100个资源池(分桶原理),这个桶可以是redis、db 等,每个db 维护着1万个资源,然后让成千上万的用户去随机请求这100个资源池,每次消耗一个就减一。 用户这块可以采用分库分表实现,每个用户与福的关系记录为5条,可以采用db、redis 的结构。
杭州-九夜茴
1.福字卡号动态规则生成(1231980000 如12 代表分库规则码 31 代表分表规则码) 2.通过卡号动态创建连接数据实例,读写分离 3.规则算法可以根据1.身份(所在区域)2. 业务类型(福卡)来设计;
北京--- 猪头哥哥
从今年已经集齐了五福的人数来看。完全就是随机给的。没有对某一个福进行数量的限制。
👊 总结
点子都是来自于大家,我将大家出的一个个点子汇总,加以发酵做个简单总结。
福卡池
首先,任何公司举办活动肯定都有奖池。
那么我相信福卡池也一定有奖池。那么根据集齐5福才能召唤神龙的规则。
也就是说,其他的福卡可以是以一定的策略随机+每日限额。
但是有一种福卡是严格按照总量控制的,这里叫他关键福
。
那么,抽福卡的流程是:
- 根据当前概率抽卡,命中则下一步,不命中则返回没有抽到卡
- 做带权重的抽签,确定本次抽到哪一种福卡。如果是非关键福则返回抽中福卡。如果是关键福,则下一步。
- 去今日投放的关键福资源池里获取资源,如果获取到则总资源-1,如果获取不到则返回未抽中。
数据存储
按照@wangguixi的算法,我们用Redis得hashes数据结构存储福卡数据。简单计算下需要内存容量。
假设:5亿玩家,每种福卡每人不超过10个。
每个玩家的数据是这样的
- userId
- A:1
- B:1
- C:1
- D:1
- E:1
这里忽略redis hashes数据结构本身需要占用的字节。同时,useId我们计16个字节。
16 + 10 = 26 byte
26 * 500000000 = 13,000,000,000 byte ≈ 12.2 Gbyte
这个内存占用完全可以接受。
我们对用户做一致性hash,分片到不同的Redis服务器。一方面将数据打散,减少出错的概率,避免单点。另一方面将压力分散到不同的节点。
福卡流转
这个系统的难点,应该是对关键福做精确的数量控制。比如总量100个,那么一个人从100中获取到一个,总量减一变成99.那获取到的1一定要保证加到那个人头上。
这中间涉及到数据一致性的问题。类似转账。
未完待续。。。
数据一致性:队列、线程同步锁、事务