本文是 实时场景下的机器学习模型实时特征离线特征融合方案(踩坑笔记) 的子问题,更多请点击原文链接查看
如果想做实时的模型预测,响应在秒级以内,建议特征简单点,并且尽量离线处理好,直接进行预测。
如果对实时性要求没那么高,想要做近实时模型预测,flinksql,是一个不错的中间件,因为flinksql有丰富的source,以及sink定义。简单的配置就可以将数据统一起来,以结构化的形式进行批量处理。
好了,优点有了,坑怎么能少呢?
简单的场景:数据只需要简单的解析就可以直接用的,而且不涉及left join 视图的情况,不会产生重复数据。
坑主要体现在复杂的场景中:
1、复杂场景如何排查数据问题:如果flinksql的source是一个比较复杂的json,然后需要自己层层解析,得到不同的view,然后基于这些视图进行最终的聚合,如果有的时候,解析的其中一张表为空,那你采用join,不就没有数据出来了,造成数据丢失(这里flinksql join机制不做展开),然后怎么办?在测试过程中将中间的结果表落入mysql中,这里不建议设置唯一主键,只设置索引进行查询,待数据校验完毕之后,将中间表入库的sink代码注释掉,只保留需要的sink。
2、sink下游数据重复问题:如果说你是在使用过程中,采用了left join 下游就可能产生重复数据,针对rds等支持更新的存储方式,你可以采用主键,flinksql可以自动更细。如果下游sink不支持update,比如kafka就不支持,数据就会有很多条,由于left join导致的数据回直接下发,当数据正确计算完成后对历史数据撤回,重新下发数据,这个机制叫回撤机制。这不就意味着,中间的数据是错误的吗?而且这种错误的数据预测出来的概率值,有可能比真实值高,也有可能比真实值低。
那下游该如何使用呢,尤其是kafka这种不支持更新的数据源?
一种方式:将flinksql结果写入mysql(为了方便追踪,所以数据都保存,只设置索引,不设置唯一主键),同时将主键写入卡夫卡,下游通过消费kafka中的主键从mysql查询该主键的最后一条记录。
另一种方式:kafka数据携带时间,flinksql处理的时间,下游通过这个时间排序取最新的一条记录,这也是需要记录所有中间状态的。
如果有其他场景的坑,欢迎留言。