在這篇論文之前 — 它所降落的世界
Flink 誕生於 Map-Reduce 時代,運算與狀態放在同一批機器上,它的狀態管理也忠實反映這一點:keyed state 事先切成 key-group,每個 stream task 以 single-writer 語意獨佔自己的分割,內嵌後端(本機磁碟上的 RocksDB,或 Java heap 上的 map)在主執行緒上同步服務每一次讀寫。Checkpoint 則是由 Job Manager 往來源注入 marker 所驅動的非同步兩階段提交:marker 對齊之後,後端先同步複製一份本機狀態,再非同步上傳到外部 DFS,Job Manager 只保管檔案參考供復原使用。到了 2020 年代中期,部署樣貌完全變了——Kubernetes 上的容器化作業、以 CPU/記憶體/磁碟綁在一起販售的雲端 compute unit、便宜的物件儲存,以及頻寬大幅拉高的資料中心內部網路。工作負載也同步長大:2024 年雙 11 期間,阿里巴巴的 Flink 基礎設施吸收了每秒超過 44 億筆的進站資料流,而一個保存 60 天訂單與物流更新的物流作業,狀態量落在數百 GB 到 TB 之間。每個容器底下那顆本機磁碟,就這樣悄悄變成決定你要租幾台機器、重啟要等多久的關鍵。
術語 — 依本篇論文的用法
- 分離式狀態管理(disaggregated state management)
- Flink 2.0 的架構:以遠端 DFS 作為活躍工作狀態的主要儲存,本機記憶體與磁碟只當快取;相對於 Flink 1.x 的內嵌後端,權威狀態是放在本機磁碟上的。
- ForSt(For Streaming)
- Flink 2.0 的分離式狀態儲存:一個 LSM-tree 引擎,檔案透過 Unified File System 層讀寫分散式檔案系統,並具備分層本機快取、checkpoint 檔案共享與選用的遠端壓縮合併。
- Unified File System(UFS)
- ForSt 內部的一層,對 HDFS、OSS、S3 提供單一邏輯檔案視圖,隱藏它們在可見性語意上的差異,並維護邏輯檔案到實體位置的對應與參考計數,使 link 與 move 不需要複製資料。
- Asynchronous Execution Controller(AEC)
- 每個 task 內部負責排程非同步狀態存取的元件,同一時間只允許同一個 key 有一個運算在飛行中,並把衝突的記錄暫存起來,讓亂序執行仍然產生 Flink 的 per-key FIFO 順序。
- Key Accounting Unit
- AEC 的記帳結構,追蹤所有進行中運算的 key——非狀態運算、狀態存取與回呼都算——並把 key 已在飛行中的記錄導向 blocking buffer。
- Event-time epoch
- 兩個相鄰 watermark 之間的區間,作為非同步進度追蹤的單位;接收記錄時為 OPEN,被下一個 watermark 封住後為 CLOSED,其中所有記錄都完整處理完畢後為 FINISHED。
- Async draining
- 在非同步執行下恢復 exactly-once 的步驟:對齊的 checkpoint marker 抵達時,任務阻擋後續輸入,等待先前所有狀態存取與回呼完成,才做本機 checkpoint 並把 marker 往下游轉發。
- Compute Unit(CU)
- 容器化 Flink 服務的綑綁計價單位;在阿里雲,一個 CU 是 1 個 CPU 核心加 4 GB 記憶體與 20 GB 磁碟,月費約 43 美元,所以在 Flink 1.x 下狀態很大的作業會買到自己用不到的核心。
- 遠端壓縮合併(remote compaction)
- ForSt 的 compaction-as-a-service:由 Flink 任務觸發,但由無狀態的 compactor worker 直接在共享 DFS 上讀寫 LSM 檔案,把壓縮合併的 CPU 與 I/O 移出 task manager。