7000字超詳細(xì)講解Hadoop、Spark、Storm、YARN,建議收藏!

一、Hadoop

1.1. 概念

就是一個(gè)大數(shù)據(jù)解決方案。它提供了一套分布式系統(tǒng)基礎(chǔ)架構(gòu)。 核心內(nèi)容包含 hdfs 和mapreduce。
hadoop2.0 以后引入 yarn.
hdfs 是提供數(shù)據(jù)存儲(chǔ)的,mapreduce 是方便數(shù)據(jù)計(jì)算的。

  1. hdfs 又對(duì)應(yīng) namenode 和 datanode. namenode 負(fù)責(zé)保存元數(shù)據(jù)的基本信息,
    datanode 直接存放數(shù)據(jù)本身;
  2. mapreduce 對(duì)應(yīng) jobtracker 和 tasktracker. jobtracker 負(fù)責(zé)分發(fā)任務(wù),tasktracker 負(fù)
    責(zé)執(zhí)行具體任務(wù);
  3. 對(duì)應(yīng)到 master/slave 架構(gòu),namenode 和 jobtracker 就應(yīng)該對(duì)應(yīng)到 master, datanode
    和 tasktracker 就應(yīng)該對(duì)應(yīng)到 slave.

1.2. HDFS

1.2.1. Client

Client(代表用 戶) 通過(guò)與 NameNode 和 DataNode 交互訪問(wèn) HDFS 中 的文件。 Client 提供
了一個(gè)類似 POSIX 的文件系統(tǒng)接口供用戶調(diào)用。

1.2.2. NameNode

整個(gè) Hadoop 集群中只有一個(gè) NameNode。 它是整個(gè)系統(tǒng)的“ 總管”, 負(fù)責(zé)管理 HDFS 的目
錄樹(shù)和相關(guān)的文件元數(shù)據(jù)信息。 這些信息是以“ fsimage”( HDFS 元數(shù)據(jù)鏡像文件)和
“ editlog”(HDFS 文件改動(dòng)日志)兩個(gè)文件形式存放在本地磁盤,當(dāng) HDFS 重啟時(shí)重新構(gòu)造出
來(lái)的。此外, NameNode 還負(fù)責(zé)監(jiān)控各個(gè) DataNode 的健康狀態(tài), 一旦發(fā)現(xiàn)某個(gè) DataNode 宕
掉,則將該 DataNode 移出 HDFS 并重新備份其上面的數(shù)據(jù)。

1.2.3. Secondary NameNode

Secondary NameNode 最重要的任務(wù)并不是為 NameNode 元數(shù)據(jù)進(jìn)行熱備份, 而是定期合并
fsimage 和 edits 日志, 并傳輸給 NameNode。 這里需要注意的是,為了減小 NameNode 壓
力, NameNode 自己并不會(huì)合并 fsimage 和 edits, 并將文件存儲(chǔ)到磁盤上, 而是交由
Secondary NameNode 完成。

1.2.4. DataNode

一般而言, 每個(gè) Slave 節(jié)點(diǎn)上安裝一個(gè) DataNode, 它負(fù)責(zé)實(shí)際的數(shù)據(jù)存儲(chǔ), 并將數(shù)據(jù)信息定期
匯報(bào)給 NameNode。 DataNode 以固定大小的 block 為基本單位組織文件內(nèi)容, 默認(rèn)情況下
block 大小為 64MB。 當(dāng)用戶上傳一個(gè)大的文件到 HDFS 上時(shí), 該文件會(huì)被切分成若干個(gè) block,
分別存儲(chǔ)到不同的 DataNode ; 同時(shí),為了保證數(shù)據(jù)可靠, 會(huì)將同一個(gè) block 以流水線方式寫到
若干個(gè)(默認(rèn)是 3,該參數(shù)可配置)不同的 DataNode 上。 這種文件切割后存儲(chǔ)的過(guò)程是對(duì)用戶
透明的。

1.3. MapReduce

同 HDFS 一樣,Hadoop MapReduce 也采用了 Master/Slave(M/S)架構(gòu),具體如圖所示。它
主要由以下幾個(gè)組件組成:Client、JobTracker、TaskTracker 和 Task。 下面分別對(duì)這幾個(gè)組件
進(jìn)行介紹。


image.png

1.3.1. Client

用戶編寫的 MapReduce 程序通過(guò) Client 提交到 JobTracker 端; 同時(shí), 用戶可通過(guò) Client 提
供的一些接口查看作業(yè)運(yùn)行狀態(tài)。 在 Hadoop 內(nèi)部用“作業(yè)”(Job) 表示 MapReduce 程序。
一個(gè) MapReduce 程序可對(duì)應(yīng)若干個(gè)作業(yè),而每個(gè)作業(yè)會(huì)被分解成若干個(gè) Map/Reduce 任務(wù)
(Task)。

