是否可以让DataFlow进程保持状态。有一些日志处理工具可以通过为实时进程提供快速访问(适当/内存)文件来实现这一点,以便在处理日志时跟踪日志状态。
用例示例将跟踪用户采用的注册步骤。注册步骤将出现在不同的日志中,并且这些日志的数据将由实时进程汇编到一个写入数据库的最终数据库记录(对于每个注册用户)。
我的DataFLow代码可以跟踪用户的许多注册步骤(流输入),并且一旦用户的注册步骤完成,然后让DataFLow进程将记录写入数据库(每个用户一条记录)。
我对DataFlow架构知之甚少。它必须使用一些(专有/内存中的nosql)数据存储来跟踪它需要跟踪的事情(例如,当它试图生产前100名客户时)。这种快速访问数据存储是否也可供DataFlow进程使用?
由于
答案 0 :(得分:3)
正如丹尼尔所说,国家尚未暴露。好消息是你的用例可能不需要它。
如果您有PCollection<KV<UserId, LogEvent>>
,则可以使用CombineFn
和Combine.perKey
获取特定LogEvent
的所有UserId
并将其合并到单个输出。 CombineFn
告诉Dataflow如何创建累加器,通过合并输入元素来更新它,然后提取最终输出。像Top
这样的转换实际上使用CombineFn
(使用堆作为累加器)而不是实际的状态API。
如果您的活动类型不同,您仍然可以执行此类操作。例如,如果您有两个日志,则可以执行以下操作:
PCollection<KV<UserId, LogEvent1>> events1 = ...;
PCollection<KV<UserId, LogEvent2>> events2 = ...;
// Create tuple tags for the value types in each collection.
final TupleTag<LogEvent1> tag1 = new TupleTag<LogEvent1>();
final TupleTag<LogEvent2> tag2 = new TupleTag<LogEvent2>();
//Merge collection values into a CoGbkResult collection
PCollection<KV<UserIf, CoGbkResult>> coGbkResultCollection =
KeyedPCollectionTuple.of(tag1, pt1)
.and(tag2, pt2)
.apply(CoGroupByKey.<UserId>create());
// Access results and do something.
PCollection<T> finalResultCollection =
coGbkResultCollection.apply(ParDo.of(
new DoFn<KV<K, CoGbkResult>, T>() {
@Override
public void processElement(ProcessContext c) {
KV<K, CoGbkResult> e = c.element();
// Get all LogEvent1 values
Iterable<LogEvent1> event1s = e.getValue().getAll(tag1);
// There will only be one LogEvent2
LogEvent2 event2 = e.getValue().getOnly(tag2);
... Do Something to compute T ....
c.output(...some T...);
}
}));
以上示例改编自docs on CoGroupByKey,其中包含信息。
答案 1 :(得分:2)
Dataflow当前没有公开它使用的基础状态机制。但是,这肯定是未来更新的关注点。