AZURE 流分析) (时间戳

所有数据流事件都有一个与之关联的时间戳。 默认情况下,事件中心和IoT 中心的事件根据事件中心或IoT 中心接收事件的时间进行时间戳;来自 Blob 存储的事件按 Blob 的上次修改时间加时间戳。 如果重新启动或重新运行作业,事件的时间戳不会更改。

许多流式处理应用程序需要使用事件发生的确切时间戳,而不是到达时间。 例如,在销售点应用程序中,可能需要与付款记录时间对应的事件时间戳,而不是支付事件到达事件引入服务的时间。 此外,异地分布式系统和网络延迟可能会导致不可预知的到达时间,从而使应用程序时间在流式处理应用程序中的使用更加可靠。 对于这些情况,TIMESTAMP BY 子句允许指定自定义时间戳值。 该值可以是 DATETIME 类型的事件有效负载或表达式中的任何字段。 还支持符合任何 ISO 8601 格式的字符串值。

请注意,使用自定义时间戳 (TIMESTAMP BY 子句) 可能会导致 Azure 流分析不按顺序引入事件,原因有两个:

  • 单个事件生成者可能具有不同的 (和倾斜) 系统时钟。
  • 单个事件生成者的事件在传输过程中可能会延迟,例如,由于生成者站点的网络不可用。

虽然事件生成者之间的无序可能很大,但单个生成者的事件中的无序通常很小,甚至不存在。 如果查询仅独立处理来自每个事件生成者的数据,则处理每个生成者在其自己的时间线的事件比管理生成者之间的时间偏差更高效。 Azure 流分析通过指定 OVER <over spec> 子子句支持子流,以便在独立时间线中处理事件。 有关 OVER 子句的使用对作业处理的影响,请参阅“OVER 子句与事件排序交互”。

语法

TIMESTAMP BY scalar_expression [OVER <over spec> ]  
      
<over spec> ::= 
      { column_name | expression } [,...n ]  

备注

检索事件时间戳

可以使用 System.Timestamp () 属性在查询的任何部分的 SELECT 语句中检索事件时间戳。

OVER 子句与事件排序交互

使用 OVER 子句时,会修改 Azure 流分析的事件处理的几个方面:

  1. 在超过规格>的单个值元组中<应用最大无序容差。 也就是说,仅当与来自同一事件生成者的其他事件相关的事件出现过多无序时,事件才会被视为无序事件。

    例如,如果始终对来自同一事件生成者的事件进行排序,并且会导致立即处理,则可以使用值“0”。 另一方面,在此处使用大值将引入处理延迟,同时等待无序事件组合。

  2. (全局应用最大延迟到达容差,就好像未) 使用 OVER 一样。 也就是说,如果事件在 TIMESTAMP BY 子句中选择的时间戳 (,) 距离其到达时间太远,则将其视为延迟到达事件。

    请注意,此处使用大值不会引入处理延迟,并且事件仍会立即 (或根据最大无序容错) 进行处理。 几天的值并非不合理。 但是,使用超长值可能会影响处理作业所需的内存量。

  3. 每个事件生成者的输出事件是在计算时生成的,这意味着输出事件可能具有无序时间戳;但是,它们将在超过规范>的<单个值元组中按顺序排列。

限制和局限

TIMESTAMP BY OVER 子句具有以下用法限制:

  1. TIMESTAMP BY OVER 子句必须用于查询的所有输入,或者不用于其中任何输入。

  2. TIMESTAMP BY OVER 子句仅支持完全并行作业或单分区作业。

  3. 如果输入流具有多个分区,则必须将 OVER 子句与 PARTITION BY 子句一起使用。 PartitionId 列必须指定为 TIMESTAMP BY OVER 列的一部分。

  4. 如果使用 TIMESTAMP BY OVER 子句,则必须在流之间联接时,在 GROUP BY 语句和所有 JOIN 谓词中将 子句中的列名用作分组键。

  5. 在 SELECT 语句或任何其他查询子句中创建的列不能在 TIMESTAMP BY 子句中使用,必须使用输入有效负载中的字段。 例如, CROSS APPLY 的结果不能用作 TIMESTAMP BY 的目标值。 但是,可以使用一个执行 CROSS APPLY 的 Azure 流分析作业,并使用另一个作业来执行 TIMESTAMP BY。

  6. System.Timestamp () 不能在 TIMESTAMP BY 中使用,因为 TIMESTAMP BY 是建立 System.Timestamp () 值的内容。

示例

示例 1 - 从有效负载访问时间戳字段

使用 EntryTime 有效负载中的字段作为事件时间戳

SELECT  
      EntryTime,  
      LicensePlate,  
      State   
FROM input TIMESTAMP BY EntryTime  

示例 2 - 使用有效负载中的 UNIX 时间作为事件时间戳

UNIX 系统通常使用 POSIX (或 Epoch) 时间定义为自 1970 年 1 月 1 日星期四 UTC) 00:00:00 协调世界时 (经过的毫秒数。

此示例演示如何使用包含 Epoch time 的数字“epochtime”字段作为事件时间戳。

SELECT  
      System.Timestamp(),  
      LicensePlate,  
      State  
FROM input TIMESTAMP BY DATEADD(millisecond, epochtime, '1970-01-01T00:00:00Z')  

示例 3 - 异类时间戳

假设处理包含两种类型的事件“A”和“B”的异类数据流。 事件“A”在字段“timestampA”中具有时间戳数据,而事件“B”在字段“timestampB”中具有时间戳。

此示例演示如何编写 TIMESTAMP BY,以便能够处理这两种类型的事件/时间戳。

SELECT  
      System.Timestamp(),  
      eventType,  
      eventValue,  
FROM input TIMESTAMP BY  
      (CASE eventType   
            WHEN 'A' THEN timestampA  
            WHEN 'B' THEN timestampB  
      ELSE NULL END) 

示例 4 - 处理分区查询中的多个时间线

处理来自不同发送方的数据 (收费站) ,而无需对不同的收费站 ID 应用时间策略。 输入数据基于 TollId 进行分区。

SELECT
      TollId,
      COUNT(*) AS Count
FROM input
      TIMESTAMP BY EntryTime OVER TollId, PartitionId
      PARTITION BY PartitionId
GROUP BY TUMBLINGWINDOW(minute,3), TollId, PartitionId

另请参阅

System.Timestamp ()
时间偏差策略
了解 Azure 流分析中的时间处理
Unix 时间