分佈式計算中,Flink會將算子(operator) 的子task鏈式組成tasks,每一個task由一個線程執行。把算子鏈化爲tasks是一個很是好的優化:它減小了線程之間的通訊和緩衝,並且還能增長吞吐量下降延遲。鏈化操做的配置詳情可參考: chaining docshtml
下圖中dataflow有5個subtasks,所以有5個線程併發進行處理。 後端
Flink運行時包含兩類進程:api
至少須要一個JobManager。高可用部署下會有多個JobManagers,其中一個做爲leader,其他處於standby狀態。緩存
至少須要一個TaskManager。安全
有多種方式能夠啓動JobManagers和TaskManagers:直接在計算機上啓動做爲 standalone cluster,在容器中或者由資源管理器YARN 或者 Mesos啓動。 TaskManagers鏈接到JobManagers後,會通知JobManagers本身已可用,接着被分配工做。數據結構
client 不做爲運行時(runtime)和程序執行的一部分,只是用於準備和發送dataflow做業給JobManager。 所以客戶端能夠斷開鏈接,或者保持鏈接以接收進度報告。客戶端能夠做爲觸發執行的Java/Scala 程序的一部分或者運行在命令行進程中 ./bin/flink run ...。併發
每一個worker(TaskManager)都是一個JVM 進程,而且能夠在不一樣的線程中執行一個或多個subtasks。每一個worker用task slots(任務槽位) (至少有一個)來控制能夠接收多少個tasks。分佈式
每一個task slot表明TaskManager中一個固定的資源子集。例如,有3個slots的TaskManager會將它的內存資源劃分紅3份分配給每一個slot。劃分資源意味着subtask不會和來自其餘做業的subtasks競爭資源,可是也意味着它只擁有固定的內存資源。注意劃分資源不進行CPU隔離,只劃份內存資源給不一樣的tasks。高併發
經過調整slots的個數進而能夠調整subtasks之間的隔離方式。當每一個TaskManager只有一個slot時,意味着每一個task group運行在不一樣的JVM中(例如:可能在不一樣的container中)。當每一個TaskManager有多個slots時,意味着多個subtasks能夠共享同一個JVM。同一個JVM中的tasks共享TCP鏈接(經過多路複用技術)和心跳消息。可能還會共享數據集和數據結構,從而減小每一個task的開銷。優化
默認狀況下,只要subtasks是來自同一個job,Flink容許不一樣tasks的subtasks共享slots。所以,一個slot可能會負責job的整個pipeline。容許slot sharing有兩個好處:
APIs還包含了一種 *資源組(resource group)*機制,用來防止沒必要要的slot sharing。
經驗來說,task slots的默認值應該與CPU核數一致。在使用超線程下,一個slot將會佔用2個或更多的硬件資源。
key/values索引存儲的準確數據結構取決於選擇的 state backend。其中一個 state backend將數據存儲在內存hash map中,另外一個 state backend使用RocksDB做爲key/value 存儲。 除了定義存儲狀態的數據結構, state backends還實現了獲取 key/value狀態的時間點快照的邏輯,並將該快照存儲爲checkpoint的一部分。
使用Data Stream API編寫的程序能夠從一個savepoint恢復執行。Savepoints容許在不丟失任何狀態的狀況下修改程序和Flink集羣。
Savepoints 是手動觸發的checkpoints,它依賴常規的checkpointing機制,生成程序快照並將其寫入到狀態後端。在運行期間,worker節點週期性的生成程序快照併產生checkpoints。在恢復重啓時只會使用最後成功的checkpoint。而且只要有一個新的checkpoint生成時,舊的checkpoints將會被安全地丟棄。
Savepoints與週期性觸發的checkpoints很相似,可是其式由由用戶觸發的,且當更新的checkpoints完成時,老的checkpoint不會自動失效。能夠經過命令行或者在取消一個job時調用REST API的方式建立Savepoints。