了解 Azure 串流分析中的時間處理

在此文章中,您將了解如何做出設計決定來解決 Azure 串流分析作業中實際的時間處理問題。 時間處理設計決策與事件順序因素有密切的關聯。

背景時間概念

為了建構討論基礎,我們將定義一些背景概念:

  • 事件時間:原始事件的發生時間。 例如,當行駛於高速公路的車輛接近收費站時。

  • 處理時間:事件到達處理系統且被發現的時間。 例如,當收費站感應器發現車輛,且電腦系統以所需時間處理資料時。

  • 浮水印:事件時間標記,可指出已將哪些時間點事件輸入至串流處理器。 浮水印讓系統明確指出擷取事件的進度。 依據資料流的特質,內送事件資料永遠不會停止,因此浮水印可指出資料流中某個時間點的進度。

    浮水印是重要的概念。 浮水印可讓串流分析判斷系統何時可產生完整、正確、可重複且不需撤回的結果。 此處理可透過可預測且可重複的方式完成。 例如,若因某些錯誤處理情況而需要重新計數,浮水印將是安全的起始點和結束點。

如需此主題的相關資源,請參閱 Tyler Akidau 的部落格文章串流 101 \(英文\) 和串流 102 \(英文\)。

選擇最理想的開始時間

串流分析有兩個選項可供使用者挑選事件時間:抵達時間與應用時間。

抵達時間

事件到達來源時,系統會為輸入來源指派抵達時間。 您可以針對事件中樞輸入使用 EventEnqueuedUtcTime 屬性、針對 IoT 中樞輸入使用 IoTHub.EnqueuedTime 屬性,以及針對 Blob 輸入使用 BlobProperties.LastModified 屬性來存取抵達時間。

系統預設會使用抵達時間,且其最適合用於不需要時態性邏輯的資料封存案例。

應用時間 (也稱為事件時間)

產生事件時會指派應用時間,且會成為事件承載的一部分。 若要按照應用時間處理事件,請在 SELECT 查詢中使用 Timestamp by 子句。 如果 Timestamp by 不存在,將按照抵達時間處理事件。

請務必在涉及時態性邏輯的情況下於承載中使用時間戳記,以將來源系統或網路中的延遲納入考量。 指派給事件的時間會在 SYSTEM.TIMESTAMP \(英文\) 中提供。

Azure 串流分析中的時間行進方式

使用應用時間時,時間行進方式會取決於內送事件。 串流處理系統難以確定是否有事件,或事件是否延遲。 因此,針對各個輸入分割區,Azure 串流分析會透過下列方式產生啟發式浮水印:

  • 只要有任何內送事件,浮水印就會是串流分析到目前為止看到的最大事件時間,減去順序錯亂容錯時間範圍大小。

  • 沒有內送事件時,浮水印就是目前的預估抵達時間,減去延遲抵達容錯時間範圍。 預估抵達時間是系統上次看到輸入事件的時間之後所經過的時間,加上該輸入事件的抵達時間。

    抵達時間僅可預估,因為真正的抵達時間會由輸入事件的訊息代理程式 (例如事件中樞) 產生,而不是在處理事件的 Azure 串流分析 VM 上產生。

除了產生浮水印以外,此設計還能提供兩個額外的用途:

  1. 無論是否有內送事件,系統都會適時產生結果。

    您可以控制顯示輸出結果的及時程度。 在 Azure 入口網站中,您可以在串流分析作業的 [事件順序] 頁面上設定 [順序錯亂事件] 設定。 進行該設定時,請適當取捨時效性與事件資料流中順序錯亂事件的容錯。

    延遲抵達容錯時間範圍為持續產生浮水印的必要項目,即便是在沒有內送事件的情況下。 有時候,可能會有某段期間沒有內送事件傳入,例如事件輸入資料流較為疏鬆時。 如果在輸入事件訊息代理程式中使用了多個分割區,這個問題會更嚴重。

    串流資料處理系統若沒有延遲抵達容錯時間範圍,在輸入較疏鬆,且使用了多個資料分割時,可能會發生輸出延遲的狀況。

  2. 系統行為必須是可重複的。 可重複性是串流資料處理系統的重要屬性。

    浮水印衍生自抵達時間和應用時間。 這兩者都會保存在事件訊息代理程式中,因此可重複使用。 在沒有事件的情況下預估抵達時間時,Azure 串流分析會在日誌中記錄預估的抵達時間,以針對失敗復原於重新執行期間提供可重複性。

