Я изучаю журналы обработки из сеансов веб-пользователей через Google Dataflow/Apache Beam и должен объединять журналы пользователей по мере их поступления (потоковой передачи) с историей сеанса пользователя за последний месяц.
Я рассмотрел следующие подходы:
- Используйте 30-дневное фиксированное окно: скорее всего, большой размер окна будет помещен в память, и мне не нужно обновлять историю пользователей, просто обратитесь к нему.
- Используйте CoGroupByKey для объединения двух наборов данных, но два набора данных должны иметь одинаковый размер окна (https://cloud.google.com/dataflow/model/group-by-key#join), что в моем случае неверно (24 ч против 30 дней).
- Использовать боковой вход для получения истории сеансов пользователя для заданного
element
вprocessElement(ProcessContext processContext)
Я понимаю, что данные, загруженные через .withSideInputs(pCollectionView)
, должны вписываться в память. Я знаю, что могу поместить всю историю сеансов одного пользователя в память, но не все истории сеансов.
Мой вопрос в том, есть ли способ загрузки/потоковой передачи данных с бокового ввода, относящегося только к текущему сеансу пользователя?
Я представляю функцию parDo, которая будет загружать сеанс истории пользователя из бокового ввода, указывая идентификатор пользователя. Но только текущий сеанс истории пользователя будет вписываться в память; загрузка всех сеансов истории через боковой вход будет слишком большой.
Некоторый псевдокод для иллюстрации:
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);
}
}