Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Session 会话窗口阻止GroupByKey工作_Session_Google Cloud Dataflow_Apache Beam - Fatal编程技术网

Session 会话窗口阻止GroupByKey工作

Session 会话窗口阻止GroupByKey工作,session,google-cloud-dataflow,apache-beam,Session,Google Cloud Dataflow,Apache Beam,我有一个传入的事件流,每个事件都已经有一个来自另一个进程的相关sessionId 我只想使用自定义CombineFn将这些事件合并到单个会话对象中 在开发过程中,我使用一个从文件读取的有界数据集,以下代码似乎可以工作: input.apply(ParDo.named("ParseEvent").of(new ParseEventFn())) .setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(Event.class)))

我有一个传入的事件流,每个事件都已经有一个来自另一个进程的相关sessionId

我只想使用自定义CombineFn将这些事件合并到单个会话对象中

在开发过程中,我使用一个从文件读取的有界数据集,以下代码似乎可以工作:

input.apply(ParDo.named("ParseEvent").of(new ParseEventFn()))
    .setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(Event.class)))
    .apply(GroupByKey.<String, Event>create())
    .apply(Combine.groupedValues(new SessionAccumulator()))
但是为了在无界数据集上工作,我需要应用一个窗口函数,在本例中是一个SessionWindow

input.apply(ParDo.named("ParseEvent").of(new ParseEventFn()))
    .setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(Event.class)))
    .apply(Window.<KV<String, Event>>into(Sessions.withGapDuration(Duration.standardMinutes(30))))
    .apply(GroupByKey.<String, Event>create())
    .apply(Combine.groupedValues(new SessionAccumulator()))
知道为什么会这样吗


编辑:我应该补充一点,ParseEventFn正在使用context.outputWithTimestamp将时间戳应用于PCollection,并且该时间戳似乎是正确的。

进一步深入研究,在我的案例中,问题是我的核心假设时间戳是正确的,但这是错误的

我在窗口打开之前应用的时间戳是错误的

窗口正是它应该做的,但是我把时间戳设置得太远了,它为每个事件创建了单独的会话


哎呀

进一步深入研究,在我的例子中,问题是我的时间戳是正确的核心假设是错误的

我在窗口打开之前应用的时间戳是错误的

窗口正是它应该做的,但是我把时间戳设置得太远了,它为每个事件创建了单独的会话


Oops

在您的情况下,您可以编写自己的WindowFn。如果您将密钥设置为会话ID,那么较大的间隔持续时间也会起作用,但它不能很好地反映数据和计算的性质

WindowFn的成分包括:

您自己的BoundedWindow子类,在本例中,您将创建一个在字段中包含会话ID的窗口类型 assignWindows,您可以将每个元素分配给由会话ID标识的窗口。窗口的长度仍然很重要,因为它控制窗口何时过期并被垃圾回收。 合并窗口,您可以合并具有相同会话ID的所有窗口。它们不必在任何特定的间隔时间内。
您需要注意的另一件事是,控制这些窗口垃圾收集的水印由无限事件流的源决定。因此,在ParDo.ofnew ParseEventFn中设置时间戳将太晚,无法影响水印。您可能已经删除了要保留的数据。

在您的情况下,您可以编写自己的WindowFn。如果您将密钥设置为会话ID,那么较大的间隔持续时间也会起作用,但它不能很好地反映数据和计算的性质

WindowFn的成分包括:

您自己的BoundedWindow子类,在本例中,您将创建一个在字段中包含会话ID的窗口类型 assignWindows,您可以将每个元素分配给由会话ID标识的窗口。窗口的长度仍然很重要,因为它控制窗口何时过期并被垃圾回收。 合并窗口,您可以合并具有相同会话ID的所有窗口。它们不必在任何特定的间隔时间内。
您需要注意的另一件事是,控制这些窗口垃圾收集的水印由无限事件流的源决定。因此,在ParDo.ofnew ParseEventFn中设置时间戳将太晚,无法影响水印。您可能已经删除了您希望保留的数据。

到目前为止,我发现一定是我的窗口正在将每个事件添加到它自己的窗口中,尽管我不知道为什么。到目前为止,我发现一定是我的窗口正在将每个事件添加到它自己的窗口中,尽管我不知道为什么。您介意共享您的工作代码吗?我在使用会话窗口时遇到了类似的问题,在会话窗口中,窗口在接收数据时立即发出结果,而不是等待事件之间的会话间隔。谢谢你介意分享你的工作代码吗?我在使用会话窗口时遇到了类似的问题,在会话窗口中,窗口在接收数据时立即发出结果,而不是等待事件之间的会话间隔。谢谢
input.apply(ParDo.named("ParseEvent").of(new ParseEventFn()))
    .setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(Event.class)))
    .apply(Window.<KV<String, Event>>into(Sessions.withGapDuration(Duration.standardMinutes(30))))
    .apply(GroupByKey.<String, Event>create())
    .apply(Combine.groupedValues(new SessionAccumulator()))
{sessionId: 1, events: [event1]}
{sessionId: 1, events: [event2]}
{sessionId: 1, events: [event3]}
{sessionId: 2, events: [event4]}
{sessionId: 2, events: [event5]}