1.3.2. JobTracker

JobTracker 主要負(fù)責(zé)資源監(jiān)控和作業(yè)調(diào)度。JobTracker 監(jiān)控所有 TaskTracker 與作業(yè)的健康狀況,
一旦發(fā)現(xiàn)失敗情況后,其會(huì)將相應(yīng)的任務(wù)轉(zhuǎn)移到其他節(jié)點(diǎn);同時(shí) JobTracker 會(huì)跟蹤任務(wù)的執(zhí)行進(jìn)
度、資源使用量等信息,并將這些信息告訴任務(wù)調(diào)度器,而調(diào)度器會(huì)在資源出現(xiàn)空閑時(shí),選擇合
適的任務(wù)使用這些資源。在 Hadoop 中,任務(wù)調(diào)度器是一個(gè)可插拔的模塊,用戶可以根據(jù)自己的
需要設(shè)計(jì)相應(yīng)的調(diào)度器。

1.3.3. TaskTracker

TaskTracker 會(huì)周期性地通過(guò) Heartbeat 將本節(jié)點(diǎn)上資源的使用情況和任務(wù)的運(yùn)行進(jìn)度匯報(bào)給
JobTracker, 同時(shí)接收 JobTracker 發(fā)送過(guò)來(lái)的命令并執(zhí)行相應(yīng)的操作(如啟動(dòng)新任務(wù)、 殺死任
務(wù)等)。TaskTracker 使用“slot” 等量劃分本節(jié)點(diǎn)上的資源量。“slot” 代表計(jì)算資源(CPU、
內(nèi)存等)。一個(gè) Task 獲取到一個(gè) slot 后才有機(jī)會(huì)運(yùn)行,而 Hadoop 調(diào)度器的作用就是將各個(gè)
TaskTracker 上的空閑 slot 分配給 Task 使用。 slot 分為 Map slot 和 Reduce slot 兩種,分別供
MapTask 和 Reduce Task 使用。 TaskTracker 通過(guò) slot 數(shù)目(可配置參數(shù))限定 Task 的并發(fā)
度。

1.3.4. Task

Task 分為 Map Task 和 Reduce Task 兩種, 均由 TaskTracker 啟動(dòng)。 HDFS 以固定大小的 block
為基本單位存儲(chǔ)數(shù)據(jù), 而對(duì)于 MapReduce 而言, 其處理單位是 split。split 與 block 的對(duì)應(yīng)關(guān)
系如圖所示。 split 是一個(gè)邏輯概念, 它只包含一些元數(shù)據(jù)信息, 比如數(shù)據(jù)起始位置、數(shù)據(jù)長(zhǎng)度、
數(shù)據(jù)所在節(jié)點(diǎn)等。它的劃分方法完全由用戶自己決定。 但需要注意的是,split 的多少?zèng)Q定了 Map
Task 的數(shù)目 ,因?yàn)槊總€(gè) split 會(huì)交由一個(gè) Map Task 處理。
Map Task 執(zhí)行過(guò)程如圖所示。 由該圖可知,Map Task 先將對(duì)應(yīng)的 split 迭代解析成一個(gè)個(gè)
key/value 對(duì),依次調(diào)用用戶自定義的 map() 函數(shù)進(jìn)行處理,最終將臨時(shí)結(jié)果存放到本地磁盤上,
其中臨時(shí)數(shù)據(jù)被分成若干個(gè) partition,每個(gè) partition 將被一個(gè) Reduce Task 處理。


image.png

1.3.5. Reduce Task 執(zhí)行過(guò)程

該過(guò)程分為三個(gè)階段

  1. 從遠(yuǎn)程節(jié)點(diǎn)上讀取 MapTask 中間結(jié)果(稱為“Shuffle 階段”);
  2. 按照 key 對(duì) key/value 對(duì)進(jìn)行排序(稱為“ Sort 階段”);
  3. 依次讀取<key, value list>,調(diào)用用戶自定義的 reduce() 函數(shù)處理,并將最終結(jié)果存到 HDFS
    上(稱為“ Reduce 階段”)。

1.4. Hadoop MapReduce 作業(yè)的生命周期

