spark 基礎(chǔ)

HDFS

HDFS 是 Hadoop Distributed File System 的簡(jiǎn)稱,顧名思義這是一個(gè)分布式的文件系統(tǒng)。HDFS可以將文件存儲(chǔ)在不同的服務(wù)器上。其組成架構(gòu)如下:

image.png

HDFS 主要分為一個(gè)Namenode和多個(gè)Datanode,其作用分別是:

  • Namenode: 維護(hù)整個(gè)文件的目錄樹(shù),以及每個(gè)文件對(duì)應(yīng)的數(shù)據(jù)塊列表(在HDFS中每個(gè)文件會(huì)被分塊放在不同的服務(wù)器上)
  • Datanode: 文件真實(shí)的存儲(chǔ)位置

寫(xiě)文件流程

在HDFS中,文件會(huì)分成許多個(gè) block(一個(gè)128M,可以通過(guò) hdfs-site.xml 修改), 每一個(gè) block 都會(huì)被復(fù)制多份放在不同的 datanode 上。當(dāng)寫(xiě)入文件的時(shí)候,首先會(huì)向 namenode 發(fā)出寫(xiě)申請(qǐng)。 namenode 會(huì)選擇一些 datanode 來(lái)存放 block。Client會(huì)選擇最近的那一個(gè)datanode進(jìn)行傳輸,其余的會(huì)和這個(gè)datanode形成pipline. 這樣雖然復(fù)制了多份,但是對(duì)于client來(lái)說(shuō)網(wǎng)絡(luò)帶寬并不需要增大。示意圖如下:



這個(gè)過(guò)程是同時(shí)進(jìn)行的。 這過(guò)程完成后,會(huì)接著傳輸?shù)诙€(gè),第三個(gè)block。直到傳輸完成。

讀文件流程

  1. client訪問(wèn)NameNode,查詢?cè)獢?shù)據(jù)信息,獲得這個(gè)文件的數(shù)據(jù)塊位置列表,返回輸入流對(duì)象。
  2. 就近挑選一臺(tái)datanode服務(wù)器,請(qǐng)求建立輸入流 。
  3. DataNode向輸入流中中寫(xiě)數(shù)據(jù),以packet為單位來(lái)校驗(yàn)。
  4. 關(guān)閉輸入流

寫(xiě)文件出錯(cuò)

在寫(xiě)文件時(shí),一個(gè)block會(huì)被分為許多個(gè)packet。當(dāng)節(jié)點(diǎn)收到某個(gè)packet時(shí),會(huì)將該packet繼續(xù)寫(xiě)往另一個(gè)節(jié)點(diǎn)。并且client會(huì)維持一個(gè) dataqueen 以及一個(gè) ackqueen。當(dāng)所有的節(jié)點(diǎn)收到某個(gè)數(shù)據(jù)包時(shí),才會(huì)將 ackqueen 中的數(shù)據(jù)刪除。當(dāng)其中一個(gè)節(jié)點(diǎn)錯(cuò)誤時(shí),會(huì)將ackqueen中的數(shù)據(jù)重新寫(xiě)入dataqueen。并將正常節(jié)點(diǎn)上當(dāng)前packet指定一個(gè)新的標(biāo)識(shí),以便完成后刪除。例如,最開(kāi)始 dataqueen = [1, 2, 3, 4, 5], 一共3個(gè)節(jié)點(diǎn),當(dāng)寫(xiě)入第3個(gè)包時(shí)節(jié)點(diǎn)2出錯(cuò),此時(shí)dataqueen = [4, 5], ackqueen=[3]. 因此將 ackqueen 放入到 dataqueen 后, dataqueen=[3, 4, 5] 因此能避免丟失任意一個(gè)數(shù)據(jù)包。

任務(wù)執(zhí)行流程

不同的任務(wù)調(diào)度框架下不同。但是基本可以分為以下幾個(gè)部分:

  1. application 用戶編寫(xiě)的應(yīng)用,這是一個(gè)虛擬的概念。
  2. driver 用戶寫(xiě)的代碼所在的線程。
  3. worker 工作節(jié)點(diǎn),負(fù)責(zé)資源的存儲(chǔ)和計(jì)算。
  4. executor 工作進(jìn)程池,可以并行計(jì)算多個(gè) task
  5. master 負(fù)責(zé)計(jì)算資源的分配,協(xié)同 driver 與 executor

Standalone模式

