有没有办法确定作业运行的“起点”?

Posted

技术标签:

【中文标题】有没有办法确定作业运行的“起点”?【英文标题】:Is there a way to determine the "starting point" of a job run? 【发布时间】:2019-04-17 10:40:25 【问题描述】:

我正在将流分析作业从 Databricks/Spark 迁移到 Azure 流分析。输入来自 IoTHub,每当传感器值在阈值范围之间变化时(例如,从“警告”范围变为“警报”范围),查询都必须发出事件。

现有解决方案利用“有状态流式传输”,即它在内存中保存每个设备的最后状态,并在每条新消息上进行比较。在作业启动时(或在某些其他情况下)没有“最后状态”;在这种情况下,会创建一个额外的事件 - 并由下游组件优雅地处理。

我正在尝试在 ASA 中实现此功能:

    使用 可以轻松地与上一条记录进行比较
lag(value, 1, null) over (partition by(serialMachine) limit duration(minute, 60))
    使用本地输入数据进行测试时,上述结果对于第一条记录为空,可用于创建消息。 但在 Azure 上运行时,“lag”会返回一个值,即使它的源记录的时间戳早于配置的作业开始时间。我猜它被视为“输出开始时间”,无论此时间戳如何,所有可用消息或至少更多消息都会从 IoTHub 加载。

我尝试了 ISFIRST 和 LAST 函数,但所有这些都指的是一个时间窗口,即派生条件将定期得到满足。但我只需要一次。

有什么解决方法的想法吗?

【问题讨论】:

【参考方案1】:

作业的开始时间实际上是定义第一次输出的时间。但是,Azure 流分析将回顾事件流,在您的情况下为 60 分钟,因为您有 60 分钟的 LAG。 我们最近在the start job doc 上添加了有关此行为的更多信息。 对于您的情况,您可以在 60 分钟后开始工作以不阅读任何过去的信息。

如果您有任何其他问题,请告诉我,我很乐意为您提供帮助。

谢谢,

JS

【讨论】:

感谢 Jean-Sébastien 的解释。选择 60 分钟后的开始时间会导致 60 分钟没有任何输出事件,对吗?这对我不起作用(我想知道在这种情况下延迟是否也不会返回值(因为开始前 60 分钟的事件总是存在的)。我搜索了可以在查询中使用的任何信息为每个作业运行创建一个条件,例如作业开始时间、时间窗口计数器等。 另一个建议是在 SQL(例如,如果时间 > X)或参考数据中对查询开始时间进行硬编码。虽然这并不理想。您是否定期开始和停止工作? 是的,我明白了,这可能会起作用(也同意“不理想”)。该作业不会定期启动,但仅在需要时启动(在当前解决方案的情况下,即在创建或处理计算的“状态更改”事件时出现问题时)。谢谢你的想法。我们是否应该为此尝试在 UserVoice 上创建一个主题?【参考方案2】:

如果我理解得很好,看起来源记录已经被调整了。这意味着System.Timestamp(即实际考虑的时间戳)在未来开始时间之后已被“移动”。您是否尝试过删除迟到的事件?您可以在Configure -> Event Ordering 菜单中调整您的策略。

参考:Configuring event ordering policies for Azure Stream Analytics

【讨论】:

我相信这不是调整源记录的问题,而是@Jean-Sebastién 在他的回答中描述的 ASA 的预期行为:收集用于聚合的整个时间窗口的所有事件在启动时的查询中,即使这些在输出开始之前有时间戳。 是的,我同意 :)

以上是关于有没有办法确定作业运行的“起点”?的主要内容,如果未能解决你的问题,请参考以下文章

如何停止长时间运行的 BigQuery 作业?

有没有办法在运行时确定 AnyLogic 中 ResourcePool 的容量?

在 ColdFusion 中,有没有办法确定代码在哪个服务器上运行?

在运行 AWS Glue ETL 作业并命名输出文件名时,有没有办法从 S3 存储桶中读取文件名。 pyspark 是不是提供了一种方法来做到这一点?

如何防止某些 Jenkins 作业同时运行?

在 Quartz.NET 中,有没有办法设置一个只允许一个 Job 实例运行的属性?