1.作業(yè)?交與初始化

  1. 用戶提交作業(yè)后, 首先由 JobClient 實(shí)例將作業(yè)相關(guān)信息, 比如將程序 jar 包、作業(yè)配置文
    件、 分片元信息文件等上傳到分布式文件系統(tǒng)( 一般為 HDFS)上,其中,分片元信息文件
    記錄了每個(gè)輸入分片的邏輯位置信息。 然后 JobClient 通過(guò) RPC 通知 JobTracker。
    JobTracker 收到新作業(yè)提交請(qǐng)求后, 由 作業(yè)調(diào)度模塊對(duì)作業(yè)進(jìn)行初始化:為作業(yè)創(chuàng)建一個(gè)
    JobInProgress 對(duì)象以跟蹤作業(yè)運(yùn)行狀況, 而 JobInProgress 則會(huì)為每個(gè) Task 創(chuàng)建一個(gè)
    TaskInProgress 對(duì)象以跟蹤每個(gè)任務(wù)的運(yùn)行狀態(tài), TaskInProgress 可能需要管理多個(gè)
    “ Task 運(yùn)行嘗試”( 稱為“ Task Attempt”)。
    2.任務(wù)調(diào)度與監(jiān)控。
  2. 前面提到,任務(wù)調(diào)度和監(jiān)控的功能均由 JobTracker 完成。TaskTracker 周期性地通過(guò)
    Heartbeat 向 JobTracker 匯報(bào)本節(jié)點(diǎn)的資源使用 情況, 一旦出 現(xiàn)空閑資源, JobTracker
    會(huì)按照一定的策略選擇一個(gè)合適的任務(wù)使用該空閑資源, 這由任務(wù)調(diào)度器完成。 任務(wù)調(diào)度器
    是一個(gè)可插拔的獨(dú)立模塊, 且為雙層架構(gòu), 即首先選擇作業(yè), 然后從該作業(yè)中選擇任務(wù), 其
    中,選擇任務(wù)時(shí)需要重點(diǎn)考慮數(shù)據(jù)本地性。 此外,JobTracker 跟蹤作業(yè)的整個(gè)運(yùn)行過(guò)程,并
    為作業(yè)的成功運(yùn)行提供全方位的保障。 首先, 當(dāng) TaskTracker 或者 Task 失敗時(shí), 轉(zhuǎn)移計(jì)算
    任務(wù) ; 其次, 當(dāng)某個(gè) Task 執(zhí)行進(jìn)度遠(yuǎn)落后于同一作業(yè)的其他 Task 時(shí),為之啟動(dòng)一個(gè)相同
    Task, 并選取計(jì)算快的 Task 結(jié)果作為最終結(jié)果。
    3.任務(wù)運(yùn)行環(huán)境準(zhǔn)備
  3. 運(yùn)行環(huán)境準(zhǔn)備包括 JVM 啟動(dòng)和資源隔 離, 均由 TaskTracker 實(shí)現(xiàn)。 TaskTracker 為每個(gè)
    Task 啟動(dòng)一個(gè)獨(dú)立的 JVM 以避免不同 Task 在運(yùn)行過(guò)程中相互影響 ; 同時(shí),TaskTracker 使
    用了操作系統(tǒng)進(jìn)程實(shí)現(xiàn)資源隔離以防止 Task 濫用資源。
    4.任務(wù)執(zhí)行
  4. TaskTracker 為 Task 準(zhǔn)備好運(yùn)行環(huán)境后, 便會(huì)啟動(dòng) Task。 在運(yùn)行過(guò)程中, 每個(gè) Task 的最
    新進(jìn)度首先由 Task 通過(guò) RPC 匯報(bào)給 TaskTracker, 再由 TaskTracker 匯報(bào)給 JobTracker。
    5.作業(yè)完成。
  5. 待所有 Task 執(zhí)行完畢后, 整個(gè)作業(yè)執(zhí)行成功。

二. Spark

2.1. 概念

Spark 提供了一個(gè)全面、統(tǒng)一的框架用于管理各種有著不同性質(zhì)(文本數(shù)據(jù)、圖表數(shù)據(jù)等)的數(shù)據(jù)
集和數(shù)據(jù)源(批量數(shù)據(jù)或?qū)崟r(shí)的流數(shù)據(jù))的大數(shù)據(jù)處理的需求。

2.2. 核心架構(gòu)

image.png