請注意,當您選擇使用抵達時間作為事件時間時,就不需要設定順序錯亂容錯和延遲抵達容錯。 由於抵達時間必定會在輸入事件的訊息代理程式中遞增,因此 Azure 串流分析會直接忽略這些設定。

延遲抵達事件

根據延遲抵達容錯時間範圍的定義,針對每個內送事件,Azure 串流分析會將事件時間抵達時間比較。 如果事件時間位於容錯時間範圍之外,您可以設定系統來卸除該事件,或是調整事件的時間來使其位於容錯之內。

在浮水印產生後,服務有可能收到事件時間低於浮水印的事件。 您可以將服務設定成會卸除那些事件,或將事件的時間調整為浮水印值。

在調整的過程中,事件的 System.Timestamp 會設為新的值,但 [事件時間] 欄位本身不會變更。 只有進行此調整時,事件的 System.Timestamp 才可能與 [事件時間] 欄位中的值不同,而且這種情況可能會導致非預期的結果。

使用子串流處理時間差異

在不同事件傳送端之間的時間大致維持同步的情況下,先前所說明的啟發學習法浮水印產生機制大多可正常運作。 但在實際情況下,尤其是許多 IoT 案例中,系統幾乎無法控制事件傳送端的時鐘。 事件傳送端可能是各式各樣的裝置,且各自採用不同版本的軟硬體。

與其使用輸入分割區中的所有事件均通用的浮水印,串流分析還有另一個稱為子串流的機制。 您也可以撰寫使用 TIMESTAMP BY 子句和關鍵字 OVER 的作業查詢,藉以在您的作業中使用子串流。 若要指定子資料流,請在 OVER 關鍵字後面提供索引鍵資料行名稱 (例如 deviceid),使系統依據該資料行套用時間原則。 每個子串流會分別取得其本身的浮水印。 在處理事件傳送端之間的時鐘誤差較大或網路延遲的問題時,此機制將有助於及時的輸出產生。

子串流是 Azure 串流分析所提供的獨特解決方案,其他串流資料處理系統並不提供。

使用子串流時,串流分析會對內送事件套用延遲抵達容錯時間範圍。 延遲抵達容錯會決定不同的子串流可與彼此分隔的最大間隔。 例如,如果裝置 1 位於時間戳記 1,且裝置 2 位於時間戳記 2,則最為延遲的抵達容錯就是時間戳記 2 減去時間戳記 1。 預設設定為 5 秒,且對於具有不同時間戳記的裝置而言很可能太小。 建議您一開始先使用 5 分鐘,再根據裝置時鐘的誤差模式進行調整。

早期抵達事件

您可能已注意到名為提早抵達時間範圍的另一個概念,其與延遲抵達容錯時間範圍的概念相對應。 此時間範圍會固定為 5 分鐘,且其用途與延遲抵達容錯時間範圍不同。

由於 Azure 串流分析保證完整結果,因此您只能將作業開始時間指定為作業的第一個輸出時間,而非輸入時間。 必須要有作業工作開始時間,才會處理完整的時間範圍,而不是只從時間範圍中間開始處理。

串流分析會從查詢規格衍生開始時間。 不過,由於輸入事件的訊息代理程式僅會依據抵達時間編製索引,因此系統必須將開始事件時間轉譯為抵達時間。 系統可以從輸入事件訊息代理程式中的那個時間點開始處理事件。 在有提早抵達時間範圍限制的情況下,轉譯會很簡單:開始事件時間減去 5 分鐘的提早抵達時間範圍。 此計算也表示系統會將事件時間看起來比抵達時間提早 5 分鐘以上的所有事件卸除。 提早輸入事件計量會在系統卸除事件時遞增。

此概念可確保無論您從何處開始要輸出,處理程序都是可重複的。 若沒有這類機制,就無法保證可重複性,儘管有許多其他串流處理系統宣稱有此功能。