Standalone是spark自帶的資源調(diào)度模式,其運(yùn)行模式為:

  1. 啟動(dòng)應(yīng)用程序,啟動(dòng) SparkContext,這個(gè)過(guò)程中會(huì)啟動(dòng) DAGScheduler 和 Taskcheduler。
  2. Driver 向 Master 注冊(cè) Application,Master 將該應(yīng)用加入到應(yīng)用隊(duì)列中。并分配Worker。
  3. 當(dāng) Driver 獲得 Worker 后,會(huì)再 Worker 上創(chuàng)建 Executor,創(chuàng)建完成后將 Executor 注冊(cè)到SparkContext。然后 SparkContext 分配任務(wù)給 Executor 執(zhí)行。
  4. 任務(wù)執(zhí)行的過(guò)程中不斷的像 Driver 返回執(zhí)行情況,執(zhí)行完畢后 SparkContext 會(huì)回收資源。

Yarn模式

Yarn 是通過(guò) ResourceManager 管理資源,每一個(gè)節(jié)點(diǎn)稱為NodeManager。在 NodeManager 中會(huì)有多個(gè)Container。Executor 會(huì)在 Container 中運(yùn)行。與 Standalone 不同的是,Yarn 通過(guò) ApplicationMaster 來(lái)申請(qǐng)任務(wù)并與 Driver 聯(lián)系。流程如下:

  1. 向 ResourceManager 申請(qǐng)一個(gè) NodeManager 中的一個(gè) Container 用于執(zhí)行 ApplicationMaster。
  2. SparkContext 初始化完成后像 ApplicationMaster 通信,注冊(cè)到 ResourceManager 并 申請(qǐng)資源。
  3. 資源申請(qǐng)成功后,便與 NodeManager 通信申請(qǐng)創(chuàng)建 Container。 SparkContext 再向NodeManager 分配任務(wù)。
  4. 任務(wù)完成后,SparkContext 向 ResourceManager 申請(qǐng)注銷,并釋放資源。

yarn 有兩種提交模式: client 以及 cluster。client 的 driver 是運(yùn)行在本地的,也就是可以實(shí)時(shí)的觀察計(jì)算的輸出結(jié)果。cluster 的 driver 是運(yùn)行在 NodeManager 上,也就是可以關(guān)閉本地的client后也可以繼續(xù)運(yùn)行,適合不需要交互的場(chǎng)景。

Mesos

Mesos 分為兩種運(yùn)行模型: 粗粒度以及細(xì)粒度模式。 粗粒度模式可以一開(kāi)始就分配好資源,這個(gè)資源在整個(gè) application 的執(zhí)行中是不會(huì)變化的。而細(xì)粒度是隨著任務(wù)的變化,Mesos動(dòng)態(tài)的分配資源。因此在細(xì)粒度的執(zhí)行過(guò)程中,Driver是不直接與 Executor 交互,而是將任務(wù)交給 Mesos Master 進(jìn)行分配,這樣在分配任務(wù)的同時(shí)可以動(dòng)態(tài)的分配資源。

調(diào)優(yōu)

代碼調(diào)優(yōu)

  1. 重用RDD
  2. 預(yù)清洗
  3. 設(shè)置緩存

配置調(diào)優(yōu)

  1. --total-executor-cores 100: 調(diào)整可使用的核心數(shù)
  2. --executor-memory 20G: 調(diào)整 executor 內(nèi)存
  3. spark.shuffe.memoryFraction: 調(diào)整 shuffle buffer 大小
  4. 使用repartitioncoalesce 調(diào)整分區(qū)數(shù)

數(shù)據(jù)傾斜調(diào)優(yōu)

  1. 增加任務(wù)數(shù)量
  2. 二階段聚合

JOIN 調(diào)優(yōu)

  1. 如果傾斜的key只占少部分,可以先篩選出這兩個(gè)key,對(duì)大表進(jìn)行隨機(jī)前綴,小表進(jìn)行擴(kuò)容(同樣打上隨機(jī)淺醉)
  2. 如果傾斜的key占大部分,可以直接不過(guò)濾,然后擴(kuò)容
  3. 廣播小表

shuffle調(diào)優(yōu)

  1. 增加 shuffle 內(nèi)存
  2. 使用預(yù)聚合算子

yarn

調(diào)度的三種模式

  1. FIFO模式: 任務(wù)先提交則一直獨(dú)占資源,小任務(wù)需要一直等待
  2. 容量調(diào)度: 容量調(diào)度使用獨(dú)立的專門(mén)隊(duì)列為小隊(duì)列分配資源,但是不能搶占資源
  3. 公平調(diào)度: 可以公平的分配資源,并且可以搶占資源

存儲(chǔ)模型

spark 存儲(chǔ)同樣采用 master-slave 方式進(jìn)行管理。Master 維護(hù)元數(shù)據(jù),包括 Block 所在位置,所占空間大小。在 spark 中,每一個(gè) partition 都對(duì)應(yīng)一個(gè) block,blockid=rdd_+rddid+_+partitionid

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容