Spark Core
包含 Spark 的基本功能;尤其是定義 RDD 的 API、操作以及這兩者上的動(dòng)作。其他 Spark 的庫(kù)都
是構(gòu)建在 RDD 和 Spark Core 之上的
*Spark SQL
提供通過(guò) Apache Hive 的 SQL 變體 Hive 查詢語(yǔ)言(HiveQL)與 Spark 進(jìn)行交互的 API。每個(gè)
數(shù)據(jù)庫(kù)表被當(dāng)做一個(gè) RDD,Spark SQL 查詢被轉(zhuǎn)換為 Spark 操作。
Spark Streaming
對(duì)實(shí)時(shí)數(shù)據(jù)流進(jìn)行處理和控制。Spark Streaming 允許程序能夠像普通 RDD 一樣處理實(shí)時(shí)數(shù)據(jù)
Mllib
一個(gè)常用機(jī)器學(xué)習(xí)算法庫(kù),算法被實(shí)現(xiàn)為對(duì) RDD 的 Spark 操作。這個(gè)庫(kù)包含可擴(kuò)展的學(xué)習(xí)算法,
比如分類、回歸等需要對(duì)大量數(shù)據(jù)集進(jìn)行迭代的操作。
GraphX
控制圖、并行圖操作和計(jì)算的一組算法和工具的集合。GraphX 擴(kuò)展了 RDD API,包含控制圖、
創(chuàng)建子圖、訪問(wèn)路徑上所有頂點(diǎn)的操作

2.3. 核心組件

image.png

Cluster Manager-制整個(gè)集群,監(jiān)控 worker
在 standalone 模式中即為 Master 主節(jié)點(diǎn),控制整個(gè)集群,監(jiān)控 worker。在 YARN 模式中為資
源管理器
Worker 節(jié)點(diǎn)-負(fù)責(zé)控制計(jì)算節(jié)點(diǎn)
從節(jié)點(diǎn),負(fù)責(zé)控制計(jì)算節(jié)點(diǎn),啟動(dòng) Executor 或者 Driver。
Driver: 運(yùn)行 Application 的 main()函數(shù)
Executor:執(zhí)行器,是為某個(gè) Application 運(yùn)行在 worker node 上的一個(gè)進(jìn)程

2.4. SPARK 編程模型

image.png

Spark 應(yīng)用程序從編寫到提交、執(zhí)行、輸出的整個(gè)過(guò)程如圖所示,圖中描述的步驟如下:

  1. 用戶使用 SparkContext 提供的 API(常用的有 textFile、sequenceFile、runJob、stop 等)
    編寫 Driver application 程序。此外 SQLContext、HiveContext 及 StreamingContext 對(duì)
    SparkContext 進(jìn)行封裝,并提供了 SQL、Hive 及流式計(jì)算相關(guān)的 API。
  2. 使用SparkContext提交的用戶應(yīng)用程序,首先會(huì)使用BlockManager和BroadcastManager
    將任務(wù)的 Hadoop 配置進(jìn)行廣播。然后由 DAGScheduler 將任務(wù)轉(zhuǎn)換為 RDD 并組織成 DAG,
    DAG 還將被劃分為不同的 Stage。最后由 TaskScheduler 借助 ActorSystem 將任務(wù)提交給
    集群管理器(Cluster Manager)。
  3. 集群管理器(ClusterManager)給任務(wù)分配資源,即將具體任務(wù)分配到Worker上,Worker
    創(chuàng)建 Executor 來(lái)處理任務(wù)的運(yùn)行。Standalone、YARN、Mesos、EC2 等都可以作為 Spark
    的集群管理器。

2.5. SPARK 計(jì)算模型

RDD 可以看做是對(duì)各種數(shù)據(jù)計(jì)算模型的統(tǒng)一抽象,Spark 的計(jì)算過(guò)程主要是 RDD 的迭代計(jì)算過(guò)
程。RDD 的迭代計(jì)算過(guò)程非常類似于管道。分區(qū)數(shù)量取決于 partition 數(shù)量的設(shè)定,每個(gè)分區(qū)的數(shù)
據(jù)只會(huì)在一個(gè) Task 中計(jì)算。所有分區(qū)可以在多個(gè)機(jī)器節(jié)點(diǎn)的 Executor 上并行執(zhí)行。


image.png

2.6. SPARK 運(yùn)行流程

image.png

1. 構(gòu)建 Spark Application 的運(yùn)行環(huán)境,啟動(dòng) SparkContext
2. SparkContext 向資源管理器(可以是 Standalone,Mesos,Yarn)申請(qǐng)運(yùn)行 Executor 資源,
并啟動(dòng) StandaloneExecutorbackend,

3. Executor 向 SparkContext 申請(qǐng) Task
4. SparkContext 將應(yīng)用程序分發(fā)給 Executor
5. SparkContext 構(gòu)建成 DAG 圖,將 DAG 圖分解成 Stage、將 Taskset 發(fā)送給 Task Scheduler,
最后由 Task Scheduler 將 Task 發(fā)送給 Executor 運(yùn)行

6. Task 在 Executor 上運(yùn)行,運(yùn)行完釋放所有資源

