我有一个Onyx段流,这些段是带有时间戳的消息(按时间顺序排列)。说,他们看起来像这样:
{:id 1 :timestamp "2018-09-04 13:15:42" :msg "Hello, World!"}
{:id 2 :timestamp "2018-09-04 21:32:03" :msg "Lorem ipsum"}
{:id 3 :timestamp "2018-09-05 03:01:52" :msg "Dolor sit amet"}
{:id 4 :timestamp "2018-09-05 09:28:16" :msg "Consetetur sadipscing"}
{:id 5 :timestamp "2018-09-05 12:45:33" :msg "Elitr sed diam"}
{:id 6 :timestamp "2018-09-06 08:14:29" :msg "Nonumy eirmod"}
...
对于数据中的每个时间窗口(一天),我想对其所有分段的集合进行计算。也就是说,在该示例中,我要对ID为1和2(9月4日)的分段进行操作,然后对ID为3、4和5(9月5日)的分段进行操作,以此类推。
Onyx提供了窗口和触发器,它们应该开箱即用。如果我使用:window/type :fixed
窗口并针对:window/range [1 :day]
在:window/window-key :timestamp
上进行汇总,则将汇总每天的所有细分。
要仅在一天的所有时间段到达时触发我的计算,Onyx提供了触发行为:onyx.triggers/watermark
。根据{{3}},它应该触发
如果段中
:window/window-key
的值在活动窗口范围内超过上限
但是,即使我看到以后的段已经进入并且几个窗口应该已满,触发器也不会触发。作为健全性检查,我尝试了一个简单的:onyx.triggers/segment
触发器,该触发器能够按预期工作。
我创建最小示例的尝试失败:
我修改了the documentation 玩具工作以测试水印触发,并且在那里工作。
但是,fixed windows认为,在此玩具工作中,触发水印触发器的原因可能是:
它关闭了输入通道吗?也许刚刚完成的工作也会触发水印。
与水印触发交互的另一个方面是对等对任务的分布式工作。
Onyx回购中对I found out( :trigger/emit
不与:onyx.triggers/watermark
一起使用的注释将我指向issue #839( Watermark不适用于具有> 1个分区的卡夫卡主题),在这里我发现了这个issue #840(强调我的意思):
问题是您的所有数据最终都集中在一个分区上,并且水印始终在输入的所有对等中采用最小水印(如果使用卡夫卡原生水印,即给定同级的最小水印。
在调用g / send并发送少量数据并自动分配分区时,所有数据最终都集中在一个分区上,这意味着另一个分区的对等方继续发出水印为0 。
我clue:
不可能将其与依赖于输入源的当前水印触发器一起使用。您可以尝试取消先前的水印实现[...]
但是,在我的任务图中,我要在窗口中聚合的细分,仅在某些中间任务中创建,它们并非源自输入任务。输入段仅提供有关如何创建/检索段内容的信息,以供该中间任务使用。
同样,此构造在上述玩具工作中可以正常工作。原因是输入通道在某个点被关闭,从而结束了工作,进而触发了水印。因此,我的玩具示例实际上不是一个好的模型,因为它不是开放式流。
如果作业确实从实际的输入源中获取了有问题的片段,但没有时间戳记,则Onyx似乎提供了空间来指定assign-watermark-fn
,这是 input 任务。该功能在新段的每次到达时设置水印。就我而言,这无济于事,因为这些段不是源自输入任务。
答案 0 :(得分:0)
我现在想出了一个解决方法。 documentation基本上提供了如何实现的线索:
这是标点符号触发器的快捷功能,当任何数据块的基于时间的窗口键位于另一个范围之上时会触发,有效地声明不再有早期窗口的数据到达。
因此,我更改了发出分段的任务,以便对于每个分段,还将发出另一个类似于分段的“前哨”:
[{:id 1 :timestamp "2018-09-04 13:15:42" :msg "Hello, World!"}
{:timestamp "2018-09-03 13:15:42" :over :out}]
请注意,:timestamp
早于窗口范围(此处为1天)。因此它将被发送到上一个窗口。由于我的数据是按时间顺序输入的,因此:punctuation
触发器可以通过存在“前哨”段(关键字:over)来告知可以关闭窗口。不要忘记逐出(即:trigger/post-evictor [:all]
)并从最终窗口中丢弃“前哨”句段。在任务图中添加:onyx/max-peers 1
可确保哨兵最终总是到达,尤其是在使用分组时。
请注意,此解决方法有两个假设: