一道面试题给我整懵了,求指导
要求设计一个这样的系统:
1. 能够支撑一百亿订单 id,一亿个用户 id,每天增量更新
2. 提供查询“用户 id-订单 id”pair 是否 valid 的服务
3. 一次查询最多一千万对数据,响应时间越低越好
我懵了,想了半天挤出来了一个 redis set 存数据,t+1 更新,接口接受 csv 文件,面试官不是很满意
要求设计一个这样的系统:
1. 能够支撑一百亿订单 id,一亿个用户 id,每天增量更新
2. 提供查询“用户 id-订单 id”pair 是否 valid 的服务
3. 一次查询最多一千万对数据,响应时间越低越好
我懵了,想了半天挤出来了一个 redis set 存数据,t+1 更新,接口接受 csv 文件,面试官不是很满意
更详细的方案可以参考这个:
[百亿级微信红包的高并发资金交易系统设计方案]( https://www.infoq.cn/article/2017hongbao-weixin)
似乎是这样:使用 ng 来进行流量分发。
执行扩容时,先把新集群进行预热,按配置文件将特定 id 范围的数据从老集群复制到新集群。(包括新的写入)
预热完毕后 ng 切到新规则,部分 id 段打到老集群,部分 id 段打到新集群,集群内部再分片,从而平衡新老集群的负载
大概是这样吧,我只是跟他们聊天的时候听说过,具体细节不清楚。
然后写入的时候一般往第二个过滤器写,如果发现打算写的位置已经被写过,则认为发生碰撞,去第一个过滤器写碰撞标记。
具体的存储,可以考虑用 HBase,用 用户 id+订单 id,作为 rowkey 进行信息存储。
1.查看 用户 id-订单 id 组合是否有效时。如果内存全量建模存储,应该是资源要求蛮高的。可以考虑用布隆过滤器。因为属于用户 1 的订单 111,永远都属于用户 1,具有不变性。所以布隆过滤器,适合这种场景,可以一直叠加。 通过第一层过滤,快速过滤出来不能 vaild 的 pair 。
2.鉴于布隆过滤器的误报的特点。不合规的 pair 会有漏网之鱼,但是到这一层数量会很少了。组装这些 pair,做成 TreeSet,找到 rowkey 的上界和下界,然后使用 HBase 的 OnlyRawKey 的 Scanner 的 Filter,只扫描 rowkey 。因为 rowkey 本来是 b 树的,线性扫描的时候,判断 rowkey 是否在 TreeSet 里。
所以最终方案 100 亿条数据,使用双布隆过滤器一共消耗 8GB 内存,hash 数量 5,有不到百万分之一的概率被穿透。还算可以吧。
你是说,对 ID 进行新旧分类处理,老的 ID, 走旧的映射,新的 ID 走新的映射?
在缩容的时候,把新集群中的数据全部写回老集群,然后流量倒回,销毁新集群即可。
这套方案主要用于大促临时扩容,大促结束后还会到原状的场景,对于需要跟据负载频繁扩缩容的场景可能不合适(毕竟海量数据来回写不太现实)
最后,说真的我觉得布隆过滤器的方案赞爆了。
@reus 谢谢指导,没有了解过 rocksdb,我先去学习一下
有条件的话,建议找几台大机器自己折腾,做 benchamark