2.7. SPARK RDD 流程

image.png
  1. 創(chuàng)建 RDD 對(duì)象
  2. DAGScheduler 模塊介入運(yùn)算,計(jì)算 RDD 之間的依賴關(guān)系,RDD 之間的依賴關(guān)系就形成了
    DAG
  3. 每一個(gè) Job 被分為多個(gè) Stage。劃分 Stage 的一個(gè)主要依據(jù)是當(dāng)前計(jì)算因子的輸入是否是確
    定的,如果是則將其分在同一個(gè) Stage,避免多個(gè) Stage 之間的消息傳遞開(kāi)銷

2.8. SPARK RDD

(1)RDD 的創(chuàng)建方式
1)從 Hadoop 文件系統(tǒng)(或與Hadoop兼容的其他持久化存儲(chǔ)系統(tǒng),如Hive、Cassandra、
HBase)輸入(例如 HDFS)創(chuàng)建。
2)從父 RDD 轉(zhuǎn)換得到新 RDD。
3)通過(guò) parallelize 或 makeRDD 將單機(jī)數(shù)據(jù)創(chuàng)建為分布式 RDD。
(2)RDD 的兩種操作算子(轉(zhuǎn)換(Transformation)與行動(dòng)(Action))
對(duì)于 RDD 可以有兩種操作算子:轉(zhuǎn)換(Transformation)與行動(dòng)(Action)。
1)轉(zhuǎn)換(Transformation):Transformation操作是延遲計(jì)算的,也就是說(shuō)從一個(gè)RDD轉(zhuǎn)
換生成另一個(gè) RDD 的轉(zhuǎn)換操作不是馬上執(zhí)行,需要等到有 Action 操作的時(shí)候才會(huì)真正觸
發(fā)運(yùn)算。

image.png

2)行動(dòng)(Action):Action 算子會(huì)觸發(fā) Spark 提交作業(yè)(Job),并將數(shù)據(jù)輸出 Spark 系統(tǒng)。


image.png

三. Storm

3.1. 概念

Storm 是一個(gè)免費(fèi)并開(kāi)源的分布式實(shí)時(shí)計(jì)算系統(tǒng)。利用 Storm 可以很容易做到可靠地處理無(wú)限的
數(shù)據(jù)流,像 Hadoop 批量處理大數(shù)據(jù)一樣,Storm 可以實(shí)時(shí)處理數(shù)據(jù)。

3.1. 集群架構(gòu)

image.png

3.1.1. Nimbus(master-代碼分發(fā)給 Supervisor)

Storm 集群的 Master 節(jié)點(diǎn),負(fù)責(zé)分發(fā)用戶代碼,指派給具體的 Supervisor 節(jié)點(diǎn)上的 Worker 節(jié)
點(diǎn),去運(yùn)行 Topology 對(duì)應(yīng)的組件(Spout/Bolt)的 Task。

3.1.2. Supervisor(slave-管理 Worker 進(jìn)程的啟動(dòng)和終止)

Storm 集群的從節(jié)點(diǎn),負(fù)責(zé)管理運(yùn)行在 Supervisor 節(jié)點(diǎn)上的每一個(gè) Worker 進(jìn)程的啟動(dòng)和終止。
通過(guò) Storm 的配置文件中的 supervisor.slots.ports 配置項(xiàng),可以指定在一個(gè) Supervisor 上最大
允許多少個(gè) Slot,每個(gè) Slot 通過(guò)端口號(hào)來(lái)唯一標(biāo)識(shí),一個(gè)端口號(hào)對(duì)應(yīng)一個(gè) Worker 進(jìn)程(如果該
Worker 進(jìn)程被啟動(dòng))。

3.1.3. Worker(具體處理組件邏輯的進(jìn)程)

運(yùn)行具體處理組件邏輯的進(jìn)程。Worker 運(yùn)行的任務(wù)類型只有兩種,一種是 Spout 任務(wù),一種是
Bolt 任務(wù)。

3.1.4. Task

worker中每一個(gè)spout/bolt的線程稱為一個(gè)task. 在storm0.8 之后,task不再與物理線程對(duì)應(yīng),
不同 spout/bolt 的 task 可能會(huì)共享一個(gè)物理線程,該線程稱為 executor。

3.1.5. ZooKeeper

用來(lái)協(xié)調(diào) Nimbus 和 Supervisor,如果 Supervisor 因故障出現(xiàn)問(wèn)題而無(wú)法運(yùn)行 Topology,
Nimbus 會(huì)第一時(shí)間感知到,并重新分配 Topology 到其它可用的 Supervisor 上運(yùn)行

