你能帮我吗?我正在尝试使用Apache Flink
与XGBoost等外部集成/树库进行机器学习任务,所以我的工作流程如下:
- 接收单个数据流,该原子事件看起来像一个简单的向量
event=(X1, X2, X3...Xn)
,可以想象为POJO字段,因此最初我们有DataStream<event> source=...
- 应用于同一事件源的许多特征提取代码:
feature1 = source.map(X1...Xn)
feature2 = source.map(X1...Xn)
等。为了简单起见,让DataStream<int> feature(i) = source.map()
用于所有功能 - 然后我需要创建一个具有提取特征的向量
(feature1, feature2, ...featureK)
,目前它将是40-50个特征,但我相信它将来会包含更多的项目,并且很容易包含100-500个特征和更多 - 按10分钟窗口将这些提取的特征放入数据集/表列中,并对这些10分钟的数据运行最终的机器学习任务
简单地说,我需要将几个完全不同的map
运算应用于流中的同一单个事件,然后将所有映射函数的结果组合到单个向量中。
所以现在我还不知道如何实现最后的reduce步骤,并在可能的情况下在parallel
中运行所有特征提取map
作业。我花了几天时间在flink docs网站、youtube视频、谷歌搜索、阅读Flink's
来源,但似乎我真的被困在了这里。
这里的简单解决方案是使用单个map
操作,在巨大的map
主体中逐个顺序运行每个特征提取代码,然后为每个输入事件返回最终向量(Feature1...FeatureK)
。但它应该是疯狂的和非最优的。
每两对特性的另一个解决方案都使用join
,因为所有特性数据流都有相同的初始事件和相同的键,并且只应用了一些转换代码,但它看起来很难看:用一些window
编写50个联接代码。我认为,连接和cogroups是为连接来自不同来源的不同流而开发的,而不是为这种映射/减少操作而开发的。
对于我来说,这里的所有map
操作都应该是我缺少的一个简单的东西。
你能告诉我你们是如何在Flink
中实现这些任务的吗?如果可能的话,请用代码示例?
谢谢!
您希望每秒处理的事件数是多少?如果它足够高(~number of machines * number of cores
),您应该可以同时处理更多的事件。与其按功能的数量缩放,不如按事件的数量缩放。如果您只有一个数据源,那么在应用转换之前,您仍然可以随机打乱事件。
另一种解决方案可能是:
- 分配唯一的eventId,并使用
flatMap
将原始事件拆分为元组:<featureId, Xi, eventId>
keyBy(featureId, eventId)
(或者可能使用shuffle()
进行随机分区?)- 执行转换
keyBy(eventId, ...)
- 窗口并减少到每个事件一条记录