事件順序時間容錯的副作用

串流分析作業有數個「事件順序」選項。 其中有兩個可在 Azure 入口網站中設定:「順序錯亂事件」設定 (順序錯亂容錯),和「延遲抵達的事件」設定 (延遲抵達容錯)。 早期抵達容錯是固定,且無法調整。 串流分析會使用這些時間原則來提供穩固的保證。 不過,這些設定有時候會一些非預期的影響:

  1. 意外過早傳送事件。

    早期事件應該不會正常輸出。 但如果傳送端的時鐘太快,就有可能將早期事件傳送至輸出。 所有早期抵達的事件都會被捨棄,因此您在輸出中不會看到任何這類事件。

  2. 將舊事件傳送至事件中樞給 Azure 串流分析處理。

    舊事件在初期可能無害,因為延遲抵達容錯的作用,可能會使舊事件遭到捨棄。 如果事件太舊,在事件擷取期間將會更改 System.Timestamp 值。 由於有此行為,Azure 串流分析目前較適用於接近即時的事件處理案例,而不是歷史事件處理案例。 在某些情況下,您可以將「延遲抵達的事件」時間設為最大可能值 (20 天),以因應此問題。

  3. 輸出似乎有延遲的現象。

    第一個浮水印會在下列計算出的時間產生:系統到目前為止觀察到的最大事件時間,減去順序錯亂容錯時間範圍大小。 根據預設,順序錯亂容錯會設定為零 (00 分 00 秒)。 當您將其設為較高的非零時間值時,基於計算出來的第一個浮水印時間,串流作業的第一個輸出將會延遲達該時間值 (或以上)。

  4. 輸入較疏鬆。

    給定的分割區中沒有輸入時,浮水印時間的計算方式為抵達時間減去延遲抵達容錯時間範圍。 因此,如果輸入事件不頻繁且疏鬆,輸出可能會延遲達該時間量。 「延遲抵達的事件」的預設值為 5 秒。 舉例來說,在逐一傳送輸入事件時,您應該會發現某種程度的延遲。 如果您將「延遲抵達的事件」時間範圍設為較大的值,延遲可能會更嚴重。

  5. System.Timestamp 值與 [事件時間] 欄位中的時間不同。

    如前所述,系統就會依據順序錯亂容錯或延遲抵達容錯時間範圍來調整事件時間。 所調整的是事件的 System.Timestamp 值,而不是 [事件時間] 欄位。 這可用來識別時間戳記所調整的事件。 如果系統因其中一個容錯而變更時間戳記,其通常會是相同的。

可觀察的計量

您可透過 Azure 串流分析作業計量來觀察許多事件排序時間容錯效果。 相關計量如下:

計量 描述
順序錯亂事件 指出已收到、但因順序錯亂而遭到捨棄或調整時間戳記的事件數目。 在 Azure 入口網站中,針對作業在 [事件順序] 頁面上設定 [順序錯亂事件] 設定,將對此計量產生直接的影響。
延遲輸入事件 指出從來源延遲抵達的事件數目。 此計量包含已遭捨棄或已調整時間戳記的事件。 在 Azure 入口網站中,針對作業在 [事件順序] 頁面上設定 [延遲抵達的事件] 設定,將對此計量產生直接的影響。
早期輸入事件 指出從來源提早抵達,但已遭到捨棄或已調整時間戳記 (若早了 5 分鐘以上) 的事件數目。
浮水印延遲 指出串流資料處理作業的延遲。 請參閱下一節的詳細說明。

浮水印延遲詳細資料

浮水印延遲計量的計算方式為處理節點的時鐘時間減去到目前為止發現的最大浮水印。 如需詳細資訊,請參閱浮水印延遲部落格文章

在正常作業下,此計量的值大於 0 的可能原因包括:

  1. 串流管線既有的處理延遲。 此延遲通常是額定的。

  2. 順序錯亂容錯時間範圍導致了延遲,因為浮水印減去了容錯時間範圍的大小。

  3. 延遲抵達時間範圍導致了延遲,因為浮水印減去了容錯時間範圍的大小。

  4. 產生計量的處理節點有時鐘誤差。

