tips icon indicating copy to clipboard operation
tips copied to clipboard

2017-01-19 如果让你设计支付宝五福系统的存储,你会怎么设计?

Open teaey opened this issue 8 years ago • 14 comments

大家踊跃推荐话题

teaey avatar Jan 18 '17 10:01 teaey

抽福的概率随机,五个福的概率也不一样,为了加更多好友。可以这样玩,第一次抽到的福,以后出现的概率更大。

lalmeme avatar Jan 19 '17 01:01 lalmeme

一个五位数字,每一位0或1 好像就可以存下了。

chendw avatar Jan 19 '17 02:01 chendw

首先,抽福结果应该先入缓存,只存储抽中福字的记录,算法规则肯定也在缓存里面。每个人可抽中福字总数和下一个抽中福字的概率都由算法决定,据我自己的体会,应该每人每天能扫到3个左右。

Jukewu avatar Jan 19 '17 02:01 Jukewu

1、扫描福字,这里涉及到识别算法,具体怎么识别的,没想明白,还望专业人员讲解。这里涉及到高可用和高并发; 2、根据各自算法,判断是否给福,给什么福; 3、给了福字,就该考虑怎么存储了,由于用户会经常性的查看福字收集情况,所以读操作很多,同时,写操作也是实时存在的,如扫福字得福,请求朋友或者发送给朋友。这种情况的话,加缓存是必须的,但是也存在频繁修改缓存的情况,请求或者赠送也涉及到事务问题,与交易类似,加一减一问题。数据存储特点,参与人数多,数据存储数量大,存储信息小。 我自己想到的是用redis集群存储,并且需要分表,分库得看情况,实现读写分离。入库也是必要的,其实还要大数据处理,分析用户行为,为以后类似活动提供依据。

个人愚见,期待大神给出专业思路。

jeffrey-hua avatar Jan 19 '17 02:01 jeffrey-hua

@chendw 一位代表一种福。这一位可以记录你的福是怎么得到的,是朋友给的,还是自己扫出来的。

guogaowei avatar Jan 19 '17 02:01 guogaowei

对这块不是很清楚底层实现,简单说下看法: 一、数据结构部分: 1、主数据结构考虑采用nosql,key+map,内容采用json格式,包括6个字段 状态位:是否期满,然后是5福,如果多月1可以分享给其他人,如果等于1,刚好,否则可从其他处获取。 2、直接关联关系数据结构:记录福的来源,福的去处。 3、间接关联关系数据结构:如个人信息、群组信息、外围嘟嘟嘟功能等。 二、数据存储: 数据可考虑按群组分布式存储,或按区域分布式存储,具体还需分析数据本身。未集满5福的用户数据存储在数据库中,已满的同步至hadoop中。 三、数据查询及计算: 集福过程中,基于数据库+流计算。 满福后,基于hadoop查询及计算。

minefeng avatar Jan 19 '17 02:01 minefeng

可以用比特币的技术来实现,区块链,把福当成数字货币,送出去的福(数字的钱)也就实现了去中心化的唯一性,其它的只需要结合大数据架构,与关系数据实现。

luofly avatar Jan 19 '17 03:01 luofly

采用redis集群(热)+ MySQL分库分表(落地)方式 福字存储: fid、跟福相关的属性,如广告信息 用户与福字关系:uid、fid

tuhailong5 avatar Jan 19 '17 06:01 tuhailong5

Redis HashMap Structure: +---------+----------+-------------+ |                 | F_A             |         "1"         |
| userId     | F_B             |         "1         |
|                 | F_C             |         "2"         |
+--------------------+-------------+

wangguixi avatar Jan 19 '17 06:01 wangguixi

可以把它抽象成资源池,资源数是固定的,每次发放数是固定的,让这么多用户去抢这个福,就相当于消耗这个资源;比如敬业福100万个,将她分成100个资源池(分桶原理),这个桶可以是redis、db 等,每个db 维护着1万个资源,然后让成千上万的用户去随机请求这100个资源池,每次消耗一个就减一。 用户这块可以采用分库分表实现,每个用户与福的关系记录为5条,可以采用db、redis 的结构。

杭州-九夜茴

grindwheel avatar Jan 19 '17 06:01 grindwheel

1.福字卡号动态规则生成(1231980000  如12 代表分库规则码 31 代表分表规则码) 2.通过卡号动态创建连接数据实例,读写分离 3.规则算法可以根据1.身份(所在区域)2. 业务类型(福卡)来设计;

北京--- 猪头哥哥

Shuangxiding avatar Jan 19 '17 07:01 Shuangxiding

从今年已经集齐了五福的人数来看。完全就是随机给的。没有对某一个福进行数量的限制。

grojef avatar Jan 19 '17 12:01 grojef

👊 总结

点子都是来自于大家,我将大家出的一个个点子汇总,加以发酵做个简单总结。

福卡池

首先,任何公司举办活动肯定都有奖池。

那么我相信福卡池也一定有奖池。那么根据集齐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一定要保证加到那个人头上。

这中间涉及到数据一致性的问题。类似转账。

未完待续。。。

teaey avatar Jan 19 '17 15:01 teaey

数据一致性:队列、线程同步锁、事务

quaxiaoalin avatar Jan 20 '17 01:01 quaxiaoalin