3.2. 編程模型(spout->tuple->bolt)

strom 在運(yùn)行中可分為 spout 與 bolt 兩個(gè)組件,其中,數(shù)據(jù)源從 spout 開(kāi)始,數(shù)據(jù)以 tuple 的方
式發(fā)送到 bolt,多個(gè) bolt 可以串連起來(lái),一個(gè) bolt 也可以接入多個(gè) spot/bolt.運(yùn)行時(shí)原理如下圖:


image.png

3.2.1. Topology

Storm 中運(yùn)行的一個(gè)實(shí)時(shí)應(yīng)用程序的名稱。將 Spout、 Bolt 整合起來(lái)的拓?fù)鋱D。定義了 Spout 和
Bolt 的結(jié)合關(guān)系、并發(fā)數(shù)量、配置等等。

3.2.2. Spout

在一個(gè) topology 中獲取源數(shù)據(jù)流的組件。通常情況下 spout 會(huì)從外部數(shù)據(jù)源中讀取數(shù)據(jù),然后轉(zhuǎn)
換為 topology 內(nèi)部的源數(shù)據(jù)。

3.2.3. Bolt

接受數(shù)據(jù)然后執(zhí)行處理的組件,用戶可以在其中執(zhí)行自己想要的操作。

3.2.4. Tuple

一次消息傳遞的基本單元,理解為一組消息就是一個(gè) Tuple。

3.2.5. Stream

Tuple 的集合。表示數(shù)據(jù)的流向。

3.3. Topology 運(yùn)行

在 Storm 中,一個(gè)實(shí)時(shí)應(yīng)用的計(jì)算任務(wù)被打包作為 Topology 發(fā)布,這同 Hadoop MapReduce
任務(wù)相似。但是有一點(diǎn)不同的是:在 Hadoop 中,MapReduce 任務(wù)最終會(huì)執(zhí)行完成后結(jié)束;而在
Storm 中,Topology 任務(wù)一旦提交后永遠(yuǎn)不會(huì)結(jié)束,除非你顯示去停止任務(wù)。計(jì)算任務(wù)
Topology 是由不同的 Spouts 和 Bolts,通過(guò)數(shù)據(jù)流(Stream)連接起來(lái)的圖?一個(gè) Storm 在集
群上運(yùn)行一個(gè) Topology 時(shí),主要通過(guò)以下 3 個(gè)實(shí)體來(lái)完成 Topology 的執(zhí)行工作:
(1). Worker(進(jìn)程)
(2). Executor(線程)
(3). Task


image.png

3.3.1. Worker(1 個(gè) worker 進(jìn)程執(zhí)行的是 1 個(gè) topology 的子集)

1 個(gè) worker 進(jìn)程執(zhí)行的是 1 個(gè) topology 的子集(注:不會(huì)出現(xiàn) 1 個(gè) worker 為多個(gè) topology
服務(wù))。1 個(gè) worker 進(jìn)程會(huì)啟動(dòng) 1 個(gè)或多個(gè) executor 線程來(lái)執(zhí)行 1 個(gè) topology 的
component(spout 或 bolt)。因此,1 個(gè)運(yùn)行中的 topology 就是由集群中多臺(tái)物理機(jī)上的多個(gè)
worker 進(jìn)程組成的。

3.3.2. Executor(executor 是 1 個(gè)被 worker 進(jìn)程啟動(dòng)的單獨(dú)線程)

executor 是 1 個(gè)被 worker 進(jìn)程啟動(dòng)的單獨(dú)線程。每個(gè) executor 只會(huì)運(yùn)行 1 個(gè) topology 的 1 個(gè)
component(spout 或 bolt)的 task(注:task 可以是 1 個(gè)或多個(gè),storm 默認(rèn)是 1 個(gè)
component 只生成 1 個(gè) task,executor 線程里會(huì)在每次循環(huán)里順序調(diào)用所有 task 實(shí)例)。

3.3.3. Task(最終運(yùn)行 spout 或 bolt 中代碼的單元)

是最終運(yùn)行 spout 或 bolt 中代碼的單元(注:1 個(gè) task 即為 spout 或 bolt 的 1 個(gè)實(shí)例,
executor 線程在執(zhí)行期間會(huì)調(diào)用該 task 的 nextTuple 或 execute 方法)。topology 啟動(dòng)后,1 個(gè) component(spout 或 bolt)的 task 數(shù)目是固定不變的,但該 component 使用的 executor 線
程數(shù)可以動(dòng)態(tài)調(diào)整(例如:1 個(gè) executor 線程可以執(zhí)行該 component 的 1 個(gè)或多個(gè) task 實(shí)
例)。這意味著,對(duì)于 1 個(gè) component 存在這樣的條件:#threads<=#tasks(即:線程數(shù)小于
等于 task 數(shù)目)。默認(rèn)情況下 task 的數(shù)目等于 executor 線程數(shù)目,即 1 個(gè) executor 線程只運(yùn)
行 1 個(gè) task。


