03.03 「大數據」(七十六)Spark之工作機制

【導讀:數據是二十一世紀的石油,蘊含巨大價值,這是·情報通·大數據技術系列第[76]篇文章,歡迎閱讀和收藏】

1 基本概念

Spark 是基於內存計算的大數據並行計算框架。 Spark 基於內存計算,提高了在大數據環境下數據處理的實時性,同時保證了高容錯性和高可伸縮性,允許用戶將 Spark 部署在大量廉價硬件之上,形成集群。正是如此, Spark 工作機制也是圍繞這幾點開展,主要包括調度管理、內存管理、容錯機制。

2 術語解釋

「大數據」(七十六)Spark之工作機制

3 Spark 工作機制介紹

3.1 調度管理

Spark 調度管理按照場景可以分為兩類,一類是 Spark 程序之間的調度,這是最主要的調度場景;另外一類是 Spark 程序內部的調度。

l Spark 程序之間的調度

當多個用戶提交多個 Spark 程序時, Spark 是如何調度這些應用併合理地分配資源呢?

Standalone 模式下,默認使用 FIFO ,每個 app 會獨佔所有資源,可以通過以下幾個參數調整集群相關的資源:

1) spark.cores.max :調整 app 可以在整個集群中申請的 CPU core 數量

2) spark.deploy.defaultCores :默認的 CPU core 數量

3) spark.executor.memory :限制每個 Executor 可用的內存

Mesos 模式下,可以使用

1) spark.mesos.coarse=true 設置靜態配置資源的策略

2) 使用 mesos://URL 且不配置 spark.mesos.coarse=true (每個 app 會有獨立固定的內存分配,空閒時其他機器可以使用其資源)

在 Yarn 模式下,提交作業時可以使用

1) 通過– num-executors 控制分配多少個 Executor 給 app

2) – executor-memory 和– executor-cores 分別控制 Executor 的內存和 CPU core

l Spark 程序內部的 Job 調度機制

一個程序應用中,由各個 Action 觸發的多個 Job 之間也是存在調度關係的。 Action 操作實現上是調用了 SparkContext 的 runJob 方法提交 Job 。

Spark 中調度 Job 有兩種策略

FIFO :

1) 第一個 Job 分配其所需的所有資源

2) 第二個 Job 如果還有剩餘資源的話就分配,否則等待

FAIR :

1) 使用輪詢的方式調度 Job

2) 可以通過配置 spark.scheduler.mode 調整 Job 的調度方式,也可以配置調度池。


其中調度池的配置如下:

n schedulingMode : FIFO 或者 FAIR

n weight :用於控制調度池相對於其他調度池的權重

n minShare :最小資源值 ( core 的數量 )

3.2 內存管理

相比 Hadoop MapReduce , Spark 計算具有巨大的性能優勢,其中很大一部分是因為 Spark 對於內存的充分利用,以及提供的緩存機制。

l 序列化

序列化的本質就是將對象轉換為字節流,可以理解為將鏈表中存儲的非連續空間的數據存儲轉化為連續空間存儲的數組中。

Spark 進行序列化操作後,內存或磁盤中 RDD 會含有對象的存儲,而在節點間數據的傳輸時,序列化之後的數據可以節約空間和提高效率。

l 壓縮

壓縮是日常生活中的一個常見操作,好處顯而易見,節約空間,從而就可以獲得時間 上的效率。 Spark 中序列化之後的數據可以進行壓縮以減少空間開銷。

Spark 支持兩種壓縮算法,在不同的場景中選擇不同的壓縮算法可以有效的提高程序運行的效率:

n Snappy 算法:高壓縮速度

n LZF 算法:高壓縮比

l 塊管理

RDD 從物理上看是一個元數據結構,記錄著 Block 和 Node 之間的映射關係。

存儲 RDD 是以 Block 塊為單位的,每個分區對應一個塊, PartitionID 通過元數據信息可以映射到 Block 。 Spark 保證了每一個 RDD 都可以被重新恢復, RDD 的持久化由 Spark 的 Storage 模塊負責,實現了 RDD 與物理存儲的解耦合。 Storage 模塊負責管理 Spark 在計算過程中產生的數據,將那些在內存或磁盤、在本地或遠程存取數據的功能封裝了起來。

3.3 容錯機制

Spark 以前的集群容錯處理模型,像 MapReduce ,將計算轉換為一個有向無環圖( DAG )的任務集合,這樣可以通過重複執行 DAG 裡的一部分任務來完成容錯恢復。但是由於主要的數據存儲在分佈式文件系統中,沒有提供其他存儲的概念,容錯過程中需要在網絡上進行數據複製,從而增加了大量的消耗。所以,分佈式編程中經常需要做檢查點,即將某個時機的中間數據寫到存儲(通常是分佈式文件系統)中。

RDD 也是一個 DAG ,每一個 RDD 都會記住創建該數據集需要哪些操作,跟蹤記錄 RDD 的繼承關係,這個關係在 Spark 裡面叫 lineage 。由於創建 RDD 的操作是相對粗粒度的變換,即單一的操作應用於許多數據元素,而不需存儲真正的數據。當一個 RDD 的某個分區丟失時, RDD 有足夠的信息記錄其如何通過其他 RDD 進行計算,且只需重新計算該分區。

RDD 之間的依賴分為兩種。

Narrow Dependencies (窄依賴):父分區對應一個子分區。

Shuffle Dependencies (寬依賴):父分區對應多個子分區。

父分區最多被一個子分區所用,即一對一或者多對一的關係

對應窄依賴,只需要通過重新計算丟失的那一塊數據來恢復,容錯成本較小。但如果是寬依賴,則當容錯重算分區時,因為父分區數據只有一部分是需要重算子分區的,其餘數據重算則成了冗餘計算。這時候就需要人為的添加檢查點來提高容錯機制的執行效率。


分享到:


相關文章: