教材:10710周志遠教授平行程式 https://www.youtube.com/playlist?list=PLS0SUwlYe8cxqw70UHOE5n4Lm-mXFXbZT 20250917 筆記 內容可能有錯僅供參考 在這個章節開始投影片和10710周志遠教授平行程式有差異,接下來以 NTHU-PP-2021 (Chinese) 為主 [NTHU-PP-Chap11-MapReduce-Part1 and 2](https://www.youtube.com/watch?v=OE2K5R-UqnE&list=PLQTDfc8kgjhMKtgumyK0gmEelnTtqJGsp&index=25) 搭配 23A~23D Advancing Programming for MapReduce 今日大綱 1.Hadoop 運作原理與程式 2.MapReduce 程式設計模型 3.Hadoop MapReduce 的執行過程與函式 4.進階程式設計技巧 **1. MapReduce 簡介與版本差異** * **目的**:學習如何撰寫分散式執行的程式,儘管使用者不需要有平行程式設計的概念。 * **作業焦點**:作業將著重於實作 MapReduce 本身,而非 MapReduce 應用。 * **Hadoop (H)**:MapReduce 的一個開源實作,由 Yahoo! 團隊開發,主要使用 Java 語言。 * **版本差異**: * **Hadoop 1.0 與 2.0 (YARN)**:主要差異在於 2.0 增加了資源管理容器 (resource management container),提升了執行上的資源配置優勢,但程式設計模型本身變化不大。 * **Hadoop 3.0**:文中提到當時仍處於 2.0 版本,但基本程式設計差異不大。 * **現今應用**:目前 Hadoop 的使用率較少,Scala Spark 應用更為普遍。但對於解決特定分散式計算問題,Hadoop 仍是重要工具。 **2. Hadoop 運作原理與程式提交** * **管理集群**:Hadoop 是一個管理集群進行分散式計算的軟體。 * **運作流程**:類似於平行程式計算集群: 1. 使用者將程式提交給排程主控端 (schedule master)。 2. 主控端開始產生可分散式計算的任務 (tasks)。 3. 主控端管理這些任務,並處理執行時的錯誤回復 (fault recovery) 等問題。 * **程式執行**:使用者執行一個程式,實際上是在提交一個工作 (job),由 Hadoop 進行排程與執行。 * **程式撰寫**:需要引用 Hadoop 的相關套件 (package)。 **3. Hadoop MapReduce 套件 (Package) 的區別** * **舊版**:`org.apache.hadoop.mapred`。 * **新版**:`org.apache.hadoop.mapreduce`。 * **重要提示**:在撰寫或參考範例程式碼時,切勿混用這兩個套件,否則可能產生奇怪的問題。本課程以 `mapreduce` 套件進行解釋。 **4. MapReduce 程式設計模型** * **Java OO 方式**:透過繼承 (inheritance) 與覆寫 (override) 類別 (class) 中的部分方法來實現。 * **優點**:程式碼量相對較少,只需覆寫特定部分。 * **缺點**:較不直觀,因無法看到整個程式的完整流程。使用者需要了解 Hadoop 框架中各類別的運作方式。 * **可覆寫的函式 (functions)**: * `Mapper class` 中的 `map function`。 * `Reducer class` 中的 `reduce function`。 * `Partitioner class` 中的 `getPartition function`。 * **核心概念**:需要想像這些類別和覆寫的方法如何協同運作,以實現整個 MapReduce 程式的執行過程。 **5. 關鍵類別 (Key Classes)** 除了 Mapper、Reducer 和 Partitioner 函式之外,主要還有兩個核心類別: * **`Configuration` 類別**:主要用於設定集群 (cluster) 的參數,決定 MapReduce 引擎如何根據設定來執行和管理工作。 * **`Job` 類別**:描述一個工作 (job)。一個程式 (program) 可以提交多個工作,甚至協調這些工作的運作,將其視為一個單一應用程式。 * 程式提交工作後,可透過 API 查詢工作狀態 (`map progress`, `reduce progress`)、控制工作 (如 `kill job`, `kill task`) 或修改執行時設定。 * **同步 (Synchronous) 提交**:使用 `waitForCompletion()`,主程式會阻塞 (block) 直到工作完成。 * **非同步 (Asynchronous) 提交**:使用 `submit()`,主程式提交後可繼續執行其他任務,並透過 API 查詢工作狀態或進行控制。 **6. Hadoop MapReduce 的執行過程與函式 (Hadoop's Implementation)** Hadoop 將 MapReduce 的執行過程分為兩個主要階段:Map Phase (M Face) 和 Reduce Phase (Reduce Face)。 **6.1. Map Phase** 由以下幾個過程和函式組成: * **Split (輸入切割)**: * `InputFormat class`:負責處理輸入資料的切割。 * **`split` 函式**:讀取一塊資料 (chunk of data),決定輸出鍵值對 (key-value pair) 的記錄。 * **預設切割**:通常以「一行」作為一個記錄 (record)。 * **Text Input Format**:預設的實作,鍵 (key) 為行號 (line number),值 (value) 為該行所有文字。 * **KeyValueText Input Format**:可指定分隔符號 (separator character/byte) 來切割一行內的鍵值對。 * **自訂切割**:可以在 `map` 函式內部進一步細切記錄。 * **Map 函式**: * 每個記錄 (record) 會被傳遞給 `map` 函式。 * 生成零個或多個中間鍵值對 (intermediate key-value pairs)。 * **輸出方式**:透過 `Context object` 來輸出鍵值對。 * **物件生命週期**:輸出的 `Writable object` 必須在類別層級 (class level) 宣告,而非 `map` 函式內部,以避免記憶體釋放導致程式崩潰。 * **Partitioner (分區)**: * `Partitioner class` 中的 `getPartition` 函式。 * 根據鍵 (key) 的雜湊值 (hash code) 或其他邏輯,決定將記錄發送到哪個 Reducer。 * **目的**:確保每個 Reducer 處理的資料量大致相同 (負載平衡, load balance),或將特定鍵分配到同一 Reducer 進行處理。 * **回傳值**:Reduer ID (範圍在 0 到 Reducer 數量減一之間)。 * **Combiner (組合器)**: * **選用 (Optional)**:框架會根據資料量大小決定是否呼叫 Combiner,程式設計師無法控制。 * **功能**:在 Mapper 端進行類似 Reduce 的預先處理,減少傳輸到 Reducer 的資料量,優化網路頻寬。 * **限制**: * Combiner 的輸出鍵值對資料型別必須與 Mapper 的輸出鍵值對資料型別一致,不能做型別轉換。 * Combiner 必須是「可重複套用」的 (idempotent),即使多次呼叫或不呼叫,最終結果也必須正確。 * 不適用於需要「全局視圖」的聚合操作 (如中位數計算)。 * **程式碼**:與 Reducer 函式非常相似。 **6.2. Shuffle and Sort Phase (洗牌與排序)** 發生在 Map Phase 和 Reduce Phase 之間。 * **資料傳輸**:Reducer 會從各個 Mapper 任務中拉取 (copy) 其分區後的暫存資料。 * **Shuffle (洗牌)**: * 在資料傳輸過程中,會使用 `Merge Sort` 演算法進行排序。 * 根據鍵 (key) 的 `compare` 函式定義的順序,收集並排序每個 Mapper 的中間鍵值對。 * **可覆寫**:`Sort Comparator` 函式可用於自訂排序順序 (升序或降序)。 * **Grouping (分組)**: * 排序完成後,Reducer 拿到的鍵值對已按鍵排序。 * 使用 `Grouping Comparator` 函式,將相同鍵的數值 (values) 合併成一個列表 (list)。 * **可覆寫**:`Grouping Comparator` 函式決定哪些鍵被視為「相同」而分組在一起。 * **結果**:每個鍵會對應一個數值列表。 **6.3. Reduce Phase** * **Reduce 函式**: * 針對每個分組後的鍵和其對應的數值列表 (list of values) 進行聚合 (aggregation)。 * 每個鍵會搭配一個值迭代器 (Iterator of values)。 * **Output (輸出)**: * `OutputFormat class`:負責將結果寫出。 * **`write` 函式**:將處理後的鍵值對寫入最終輸出檔案。 * **預設格式**:通常一個輸出鍵對應一行。 * **可覆寫**:可以自訂輸出格式,例如不換行、只輸出值不輸出鍵等。 * **Text Output Format**:預設的實作,一個鍵值對對應一行。 **7. 資料型別 (Data Types)** * **強型別 (Strongly Typed)**:Java 要求明確定義資料型別並進行正確的型別轉換。 * **`Writable` 介面**:所有鍵值對的資料型別都必須實作此介面,因為這些物件將在不同類別間處理。 * **`ComparableWritable` 介面**:鍵 (key) 的資料型別除了 `Writable` 外,還必須實作 `Comparable` 介面,以便進行排序。 * **實作方法**:`write()` 和 `readFields()` (用於序列化/反序列化)、`compareTo()` (用於排序)、`hashCode()` (用於 Partitioner)。 * **可定義的型別**: * `setInputFormatClass`:控制初始輸入鍵值對的型別。 * `setMapOutputKeyClass` / `setMapOutputValueClass`:控制 Mapper 輸出鍵值對的型別。 * `setOutputKeyClass` / `setOutputValueClass`:控制 Reducer 輸出鍵值對的型別 (最終輸出)。 * `setOutputFormatClass`:控制輸出檔案的寫入格式。 * **範例型別**:`IntWritable` (對應 Java int)、`Text` (對應 Java String),這些都實作了 `Writable` 及 `Comparable` 介面。 * **自訂資料型別**: * 透過實作 `Writable` 和 `ComparableWritable` 介面,可以自訂複雜的資料型別,如 3D 座標作為鍵。 * 避免在 `map` 函式內進行繁瑣的字串解析和組合,使程式碼更直觀。 **8. Reducer 數量的設定** * **Mapper 數量**:由輸入檔案的大小和切割方式決定,不可手動設定。 * **Reducer 數量**:可透過 `setNumReduceTasks()` 函式來設定。 * **Reducer 數量過多**: * 每個 Reducer 處理的工作量減少,導致啟動/停止 Reducer 的開銷 (overhead) 佔比較高。 * 產生過多的輸出檔案,且每個檔案內的鍵可能無法有效排序。 * **Reducer 數量過少 (如一個)**: * 失去平行處理的優勢,降低平行度。 * **優勢**:可實現「全域排序 (global sorting)」,將所有結果排序在單一輸出檔案中。 * **最佳數量**:通常與 `Reduce slot` 數量相關,應盡量利用硬體資源,但避免過多或過少。 **9. 進階程式設計技巧 (Advanced Programming)** 除了基本的 `map` 和 `reduce` 函式,還可以覆寫其他類別的函式,實現更複雜或高效的計算。 * **1. 自訂資料型別 (Custom Data Types)** * **目的**:定義特殊的鍵 (key) 或值 (value) 型別,如 3D 座標。 * **實現**: * 值 (value) 實作 `Writable` 介面。 * 鍵 (key) 實作 `Comparable` 和 `Writable` 介面。 * **需要覆寫的方法**: * `write(DataOutput out)` 和 `readFields(DataInput in)`:用於資料的序列化 (serialize) 和反序列化 (deserialize),供 Input/Output Format 類別使用。 * `compareTo(Object o)`:供排序函式 (Sort Comparator) 比較物件大小。 * `hashCode()`:供 Partitioner 函式決定分區。 * **2. 自訂 Partitioner (分區器)** * **目的**:精確控制鍵值對分配到哪個 Reducer,實現負載平衡或特定鍵的分組。 * **實現**:覆寫 `Partitioner` 類別的 `getPartition` 函式。 * **範例**:將 A-K 開頭的鍵丟到第一個 Reducer,L-Z 開頭的鍵丟到第二個 Reducer。 * **進階應用**:透過資料分析 (profiling/sampling) 了解鍵的分布,進行更精確的負載平衡。 * **3. 自訂 Comparators (比較器)** * **a. Sort Comparator (排序比較器)** * **目的**:在 Shuffle 階段定義鍵的排序邏輯。 * **實現**:覆寫 `WritableComparator` 或實作 `RawComparator` 介面。 * **範例**:自訂按鍵的第一個字元排序。 * **b. Grouping Comparator (分組比較器)** * **目的**:在 Reduce 階段定義哪些鍵被視為「相同」而分組在一起,即使它們在排序上是不同的。 * **實現**:覆寫 `WritableComparator` 或實作 `RawComparator` 介面。 * **範例**:只比較鍵的第一個字元來進行分組。 * **注意**:分組後,Reduer 會將該組的第一個鍵作為代表鍵,並將所有對應的值作為列表處理。 * **4. 二級排序 (Secondary Sort)** * **問題**:除了按鍵排序,還希望對鍵所對應的值進行排序。例如,按年/月分組,然後按溫度排序。 * **傳統做法的缺點**:將所有值拉到 Reducer 端再排序效率低下。 * **高效實作方法 (Solution 2 - Composite Key)**: 1. **Composite Key (組合鍵)**:在 Mapper 輸出時,將希望進行排序的值也包含在鍵中 (例如:`年,月,溫度` 作為一個鍵)。 2. **自訂 Partitioner**:確保只有年和月相同的記錄被送往同一個 Reducer (Partitioner 只看組合鍵的前半部分,例如年和月)。 3. **自訂 Sort Comparator**:定義排序規則,先按年、月排序,如果年、月相同,再按溫度排序。 4. **自訂 Grouping Comparator**:定義分組規則,只按年、月進行分組,忽略溫度部分。 5. **Reducer 處理**:Reducer 接收到年/月相同但溫度已排序的記錄組。在 `reduce` 函式中,去除鍵中多餘的溫度部分,只輸出年/月和排序過的值列表。 * **優勢**:利用 MapReduce 框架自動化的排序功能,實現值內部的排序,效率高。 --- 其他課程連結 [平行程式1C~2B Introduction parallel programming](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/Syxh3H7Kxe) [平行程式3A~3D The Latest Developments and Applications Using Parallel Programming](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJh7QFVKle) [平行程式4A~4B IO Parallel IO and Program Analysis](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJLMsuHFgg) [平行程式5A~5B The Latest Developments and Applications Using Parallel Programming](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/SJh57hIFle) [平行程式6A~6B Communication Routines and Parallel Function Code](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/r1X9kX_Fle) [平行程式 6C~6D Communication Routines and Parallel Function Code](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/S1DPjoYFlx) [平行程式 7A~8A Pthread:Synchronization Problem & Tools](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJu-_0tKge) [平行程式 8B~8D Synchronization Tools & Open Multi-Processing(OpenMP)](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/H1ki4E2Fee) [平行程式 9A~9B Synchronization Construct](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BJTYMrpKlx) [平行程式 10A~10B Synchronization Tools & Open Multi-Processing Synchronization Construct](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/B1cY6M1qee) [平行程式 10C~10D Synchronization Tools & Open Multi-Processing Synchronization Construct](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BkgFaNg5gg) [平行程式 11A~11B Parallel Work Pool and Termination / Parallel Sorting](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/H1hfOw-5xl) [平行程式 12A~12B Parallel Sorting and Pipelined Computations](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/Symo-zQ9eg) [平行程式 12C~12D Parallel Sorting and Pipelined Computations](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BJYNKDVceg) [平行程式 13A-13B Sychronous Parallelism](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJ2UJ2Bqex) [平行程式 14A~14B Heterogeneous Computing](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BksS4yP5eg) [平行程式 14C~14D Heterogeneous Computing](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BJrfTUd9xx) [平行程式 15A~15B Parallel Programming Model on GPU](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/ByWnl-t5gg) [平行程式 16A~16B What is Compute Unified Device Architecture(CUDA)?](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HyYpsjcqgl) [平行程式 17A~18A 平行運算的CUDA](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/H1dUeBT5lg) [平行程式 18B~19A 記憶體層級 / CUDA的優化](https://hackmd.io/@JuitingChen/HyF44e1jge) [平行程式 19B~19D 記憶體層級 / CUDA的優化 ](https://hackmd.io/@JuitingChen/ryPEu4lieg) [平行程式 20A~20B CUDA優化全域和區域記憶體/共享記憶體](https://hackmd.io/@JuitingChen/r1X659Zoxl) [平行程式 21A~21B Parallel Reduction / Distributed Computing Framework](https://hackmd.io/@JuitingChen/HyiOpozjxl) [平行程式 NTHU-PP-Chap10-Big Data-Part1 ](https://hackmd.io/@JuitingChen/Hyc-e3Golx) [平行程式 NTHU-PP-Chap10-Big Data-Part2 ](https://hackmd.io/@JuitingChen/ryC_QTXoxl) [平行程式 NTHU-PP-Chap11-MapReduce](https://hackmd.io/@JuitingChen/HJgBXJOsge) [平行程式 NTHU-PP-Chap12-Distributed Training-Part1](https://hackmd.io/@JuitingChen/ryh5hBtsge) [平行程式 NTHU-PP-Chap12-Distributed Training-Part2](https://hackmd.io/@JuitingChen/rJ2G7kdjxg) [平行程式 NTHU-PP-Chap12-Distributed Training-Part3](https://hackmd.io/@JuitingChen/HkA471dilx) [平行程式 NTHU-PP-Chap13-UCX-Part1](https://hackmd.io/@JuitingChen/rJbq103ieg) [平行程式 NTHU-PP-Chap13-UCX-Part2](https://hackmd.io/@JuitingChen/SJpNmk_ixl) [平行程式 NTHU-PP-Chap13-UCX-Part3](https://hackmd.io/@JuitingChen/HkIUYa13xe)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.