image.png

3.4. Storm Streaming Grouping

Storm 中最重要的抽象,應(yīng)該就是 Stream grouping 了,它能夠控制 Spot/Bolt 對(duì)應(yīng)的 Task 以
什么樣的方式來(lái)分發(fā) Tuple,將 Tuple 發(fā)射到目的 Spot/Bolt 對(duì)應(yīng)的 Task.


image.png

目前,Storm Streaming Grouping 支持如下幾種類型:

3.4.1. huffle Grouping

隨機(jī)分組,盡量均勻分布到下游 Bolt 中將流分組定義為混排。這種混排分組意味著來(lái)自 Spout 的
輸入將混排,或隨機(jī)分發(fā)給此 Bolt 中的任務(wù)。shuffle grouping 對(duì)各個(gè) task 的 tuple 分配的比
較均勻。

3.4.2. Fields Grouping

按字段分組,按數(shù)據(jù)中 field 值進(jìn)行分組;相同 field 值的 Tuple 被發(fā)送到相同的 Task 這種
grouping 機(jī)制保證相同 field 值的 tuple 會(huì)去同一個(gè) task。

3.4.3. All grouping :廣播

廣播發(fā)送, 對(duì)于每一個(gè) tuple 將會(huì)復(fù)制到每一個(gè) bolt 中處理。

3.4.4. Global grouping

全局分組,Tuple 被分配到一個(gè) Bolt 中的一個(gè) Task,實(shí)現(xiàn)事務(wù)性的 Topology。Stream 中的所
有的 tuple 都會(huì)發(fā)送給同一個(gè) bolt 任務(wù)處理,所有的 tuple 將會(huì)發(fā)送給擁有最小 task_id 的 bolt
任務(wù)處理。

3.4.5. None grouping :不分組

不關(guān)注并行處理負(fù)載均衡策略時(shí)使用該方式,目前等同于 shuffle grouping,另外 storm 將會(huì)把
bolt 任務(wù)和他的上游提供數(shù)據(jù)的任務(wù)安排在同一個(gè)線程下。

3.4.6. Direct grouping :直接分組 指定分組

由 tuple 的發(fā)射單元直接決定 tuple 將發(fā)射給那個(gè) bolt,一般情況下是由接收 tuple 的 bolt 決定
接收哪個(gè) bolt 發(fā)射的 Tuple。這是一種比較特別的分組方法,用這種分組意味著消息的發(fā)送者指
定由消息接收者的哪個(gè) task 處理這個(gè)消息。 只有被聲明為 Direct Stream 的消息流可以聲明這種
分組方法。而且這種消息 tuple 必須使用 emitDirect 方法來(lái)發(fā)射。消息處理者可以通過(guò)
TopologyContext 來(lái)獲取處理它的消息的 taskid (OutputCollector.emit 方法也會(huì)返回
taskid)。

四. YARN

4.1. 概念

YARN 是一個(gè)資源管理、任務(wù)調(diào)度的框架,主要包含三大模塊:ResourceManager(RM)、
NodeManager(NM)、ApplicationMaster(AM)。其中,ResourceManager 負(fù)責(zé)所有資
源的監(jiān)控、分配和管理; ApplicationMaster 負(fù)責(zé)每一個(gè)具體應(yīng)用程序的調(diào)度和協(xié)調(diào);
NodeManager 負(fù)責(zé)每一個(gè)節(jié)點(diǎn)的維護(hù)。對(duì)于所有的 applications,RM 擁有絕對(duì)的控制權(quán)和對(duì)資
源的分配權(quán)。而每個(gè) AM 則會(huì)和 RM 協(xié)商資源,同時(shí)和 NodeManager 通信來(lái)執(zhí)行和監(jiān)控 task。
幾個(gè)模塊之間的關(guān)系如圖所示。


image.png

4.2. ResourceManager

  1. ResourceManager 負(fù)責(zé)整個(gè)集群的資源管理和分配,是一個(gè)全局的資源管理系統(tǒng)。
  2. NodeManager 以心跳的方式向 ResourceManager 匯報(bào)資源使用情況(目前主要是 CPU 和
    內(nèi)存的使用情況)。RM 只接受 NM 的資源回報(bào)信息,對(duì)于具體的資源處理則交給 NM 自己
    處理。
  3. YARN Scheduler 根據(jù) application 的請(qǐng)求為其分配資源,不負(fù)責(zé) application job 的監(jiān)控、
    追蹤、運(yùn)行狀態(tài)反饋、啟動(dòng)等工作。

