✅ Azure 串流分析
所有數據流事件都有與其相關聯的時間戳。 根據預設,事件中樞和IoT中樞的事件會根據事件中樞或IoT中樞接收事件時時間戳;來自 Blob 記憶體的事件是由 Blob 上次修改時間所時間戳。 如果您重新啟動或重新執行作業,事件的時間戳不會變更。
許多串流應用程式需要使用事件發生的確切時間戳,而不是抵達時間。 例如,在銷售點應用程式中,一個可能需要對應到付款記錄時間的事件時間戳,而不是付款事件到達事件擷取服務的時間。 此外,異地分散式系統和網路等待時間可能會導致無法預測的抵達時間,使得在串流應用程式中使用應用程式時間更可靠。 在這些情況下,TIMESTAMP BY 子句允許指定自定義時間戳值。 值可以是 DATETIME 類型的事件承載或表達式中的任何欄位。 也支援符合 任何 ISO 8601 格式的字串值。
請注意,使用自定義時間戳 (TIMESTAMP BY 子句) 可能會導致 Azure 串流分析在其時間戳方面依序擷取事件,原因有兩個:
- 個別事件產生者可能會有不同的系統時鐘(且扭曲)。
- 來自個別事件產生者的事件可能會在傳輸中延遲,例如,由產生者網站的網路無法使用。
雖然事件產生者之間的混亂可能很大,但來自單一產生者的事件內的混亂通常很小,甚至不存在。 如果查詢只會獨立處理每個事件產生者的數據,則處理每個產生者在其時間軸中的事件比管理產生者之間的時間扭曲更有效率。 Azure 串流分析支持子數據流,方法是指定 OVER <over over spec> 子句,以在獨立時間軸中處理事件。 如需 OVER 子句對作業處理的影響,請參閱『OVER 子句與事件排序互動』。
Syntax
TIMESTAMP BY scalar_expression [OVER <over spec> ]
<over spec> ::=
{ column_name | expression } [,...n ]
Remarks
擷取事件時間戳
您可以使用 System.Timestamp() 屬性,在查詢的任何部分的 SELECT 語句中擷取事件時間戳。
OVER 子句會與事件排序互動
使用 OVER 子句時,會修改 Azure 串流分析的數個事件處理層面:
在超過規格<的單一值元組>內,會套用順序上限容錯。 也就是說,只有在從相同事件產生者的其他事件到達太多順序錯誤時,才會將事件視為順序錯亂。
例如,如果來自相同事件產生者的事件一律排序,而且會導致立即處理,則可以使用 『0』 的值。 另一方面,在這裡使用大型值會導致處理延遲,同時等待順序錯亂的事件進行組合。
全域套用延遲抵達容錯上限(如同未使用 OVER)。 也就是說,如果事件選擇的時間戳(在 TIMESTAMP BY 子句中)離到達時間太遠,就會被視為遲到的事件。
請注意,在這裡使用大型值不會造成處理延遲,而且事件仍會立即處理(或根據順序錯亂的容錯上限)。 數天的值不合理。 不過,使用異常長的值可能會影響處理作業所需的記憶體數量。
每個事件產生者的輸出事件都會在計算時產生,這表示輸出事件可能有順序錯亂的時間戳;不過,它們會依序排列在超過規格<的單一值元組>內。
限制與制約
TIMESTAMP BY OVER 子句具有下列使用限制:
TIMESTAMP BY OVER 子句必須用於查詢的所有輸入,或未用於其中任何輸入。
TIMESTAMP BY OVER 子句僅支援完全平行作業或單一數據分割作業。
如果輸入數據流有多個數據分割,則 OVER 子句必須與 PARTITION BY 子句搭配使用。 PartitionId 資料行必須指定為 TIMESTAMP BY OVER 數據行的一部分。
如果使用 TIMESTAMP BY OVER 子句,子句中的數據行名稱必須在 GROUP BY 語句和所有 JOIN 述詞中當做串流之間聯結時的群組索引鍵使用。
在 SELECT 語句或任何其他查詢子句中建立的數據行不能用於 TIMESTAMP BY 子句中,必須使用輸入承載中的字段。 例如, CROSS APPLY 的結果不能當做 TIMESTAMP BY 的目標值使用。 不過,您可以使用一個執行 CROSS APPLY 的 Azure 串流分析作業,並使用第二個作業來執行 TIMESTAMP BY。
System.Timestamp() 無法用於 TIMESTAMP BY,因為 TIMESTAMP BY 是建立 System.Timestamp() 值的專案。
Examples
範例 1 – 從承載存取時間戳欄位
使用 EntryTime 承載中的欄位作為事件時間戳
SELECT
EntryTime,
LicensePlate,
State
FROM input TIMESTAMP BY EntryTime
範例 2 – 使用來自承載的 UNIX 時間作為事件時間戳
UNIX 系統通常會使用 POSIX (或 Epoch) 時間定義為自 1970 年 1 月 1 日 00:00:00 國際標準時間 (UTC) 起經過的毫秒數。
此範例示範如何使用數值 'epochtime' 字段,包含 Epoch 時間做為事件時間戳。
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 – 處理分割查詢中的多個時間軸
處理來自不同寄件者(收費站)的數據,而不需跨不同的收費站標識碼套用時間原則。 輸入數據會根據 TollId 進行分割。
SELECT
TollId,
COUNT(*) AS Count
FROM input
TIMESTAMP BY EntryTime OVER TollId, PartitionId
PARTITION BY PartitionId
GROUP BY TUMBLINGWINDOW(minute,3), TollId, PartitionId