【发布时间】:2016-04-29 00:21:59
【问题描述】:
我正在调查通过 Google Dataflow/Apache Beam 处理来自网络用户会话的日志,并且需要将用户的日志(流式传输)与上个月的用户会话历史记录结合起来。
我研究了以下方法:
- 使用 30 天的固定窗口:最有可能大的窗口适合内存,我不需要更新用户的历史记录,参考一下即可
- 使用 CoGroupByKey 连接两个数据集,但两个数据集必须具有相同的窗口大小 (https://cloud.google.com/dataflow/model/group-by-key#join),在我的情况下不是这样(24 小时 vs 30 天)
- 使用 Side Input 检索用户在
processElement(ProcessContext processContext)中给定element的会话历史记录
我的理解是通过.withSideInputs(pCollectionView) 加载的数据需要适合内存。我知道我可以将单个用户的所有会话历史记录到内存中,但不能将 所有 会话历史记录。
我的问题是,是否有办法从仅与当前用户会话相关的侧面输入加载/流式传输数据?
我正在想象一个 parDo 函数,它通过指定用户的 ID 从侧面输入加载用户的历史会话。但是只有当前用户的历史会话才能放入内存;通过侧面输入加载所有历史会话会太大。
一些伪代码来说明:
public static class MetricFn extends DoFn<LogLine, String> {
final PCollectionView<Map<String, Iterable<LogLine>>> pHistoryView;
public MetricFn(PCollectionView<Map<String, Iterable<LogLine>>> historyView) {
this.pHistoryView = historyView;
}
@Override
public void processElement(ProcessContext processContext) throws Exception {
Map<String, Iterable<LogLine>> historyLogData = processContext.sideInput(pHistoryView);
final LogLine currentLogLine = processContext.element();
final Iterable<LogLine> userHistory = historyLogData.get(currentLogLine.getUserId());
final String outputMetric = calculateMetricWithUserHistory(currentLogLine, userHistory);
processContext.output(outputMetric);
}
}
【问题讨论】:
标签: java apache-flink google-cloud-dataflow apache-beam