题目
-
设计pastebin,用户A输入文本信息,系统生成URL,用户A可以分享这个url给其他用户
-
url有过期时间,过期后无法查看,用户可以指定过期时间
-
url不可以被预测
-
核心是1)如何生成唯一url;2)过期机制的实现
scenario
-
流量预估
用户5M,日活2M,日信息上传数量1M * 1 = 1M,
写入qps:12
读取qps:60 -
存储预估
-
内容存储:一条信息平均10K; 日存储10GB;存储数据不能丢失,10年需要36TB;
*过期时间默认一天,总存储量等同于1TB* -
pasteId存储:10年需要1M * 360 * 10 = 3.6B个pasteID,base62编码需要6位(几百亿)即可搞定;6 * 3.6B >= 20GB(相比于内存存储,可以忽略)
-
考虑70%容量负载率,实际存储利用率低于70%,需要52TB
3. 带宽预估
入口带宽:12 * 10K = 120K/s
出口带宽:60 * 10K = 600K/s
4. 内存预估
缓存读取的20%数据,600K * 0.2 * 86400 = 10GB,日缓存数量10GB;考虑缓存数据周期,不会持续增长;
service
1.核心功能:应用层如何生成唯一的不可以预测的URL;不可预测意味着URL的逻辑不是连续的,防止被对手知道一天的单量;
-
base62(userID + timestamp),userID 5位base62 + timestamp 10位base10,userID是高位(30) + 时间戳低位(32) = 62位,10字符的url;缺点是空间占用;
-
随机数url生成
- 在线生成6位的随机数,缺点时碰撞后效率较低
- 提供KGS服务,负责离线生成一组随机key,6位的base62字符串并存储DB中;
- app server处理写入请求时查询数据库获取未使用的首个key;获取成功后在DB中标记key为使用过。但这样效率过低,多个app server获取key同步耗时,另一方面DB压力大;
- 为缓解DB压力,KGS可以将未被使用的key放在内存中;但还是要解决多个app server的同步问题,那换个思路,让KGS将生成的key的列表分段推送给各个app server,这样就省去了不同server的同步问题;已经推送出去的key即可标记使用过;但是如果app server宕机,key列表丢失怎么办呢?一方面认为我们提供的key足够多,少部分丢失没有问题,另一方面可以记录每个app server最后消费的key,然后根据推送的key列表以及last_key恢复出未使用过的列表;
- 推送key恐怕是有问题的,KGS不知道app server何时消费完成,所以还是需要app server主动来pull数据;KSG可以在内存中保存一批数据
- KSG会成为单点服务么?会的,需要怎么做呢?那需要配置SLAVE节点,MASTER宕机后,SLAVE需要代替;
然后查询是否有重复url;如果没有,则将<url, pasteId, timestamp, userId, expireTime>存储;如果有则重新生成随机url,否则存储成功;
2.过期机制
用户访问url时,系统查看url是否存在,如果存在,则查看过期时间,有效则返回pasteId对应的内容;
过期url的标记是lazy的方式,1)用户访问url时校验 2)生成新的url时校验