eKuiper Newsletter 2022-06|離線快取重發機制升級,優化弱網場景使用

EMQX發表於2022-07-11

六月的盛夏時節正是 eKuiper 專案捐獻給 LF Edge 基金會一週年之時。六月初,專案圓滿完成了在基金會的第一次年度 review,並確立了下一年度升級到 Stage 2 的目標。在此我們衷心感謝各位社群貢獻者、合作伙伴和使用者,期待新的一年能有更多夥伴加入到社群的建設中。

我們的開發工作也取得了不錯的進展。月初,小版本 1.5.1 釋出,主要解決了一些使用者問題。在 1.6.0 版本開發方面,我們完成了離線快取和重發機制的升級,更適應邊緣部署中常見的邊雲網路連線易丟失的弱網場景。與此同時,我們補齊了一些 SQL 語法支援,包括 IN/NOT IN 表示式的支援、ORDER BY 對錶達式和別名的支援等,方便使用者編寫更復雜的過濾和排序邏輯。最後,視覺化拖拽能力的開發目前已完成後臺 API 的部分驗證。

離線快取和重發

大資料時代,雲邊協同是主流的計算模式。邊緣計算的一部分結果需要傳送到雲端進行進一步的整合。然而邊雲之間的網路連線常常是不穩定的,網路連線故障時有發生。作為邊緣流式計算引擎,eKuiper 經常有規則將計算結果匯入外部系統,尤其是遠端的外部系統中。這種情況下,我們需要考慮弱網環境的處理:在網路斷開等故障期間,必須對資料進行快取,並在重新連線後重新傳送。

此前,eKuiper 在一定程度上支援 sink 快取。它提供了一個全域性配置來切換快取開啟;系統/規則級配置用於記憶體快取的序列化時間間隔。然而,快取只是在記憶體中和複製到 DB(記憶體的映象)中,並且沒有定義明確的重發策略。六月,我們對快取機制進行了優化,快取將同時儲存在記憶體和磁碟中,這樣快取的容量就變得更大了;它還將持續檢測故障恢復狀態,並在不重新啟動規則的情況下實現自動重新傳送。

流程

快取只發生在 sink 中,因為那是 eKuiper 之外唯一可以傳送資料的地方。每個 sink 都可以配置自己的快取機制。每個 sink 的快取流程是相同的。如果啟用了快取,所有 sink 的事件都會經過兩個階段:首先是將所有內容儲存到快取中;然後在收到 ack 後刪除快取。

  • 錯誤檢測:傳送失敗後,sink 應該通過返回特定的錯誤型別來識別可恢復的失敗(網路等),這將返回一個失敗的 ack,這樣快取就可以被保留下來。對於成功的傳送或不可恢復的錯誤,將傳送一個成功的 ack 來刪除快取。
  • 快取機制:快取將首先被儲存在記憶體中。如果超過了記憶體的閾值,後面的快取將被儲存到磁碟中。一旦磁碟快取超過磁碟儲存閾值,快取將開始 rotate。記憶體中最早的快取將被丟棄,並載入磁碟中最早的快取來代替。
  • 重發策略:如果有一個 ack 正在傳送中,則等待一個成功的 ack 以繼續傳送下個快取資料。否則,當有新的資料到來時,傳送快取中的第一個資料以檢測網路狀況。如果 ack 成功,按順序鏈式傳送所有的快取(mem + disk)。鏈式傳送可定義一個傳送間隔,防止形成訊息風暴。

配置

sink 快取的配置有兩個層次。etc/kuiper.yaml 中的全域性配置,定義所有規則的預設行為。還有一個規則 sink 層的定義,用來覆蓋預設行為。

  • enableCache:是否啟用 sink cache。快取儲存配置遵循 etc/kuiper.yaml 中定義的後設資料儲存的配置。
  • memoryCacheThreshold:要快取在記憶體中的訊息數量。出於效能方面的考慮,最早的快取資訊被儲存在記憶體中,以便在故障恢復時立即重新傳送。這裡的資料會因為斷電等故障而丟失。
  • maxDiskCache:快取在磁碟中的資訊的最大數量。磁碟快取是 FIFO。如果磁碟快取滿了,最早的一頁資訊將被載入到記憶體快取中,取代舊的記憶體快取。
  • bufferPageSize:緩衝頁是批量讀/寫到磁碟的單位,以防止頻繁的IO。如果頁面未滿,eKuiper因硬體或軟體錯誤而崩潰,最後未寫入磁碟的頁面將被丟失。
  • resendInterval:故障恢復後重新傳送資訊的時間間隔,防止資訊風暴。
  • cleanCacheAtStop:是否在規則停止時清理所有快取,以防止規則重新啟動時對過期訊息進行大量重發。如果不設定為 true,一旦規則停止,記憶體快取將被儲存到磁碟中。否則,記憶體和磁碟規則會被清理掉。

目前,該功能的程式碼已經合併到 1.6.0 版本的分支(https://github.com/lf-edge/ek...)中。感興趣的朋友可以自行編譯使用。

列表過濾

在規則引擎中,我們經常需要判斷某個值是否在一個列表中,從而觸發相應的動作。在標準 SQL 語法中,通常使用 IN/NOT IN 表示式進行這樣的過濾。本月,我們實現了 IN 運算子的支援。使用方法支援以下兩種:

  1. 與標準 SQL 語法相同,支援同時設定多個表示式。

    expression [NOT] IN (expression2,...n)
  2. 在 eKuiper 的使用場景中,複雜型別和無模式使用較多,因此也支援直接使用表示式(需要確保為陣列型別)作為右側運算子。

    expression [NOT] IN arrayExpression

1.5.1 版本

月初發布的 1.5.1 版本主要解決問題和小功能更新。主要的功能更新包括:

  • 擴大資料模板的支援範圍。新的版本中新增了 memory sink, edegX sink, tdengine sink 等對資料模板的支援。
  • 支援 window_start() 和 window_end() 作為其他函式的引數。

解決的 bug 包括:

  • 重啟規則後,Neuron 連線失敗問題
  • 外掛更新導致規則語法錯誤時,已執行規則的狀態異常問題
  • 使用共享源時,重啟規則可能隨機導致連線失敗
  • REST API 使用鑑權後的跨域訪問問題

版權宣告: 本文為 EMQ 原創,轉載請註明出處。

原文連結:https://www.emqx.com/zh/blog/ekuiper-newsletter-202206

相關文章