背景
我们小组前段时间接到一个需求,希望能够按照小时为单位,看到每个实验中各种特征(单个或组合)的覆盖率、正样本占比、负样本占比。我简单解释一下这三种指标的定义:
覆盖率:所有样本中出现某一特征的样本的比例
正样本占比:所有出现该特征的样本中,正样本的比例
负样本占比:所有出现该特征的样本中,负样本的比例
光看这三个指标,大家可能会觉得这个需求很简单,无非就是一个简单的筛选、聚合而已。
如果真的这么简单,我也没必要写这篇文章单独记录了。问题的关键就在于,每小时有将近1亿的数据量,而我们需要保存7天的数据,数据总量预计超过了100亿。
技术方案
在了解清楚需求后,我们小组马上对技术方案展开讨论,讨论过程中出现了3种方案:
第一种:用Spark流式计算,计算每一种可能单个或组合特征的相关指标
第二种:收到客户端请求后,遍历HDFS中相关数据,进行离线计算
第三种:将数据按照实验+小时分索引存入ES,收到客户端请求后,实时计算返回
首先,第一种方案直接被diss,原因是一个实验一般会出现几百、上千个特征,而这些特征的组合何止几亿种,全部计算的话,可行性暂且不论,光是对资源的消耗就无法承受。
第二种方案,虽然技术上是可行的,但离线计算所需时间较长,对用户来说,体验并不理想。并且,为了计算目标1%的数据而要遍历所有数据,对资源也存在很大浪费。