此外還有許多其他資源條件約束可能導致串流管線的速度變慢。 浮水印延遲計量可能因下列狀況而產生:

  1. 串流分析中沒有足夠的資源可處理該數量的輸入事件。 若要擴大資源,請參閱了解和調整串流單位

  2. 輸入事件的訊息代理程式內沒有足夠的輸送量,因此受到節流控制。 如需可能的解決方案,請參閱自動擴大 Azure 事件中樞輸送量單位

  3. 輸出接收端未佈建足夠的容量,因此受到節流控制。 可能的解決方案依據所使用的輸出服務類型而有很大的不同。

輸出事件頻率

Azure 串流分析會以浮水印進度作為產生輸出事件的唯一觸發程序。 浮水印衍生自輸入資料,因此在失敗復原期間以及使用者起始的重新處理中,都可重複使用。 使用時間範圍型彙總時,服務只會在時間範圍結束時產生輸出。 在某些情況下,使用者可能會想要查看從時間範圍產生的部分彙總。 Azure 串流分析目前不支援部分彙總。

在其他串流解決方案中,輸出事件可根據外部情況在不同的觸發點具體化。 在某些解決方案中,指定時間範圍的輸出事件有可能會多次產生。 隨著輸入值的調整,彙總結果會變得更精確。 事件一開始可能是推測的,其後再逐漸修訂。 例如,當一個裝置未連接網路時,系統可能會使用預估值。 其後,該裝置連上了網路。 此時,就可將實際的事件資料包含在輸入資料流中。 處理該時間範圍的輸出結果會產生更精確的輸出。

浮水印的說明範例

以下影像說明浮水印在不同的環境中的進程。

下表顯示後續圖表中的範例資料。 請注意,事件時間和抵達時間不盡相同,有時相符,有時則否。

事件時間 抵達時間 deviceId
12:07 12:07 device1
12:08 12:08 device2
12:17 12:11 device1
12:08 12:13 device3
12:19 12:16 device1
12:12 12:17 device3
12:17 12:18 device2
12:20 12:19 device2
12:16 12:21 device3
12:23 12:22 device2
12:22 12:24 device2
12:21 12:27 device3

此圖使用下列容錯:

  • 早期抵達時間範圍為 5 分鐘
  • 延遲抵達時間範圍為 5 分鐘
  • 重新排序時間範圍為 2 分鐘
  1. 下圖顯示浮水印處理這些事件的進程:

    Azure 串流分析浮水印圖

    上圖中值得注意的程序為:

    1. 第一個事件 (device1) 和第二個事件 (device2) 的時間一致,未經調整即完成處理。 浮水印在每個事件後都有進展。

    2. 處理第三個事件 (device1) 時,抵達時間 (12:11) 在事件時間 (12:17) 之前。 此事件提早抵達了 6 分鐘,因此基於 5 分鐘的早期抵達容錯而遭到捨棄。

      經歷此案例中的早期事件後,浮水印並沒有進展。

    3. 第四個事件 (device3) 和第五個事件 (device1) 的時間一致,未經調整即完成處理。 浮水印在每個事件後都有進展。

    4. 處理第六個事件 (device3) 時,抵達時間 (12:17) 和事件時間 (12:12) 低於浮水印層級。 事件時間調整為浮水印層級 (12:17)。

    5. 處理第十二個事件 (device3) 時,抵達時間 (12:27) 比事件時間 (12:21) 早了 6 分鐘。 此時適用延遲抵達原則。 事件時間調整為 (12:22) 而高於浮水印 (12:21),因此無需進一步調整。

  2. 第二個圖中的浮水印進程未套用早期抵達原則:

    Azure 串流分析無早期原則的浮水印圖

    此範例未套用早期抵達原則。 提早抵達的極端值事件大幅提高了浮水印。 請注意,第三個事件 (deviceId1,時間為 12:11) 在此案例中並未遭到捨棄,而浮水印則提高至 12:15。 第四個事件的時間因此往後調整了 7 分鐘 (12:08 到 12:15)。

  3. 最後一個圖中使用了子串流 (透過 DeviceId)。 系統追蹤多個浮水印,每個資料流各一個。 因此,調整過時間的事件較少。

    Azure 串流分析子串流浮水印圖

後續步驟