本書主要分為兩部分。第一部分以核心概念和基本應用為脈絡,介紹了Flink的核心特性(如檢查點機制、時間與窗口、shuffle機制等),部署,DataStream API、Dataset API、Table API的應用,運行時的原理等內容,每一章先對概念做基本的介紹,然后基于應用實例詳細分析Flink的設計思想和源碼實現(xiàn)。第二部分基于對原理的理解,手把手教讀者如何進行定制化的特性開發(fā)和性能提升,能夠讓讀者對Flink的理解有質的飛躍。這一部分內容來自作者大量的工作實踐,所引用例均源自企業(yè)級的真實需求,能夠解決非常復雜的現(xiàn)網(wǎng)問題。
本書從設計思想與特性開發(fā)兩個視角,對Flink框架進行介紹。設計思想篇概述Flink的歷史、應用場景與架構,介紹Flink核心API的使用方式,并分模塊介紹Flink的源碼實現(xiàn)及其設計思想。特性開發(fā)篇基于真實的企業(yè)級代碼運行流程,針對Flink核心功能進行特性開發(fā),幫助讀者解決復雜的業(yè)務難題。
黃偉哲,約翰斯·霍普金斯大學碩士,架構師、軟件開發(fā)工程師、咨詢師,Spark Contributor!度斯ぶ悄芗夹g與大數(shù)據(jù)》譯者,目前就職于美團。在開源大數(shù)據(jù)框架的應用與特性開發(fā)方面有豐富的經(jīng)驗。
第 一部分 設計思想篇
第 1章 序篇 3
1.1 Flink的誕生與發(fā)展 3
1.1.1 Stratosphere項目 3
1.1.2 Apache Flink的發(fā)展 4
1.2 Flink的應用場景 5
1.2.1 事件驅動型應用 5
1.2.2 數(shù)據(jù)分析型應用 5
1.2.3 數(shù)據(jù)管道型應用 9
1.3 Flink的核心特性與架構 9
1.3.1 核心特性 9
1.3.2 架構 10
1.4 準備工作 11
1.5 總結 12
第 2章 Flink編程 13
2.1 API層級 13
2.2 DataStream API 14
2.2.1 DataStream版本的
WordCount 14
2.2.2 數(shù)據(jù)源 16
2.2.3 數(shù)據(jù)的轉換操作 16
2.2.4 數(shù)據(jù)的輸出 20
2.2.5 重分區(qū) 21
2.3 DataSet API 21
2.3.1 DataSet版本的WordCount 21
2.3.2 數(shù)據(jù)源 22
2.3.3 數(shù)據(jù)的轉換操作 22
2.3.4 數(shù)據(jù)的輸出 24
2.3.5 重分區(qū) 25
2.4 Table API 25
2.4.1 Table API版本的WordCount 25
2.4.2 初始化執(zhí)行環(huán)境 26
2.4.3 獲取Table對象 28
2.4.4 Table API中的轉換操作及輸出 28
2.5 SQL 34
2.6 總結 34
第3章 Flink API層的實現(xiàn)原理 36
3.1 DataStream API 37
3.1.1 StreamExecutionEnvironment執(zhí)行環(huán)境 37
3.1.2 Function接口分析 42
3.1.3 StreamOperator算子分析 45
3.1.4 轉換操作分析 48
3.1.5 數(shù)據(jù)流相關類分析 53
3.2 DataSet API 59
3.2.1 ExecutionEnvironment執(zhí)行環(huán)境 59
3.2.2 InputFormat和OutputFormat 62
3.2.3 數(shù)據(jù)集相關類分析 63
3.3 Table API和SQL 68
3.4 總結 71
第4章 Flink的執(zhí)行圖 72
4.1 StreamGraph的生成 73
4.1.1 StreamGraphGenerator分析 73
4.1.2 StreamGraph分析 77
4.1.3 StreamNode和StreamEdge 80
4.2 Plan的生成 81
4.2.1 OperatorTranslation分析 82
4.2.2 Plan分析 84
4.3 從StreamGraph到JobGraph 85
4.3.1 StreamingJobGraphGenerator分析 87
4.3.2 JobGraph分析 93
4.3.3 JobVertex、JobEdge和IntermediateDataSet 94
4.4 從Plan到JobGraph 95
4.5 從JobGraph到ExecutionGraph 96
4.5.1 ExecutionGraphBuilder分析 98
4.5.2 ExecutionGraph分析 99
4.5.3 ExecutionJobVertex、ExecutionVertex和Execution分析 102
4.5.4 IntermediateResult、IntermediateResultPartition和ExecutionEdge 106
4.6 總結 108
第5章 Flink的運行時架構 109
5.1 客戶端代碼的運行 110
5.2 高可用相關組件 115
5.2.1 EmbeddedHaServices 115
5.2.2 EmbeddedLeaderService 117
5.3 派發(fā)器的初始化與啟動 122
5.4 資源管理器的初始化與啟動 128
5.5 TaskExecutor的初始化與啟動 131
5.6 JobMaster的初始化與啟動 134
5.7 總結 137
第6章 任務調度 138
6.1 調度器 138
6.1.1 調度器的基本構成與初始化 139
6.1.2 構造ExecutionGraph 142
6.2 調度拓撲 143
6.3 調度策略 147
6.3.1 EagerSchedulingStrategy 147
6.3.2 LazyFromSourcesSchedulingStrategy 149
6.3.3 InputDependencyConstraintChecker 152
6.4 調度過程的實現(xiàn) 157
6.4.1 開始調度 157
6.4.2 更新任務狀態(tài) 159
6.4.3 調度或更新消費者 163
6.5 任務的部署 163
6.6 Execution對象在調度過程中的行為 166
6.7 總結 173
第7章 任務的生命周期 174
7.1 任務的提交 174
7.1.1 TaskDeploymentDescriptor 176
7.1.2 ResultPartitionDeployment Descriptor 178
7.1.3 InputGateDeployment Descriptor 180
7.1.4 ShuffleDescriptor 181
7.1.5 ProducerDescriptor和PartitionDescriptor 185
7.1.6 TaskDeploymentDescriptor的提交 188
7.2 任務的初始化 189
7.2.1 Task的初始化 189
7.2.2 ResultPartition的初始化 191
7.2.3 InputGate的初始化 194
7.3 任務的執(zhí)行 197
7.3.1 StreamTask的初始化 202
7.3.2 StreamTask中的重要概念 204
7.3.3 StreamTask的實現(xiàn)類 219
7.3.4 StreamTask的生命周期 222
7.3.5 DataSourceTask、BatchTask和DataSinkTask 227
7.4 總結 237
第8章 數(shù)據(jù)傳輸 238
8.1 基本概念與設計思想 238
8.1.1 從邏輯執(zhí)行圖到物理執(zhí)行圖 239
8.1.2 用同一套模型應對批處理和流處理 242
8.1.3 混洗 242
8.1.4 流量控制 245
8.2 數(shù)據(jù)的輸出 252
8.2.1 ResultPartitionType 253
8.2.2 ResultPartitionWriter 256
8.2.3 ResultSubpartition 262
8.3 數(shù)據(jù)的讀取 265
8.3.1 ResultSubpartitionView 266
8.3.2 InputGate 269
8.3.3 InputChannel 273
8.4 反壓機制的原理 278
8.5 總結 283
第9章 時間與窗口 284
9.1 基本概念和設計思想 284
9.1.1 從批處理到流處理 284
9.1.2 數(shù)據(jù)流模型的設計思想 287
9.1.3 Flink中與窗口操作相關的核心概念 289
9.2 WindowedStream 290
9.3 窗口相關模型的實現(xiàn) 292
9.3.1 Window類 292
9.3.2 WindowAssigner類 293
9.3.3 Trigger類 294
9.3.4 Evictor類 296
9.4 WindowOperator 297
9.5 水位線 299
9.5.1 產生水位線 300
9.5.2 多個數(shù)據(jù)流傳來的水位 303
9.6 定時器 304
9.7 總結 307
第 10章 狀態(tài)與容錯 308
10.1 基本概念與設計思想 308
10.1.1 狀態(tài)與容錯的基本概念 308
10.1.2 Hadoop與Spark如何設計容錯機制 311
10.1.3 Flink中容錯機制的設計思想 311
10.1.4 Flink的狀態(tài)與容錯機制的核心概念 313
10.2 狀態(tài)存儲 315
10.2.1 檢查點的觸發(fā) 316
10.2.2 柵欄的傳輸 323
10.2.3 狀態(tài)數(shù)據(jù)的更新和存儲 331
10.2.4 元信息的存儲 336
10.3 狀態(tài)恢復 341
10.3.1 元信息的讀取 342
10.3.2 狀態(tài)的重分配 344
10.3.3 狀態(tài)數(shù)據(jù)的恢復 347
10.4 狀態(tài)的重分配策略 349
10.4.1 操作符狀態(tài)的重分配 350
10.4.2 鍵控狀態(tài)的重分配 352
10.5 總結 353
第二部分 特性開發(fā)篇
第 11章 動態(tài)調整并行度 357
11.1 模型設計 357
11.1.1 傳統(tǒng)模型的局限 357
11.1.2 DS2模型的核心概念 358
11.1.3 算法原理 359
11.1.4 架構設計 360
11.1.5 使用DS2模型的注意事項 361
11.2 指標收集 361
11.3 指標管理 364
11.4 總結 366
第 12章 自適應查詢執(zhí)行 367
12.1 Flink框架下的自適應查詢執(zhí)行 368
12.1.1 執(zhí)行階段的劃分 368
12.1.2 優(yōu)化流程 368
12.1.3 優(yōu)化策略 370
12.2 統(tǒng)計信息的收集 373
12.3 執(zhí)行圖與調度拓撲的修改 374
12.4 上下游關系的建立 377
12.5 總結 378
第 13章 Flink Sort-Merge Shuffle 379
13.1 混洗機制的對比 379
13.2 Flink混洗機制 381
13.3 Blink混洗的數(shù)據(jù)流轉 382
13.3.1 ExternalResultPartition 383
13.3.2 PartitionMergeFileWriter 384
13.4 Blink混洗的Sort-Merge過程 386
13.4.1 PushedUnilateralSort Merger 387
13.4.2 NormalizedKeySorter 390
13.4.3 排序線程 393
13.4.4 溢寫線程 393
13.4.5 合并線程 395
13.5 文件的讀取和元信息管理 398
13.5.1 ExternalBlockResultPartition Manager 398
13.5.2 ExternalBlockResultPartition Meta 399
13.5.3 ExternalBlockSubpartition View 400
13.6 總結 402
第 14章 修改檢查點的狀態(tài) 403
14.1 狀態(tài)修改的原理 403
14.1.1 狀態(tài)元信息的讀取 404
14.1.2 狀態(tài)數(shù)據(jù)的讀取 405
14.2 狀態(tài)處理器API 407
14.2.1 數(shù)據(jù)的讀取 409
14.2.2 數(shù)據(jù)的寫出 413
14.3 總結 414