為什麼要在 Orleans 中使用串流?
已經有各種不同的技術可讓您建置串流處理系統。 其中包括永久儲存串流資料的系統 (例如,事件中樞和 Kafka),以及透過串流資料表達計算作業的系統 (例如,Azure 串流分析、Apache Storm 和 Apache Spark Streaming)。 這些是絕佳的系統,可讓您建置有效率的資料串流處理管線。
現有系統的限制
不過,這些系統不適用於對串流資料進行精細的自由格式計算。 上述串流計算系統都可讓您指定以相同方式套用至所有串流項目之作業的統一資料流程圖表。 當資料是統一的,而且您想要在此資料上表達相同的轉換、篩選或彙總作業集時,這是功能強大的模型。 但是還有其他使用案例,您需要在不同的資料項目上表達基本不同的作業。 此外,在此處理的部分過程中,您偶爾需要進行外部呼叫,例如叫用一些任意 REST API。 統一資料流程處理引擎不支援這些案例、以有限且受限的方式支援,或支援的效率不佳。 這是因為其原本就已針對大量類似項目進行最佳化,而且通常受限於表達性、處理。 Orleans 串流會以這些其他案例為目標。
動機
這一切都從 Orleans 使用者的要求開始,以支援從精細度方法呼叫傳回一連串的項目。 如您所見,這只是冰山一角。 其需求遠遠不止於此。
Orleans 串流的一般案例是當您有每個使用者串流,而且您想要在個別使用者的內容中執行每個使用者的不同處理。 我們可能有數百萬個使用者,但其中有些使用者對天氣感興趣,而且可以訂閱特定位置的天氣警示,而有些使用者對運動賽事感興趣;其他人則正在追蹤特定發行小眾測試版的狀態。 處理這些事件需要不同的邏輯,但是您不會想要執行兩個獨立的串流處理執行個體。 有些使用者只對特定股票感興趣,而且只有在套用特定外部條件時,此條件不一定是串流資料的一部分 (因此必須在處理過程中於執行階段動態檢查)。
使用者隨時都會改變興趣,因此其對於特定事件串流的訂閱會動態來來去去,因此串流拓撲會動態且快速地變更。 在這樣的基礎上,每個使用者的處理邏輯也會根據使用者狀態和外部事件,動態演進和變更。 外部事件可能會修改特定使用者的處理邏輯。 例如,在遊戲作弊偵測系統中,探索到新的作弊方法時,需要以新的規則更新處理邏輯,以偵測這個新的違規。 當然這必須完成,而不會中斷進行中的處理管線。 大量資料流程處理引擎不是為了支援這類案例而建置。
這類系統必須在數部網路連線的電腦上執行,而不是在單一節點上執行,這一點不言而喻。 因此,處理邏輯必須在伺服器叢集之間以可調整且彈性的方式散發。
新的需求
我們發現串流處理系統有 4 個基本需求,可讓其以上述案例為目標。
- 彈性串流處理邏輯
- 支援高度動態拓撲
- 精細的串流細微性
- Distribution
彈性串流處理邏輯
我們希望系統支援以不同方式表達串流處理邏輯。 上述的現有系統需要開發人員撰寫宣告式資料流程計算圖表,通常是遵循功能性程式設計樣式。 這會限制處理邏輯的表達性和彈性。 Orleans 串流與處理邏輯的表達方式不同。 可以使用資料流程的形式表達 (例如,藉由使用 .NET 中的 Reactive Extensions (Rx));以功能性程式的形式表達;以宣告式查詢的形式表達;或以一般命令式邏輯的形式表達。 邏輯可以是具狀態或無狀態,也可能沒有副作用,而且可以觸發外部動作。 所有能力都會提供給開發人員。
支援動態拓撲
我們希望系統允許動態演進拓撲。 上述的現有系統通常僅限於靜態拓撲,其部署時間固定且無法在執行階段演進。 在下列資料流程運算式範例中,所有項目都不錯且簡單,直到您需要變更它為止。
Stream.GroupBy(x=> x.key).Extract(x=>x.field).Select(x=>x+2).AverageWindow(x, 5sec).Where(x=>x > 0.8) *
變更 Where 篩選中的閾值條件、新增 Select 陳述式,或在資料流程圖表中新增另一個分支,並產生新的輸出串流。 在現有的系統中,在未卸除整個拓撲並從頭開始重新啟動資料流程的情況下,就無法這樣做。 實際上,這些系統會設定現有計算的檢查點,而且能夠從最新的檢查點重新啟動。 不過,這類重新啟動對產生即時結果的線上服務是干擾性且成本高昂的。 當我們談論大量執行這類運算式時,此類重新啟動會變得特別不切實際,這些運算式會以類似但不同的 (每個使用者、每部裝置等) 參數執行,且持續變更。
我們想要讓系統在執行階段允許串流處理圖表演進、將新的連結或節點新增至計算圖表,或變更計算節點內的處理邏輯。
精細的串流細微性
在現有的系統中,抽象概念的最小單位通常是整個流程 (拓撲)。 不過,我們的許多目標案例都需要拓撲中的個別節點/連結本身成為邏輯實體。 如此一來,每個實體都可以獨立管理。 例如,在組成多個連結的巨量串流拓撲中,不同的連結可以有不同的特性,而且可以透過不同的實體傳輸來實作。 有些連結可以透過 TCP 通訊端,而其他連結則透過可靠的佇列。 不同的連結可以有不同的傳遞保證。 不同的節點可以有不同的檢查點策略,而且其處理邏輯可以使用不同的模型或甚至是不同的語言表達。 現有系統中通常不可能有這樣的彈性。
抽象和彈性引數的單位類似於 SoA (服務導向結構) 與執行者的比較。 動作項目系統允許更多彈性,因為每個動作項目基本上都是獨立管理的「小型服務」。 同樣地,我們希望串流系統允許這類精細的控制。
Distribution
當然,我們的系統應該具有「良好分散式系統」的所有屬性。 其中包含:
- 可擴縮性 - 支援大量的串流和計算元素。
- 彈性 - 允許新增/移除資源,以根據負載成長/縮小。
- 可靠性 - 可從失敗復原
- 效率 - 有效率地使用基礎資源
- 回應性 - 啟用近乎即時的案例。
這些是我們所知,建置 Orleans 串流的需求。
釐清:Orleans 目前不直接支援撰寫宣告式資料流程運算式,如上述範例所示。 目前的 Orleans 串流 API 是較低階的建置組塊,如這裡所述。 提供宣告式資料流程運算式是我們未來的目標。