4.3. NodeManager

  1. NodeManager 是每個(gè)節(jié)點(diǎn)上的資源和任務(wù)管理器,它是管理這臺(tái)機(jī)器的代理,負(fù)責(zé)該節(jié)點(diǎn)
    程序的運(yùn)行,以及該節(jié)點(diǎn)資源的管理和監(jiān)控。YARN集群每個(gè)節(jié)點(diǎn)都運(yùn)行一個(gè)NodeManager。
  2. NodeManager 定時(shí)向 ResourceManager 匯報(bào)本節(jié)點(diǎn)資源(CPU、內(nèi)存)的使用情況和
    Container 的運(yùn)行狀態(tài)。當(dāng) ResourceManager 宕機(jī)時(shí) NodeManager 自動(dòng)連接 RM 備用節(jié)
    點(diǎn)。
  3. NodeManager 接收并處理來(lái)自 ApplicationMaster 的 Container 啟動(dòng)、停止等各種請(qǐng)求。

4.4. ApplicationMaster

用戶提交的每個(gè)應(yīng)用程序均包含一個(gè) ApplicationMaster,它可以運(yùn)行在 ResourceManager 以外
的機(jī)器上。

  1. 負(fù)責(zé)與 RM 調(diào)度器協(xié)商以獲取資源(用 Container 表示)。
  2. 將得到的任務(wù)進(jìn)一步分配給內(nèi)部的任務(wù)(資源的二次分配)。
  3. 與 NM 通信以啟動(dòng)/停止任務(wù)。
  4. 監(jiān)控所有任務(wù)運(yùn)行狀態(tài),并在任務(wù)運(yùn)行失敗時(shí)重新為任務(wù)申請(qǐng)資源以重啟任務(wù)。
  5. 當(dāng)前 YARN 自帶了兩個(gè) ApplicationMaster 實(shí)現(xiàn),一個(gè)是用于演示 AM 編寫方法的實(shí)例程序
    DistributedShell,它可以申請(qǐng)一定數(shù)目的 Container 以并行運(yùn)行一個(gè) Shell 命令或者 Shell
    腳本;另一個(gè)是運(yùn)行 MapReduce 應(yīng)用程序的 AM—MRAppMaster。
    注:RM 只負(fù)責(zé)監(jiān)控 AM,并在 AM 運(yùn)行失敗時(shí)候啟動(dòng)它。RM 不負(fù)責(zé) AM 內(nèi)部任務(wù)的容錯(cuò),任務(wù)
    的容錯(cuò)由 AM 完成。

4.5.YARN 運(yùn)行流程

  1. client 向 RM 提交應(yīng)用程序,其中包括啟動(dòng)該應(yīng)用的 ApplicationMaster 的必須信息,例如
    ApplicationMaster 程序、啟動(dòng) ApplicationMaster 的命令、用戶程序等。
  2. ResourceManager 啟動(dòng)一個(gè) container 用于運(yùn)行 ApplicationMaster。
  3. 啟動(dòng)中的ApplicationMaster向ResourceManager注冊(cè)自己,啟動(dòng)成功后與RM保持心跳。
  4. ApplicationMaster 向 ResourceManager 發(fā)送請(qǐng)求,申請(qǐng)相應(yīng)數(shù)目的 container。
  5. ResourceManager 返回 ApplicationMaster 的申請(qǐng)的 containers 信息。申請(qǐng)成功的
    container,由 ApplicationMaster 進(jìn)行初始化。container 的啟動(dòng)信息初始化后,AM 與對(duì)
    應(yīng)的 NodeManager 通信,要求 NM 啟動(dòng) container。AM 與 NM 保持心跳,從而對(duì) NM 上
    運(yùn)行的任務(wù)進(jìn)行監(jiān)控和管理。
  6. container 運(yùn)行期間,ApplicationMaster 對(duì) container 進(jìn)行監(jiān)控。container 通過(guò) RPC 協(xié)議
    向?qū)?yīng)的 AM 匯報(bào)自己的進(jìn)度和狀態(tài)等信息。
  7. 應(yīng)用運(yùn)行期間,client 直接與 AM 通信獲取應(yīng)用的狀態(tài)、進(jìn)度更新等信息。
  8. 應(yīng)用運(yùn)行結(jié)束后,ApplicationMaster 向 ResourceManager 注銷自己,并允許屬于它的
    container 被收回
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容