Spark存儲管理(讀書筆記)

来源:http://www.cnblogs.com/BYRans/archive/2016/10/10/5945667.html
-Advertisement-
Play Games

Spark存儲管理(讀書筆記) 轉載請註明出處: "http://www.cnblogs.com/BYRans/" Spark的存儲管理 RDD的存放和管理都是由Spark的存儲管理模塊實現和管理的。本文從架構和功能兩個角度對Spark的存儲管理模塊進行介紹。 架構角度 從架構角度,存儲管理模塊主要 ...


Spark存儲管理(讀書筆記)


轉載請註明出處:http://www.cnblogs.com/BYRans/

Spark的存儲管理

RDD的存放和管理都是由Spark的存儲管理模塊實現和管理的。本文從架構和功能兩個角度對Spark的存儲管理模塊進行介紹。

架構角度

從架構角度,存儲管理模塊主要分為以下兩層:

  • 通信層:存儲管理模塊採用的是主從結構來實現通信層,主節點和從節點之間傳輸控制信息、狀態信息。
  • 存儲層:存儲管理模塊需要把數據存儲到硬碟或者記憶體中,必要時還需要複製到遠端,這些操作由存儲層來實現和提供相應介面。

通信層消息傳遞

在存儲管理模塊的通信層,每個Executor上的BlockManager只負責管理其自身Executor所擁有的數據塊原信息,而不會管理其他Executor上的數據塊元信息;而Driver端的BlockManager擁有所有已註冊的BlockManager信息和數據塊元信息,因此Executor的BlockManager往往是通過向Driver發送信息來獲得所需要的非本地數據的。

存儲層架構

RDD是由不同的分區組成的,我們所進行的轉換和執行操作都是在每一塊獨立的分區上各自進行的。而在存儲管理模塊內部,RDD又被視為由不同的數據塊組成,對於RDD的存取是以數據塊為單位的,本質上分區(partition)和數據塊(block)是等價的,只是看待的角度不同。同時,在Spark存儲管理模塊中存取數據的最小單位是數據塊,所有的操作都是以數據塊為單位的。

數據塊(Block)

前面章節已經提到:存儲管理模塊以數據塊為單位進行數據管理,數據塊是存儲管理模塊中最小的操作單位。在存儲管理模塊中管理著各種不同的數據塊,這些數據塊為Spark框架提供了不同的功能,Spark存儲管理模塊中所管理的幾種主要數據塊為:

  • RDD數據塊:用來存儲所緩存的RDD數據。
  • Shuffle數據塊:用來存儲持久化的Shuffle數據。
  • 廣播變數數據塊:用來存儲所存儲的廣播變數數據。
  • 任務返回結果數據塊:用來存儲在存儲管理模塊內部的任務返回結果。通常情況下任務返回結果隨任務一起通過Akka返回到Driver端。但是當任務返回結果很大時,會引起Akka幀溢出,這時的另一種方案是將返回結果以塊的形式放入存儲管理模塊,然後在Driver端獲取該數據塊即可,因為存儲管理模塊內部數據塊的傳輸是通過Socket連接的,因此就不會出現Akka幀溢出了。
  • 流式數據塊:只用在Spark Streaming中,用來存儲所接收到的流式數據塊。

從功能角度

從功能角度,存儲管理模塊可以分為以下兩個主要部分:

  • RDD緩存:整個存儲管理模塊主要的工作是作為RDD的緩存,包括基於記憶體和磁碟的緩存。
  • Shuffle數據的持久化:Shuffle中間結果的數據也是交由存儲管理模塊進行管理的。Shuffle性能的好壞直接影響了Spark應用程式整體的性能,因此存儲管理模塊中對於Shuffle數據的處理有別於傳統的RDD緩存。

RDD持久化

存儲管理模塊可以分為兩大塊,一是RDD的緩存,二是Shuffle數據的持久化。接下來將介紹存儲管理模塊如何從記憶體和磁碟兩個方面對RDD進行緩存。

RDD分區和數據塊的關係

對於RDD的各種操作,如轉換操作、執行操作,我們將操作函數施行於RDD之上,而最終這些操作都將施行於每一個分區之上,因此可以這麼說,在RDD上的所有運算都是基於分區的。而在存儲管理模塊內,我們所接觸到的往往是數據塊這個概念,在存儲管理模塊中對於數據的存取都是以數據塊為單位進行的。分區是一個邏輯上的概念,而數據塊是物理上的數據實體,我們操作的分區和數據塊,它們兩者之間有什麼關係呢?本小節我們將介紹分區與數據塊的關係。

在Spark中,分區和數據塊是一一對應的,一個RDD中的一個分區對應著存儲管理模塊中的一個數據塊,存儲管理模塊接觸不到也並不關心RDD,它只關心數據塊,對於數據塊和分區之間的映射則是通過名稱上的約定進行的。

這種名稱上的約定是按如下方式建立的:Spark為每一個RDD在其內部維護了獨立的ID號,同時,對於RDD的每一個分區也有一個獨立的索引號,因此只要知道ID號和索引號我們就能找到RDD中的相應分區,也就是說“ID號+索引號”就能全局唯一地確定這個分區。這樣以“ID號+索引號”作為塊的名稱就自然地建立起了分區和塊的映射。

在顯示調用調用函數緩存我們所需的RDD時,Spark在其內部就建立了RDD分區和數據塊之間的映射,而當我們需要讀取緩存的RDD時,根據上面所提到的映射關係,就能從存儲管理模塊中取得分區對應的數據塊。下圖展示了RDD分區與數據塊之間的映射關係。

圖5-5 RDD分區和數據塊的映射關係

內部緩存

當以預設或者基於記憶體的持久化方式緩存RDD時,RDD中的每一分區所對應的數據塊是會被存儲管理模塊中的記憶體緩存(Memory Store)所管理的。記憶體緩存在其內部維護了一個以數據塊名為鍵,塊內容為值的哈希表。

在記憶體緩存中有一個重要的問題是,當記憶體不是或是已經到達所設置的閾值時應如何處理。在Spark中對於記憶體緩存可使用的記憶體閾值有這樣一個配置:spark.storage.memoryFraction。預設情況下是0.6,也就是說JVM記憶體的60%可被記憶體緩存用來存儲塊內容。當我們存儲的數據塊所占用的記憶體大於60%時,Spark會採取一些策略釋放記憶體緩存空間:丟棄一些數據塊,或是將一些數據塊存儲到磁碟上以釋放記憶體緩存空間。是丟棄還是存儲到磁碟上,依賴於進行操作的這些數據塊的持久化選項,若持久化選項中包含了磁碟緩存,則會將這些塊已入磁碟進行緩存,反之則直接刪除。

那麼直接刪除是否會影響Spark程式的錯誤恢復機制呢?這取決於依賴關係的可回溯性,若該RDD所依賴的祖先RDD是可被回溯並可用的,那麼該RDD所對應的塊被刪除是不會影響錯誤恢復的。反之,若該RDD已經是祖先RDD,且數據已無法被回溯到,那麼程式就會出錯。lost executor錯誤是不是就是這個原因?

從上面的介紹可以看出,記憶體緩存對於數據塊的管理是非常簡單的,本質上就是一個哈希表加上一些存取策略。

磁碟緩存

磁碟緩存管理數據塊的方式為,首先,這些數據塊會被存放到磁碟中的特定目錄下。當我們配置spark.local.dir時,我們就配置了存儲管理模塊磁碟緩存存放數據的目錄。磁碟緩存初始化時會在這些目錄下創建Spark磁碟緩存文件夾,文件夾的命名方式是:spark-local-yyyyMMddHHmmss-xxxx,其中xxxx是一隨機數。伺候所有的塊內容都將存儲到這些創建的目錄中。

其次,在磁碟緩存中,一個數據塊對應著文件系統中的一個文件,文件名和塊名稱的映射關係是通過哈希演算法計算所得的。

總而言之,數據塊對應的文件路徑為:dirId/subDirId/block_id。這樣我們就建立了塊和文件之間的對應關係,而存取塊內容就變成了寫入和讀取相應的文件了。

持久化選項

被緩存的數據塊是可容錯恢復的,若RDD的某一分區丟失,他會通過繼承關係自動重新獲得。

對於RDD的持久化,Spark為我們提供了不同的選項,使我們能將RDD持久化到記憶體、磁碟,或是以序列化的方式持久化到記憶體中,設置可以在集群的不同節點之間存儲多份拷貝。所有這些不同的存儲策略都是通過不同的持久化選項來決定的。

Shuffle數據持久化

存儲管理模塊可以分為兩大塊,一是RDD的緩存,二是Shuffle數據的持久化。介紹完RDD緩存,接下來介紹Shuffle數據持久化。

下圖為Spark中Shuffle操作的流程示意圖

圖5-6 Spark Shuffle流程

首先,每一個Map任務會根據Reduce任務的數據量創建出相應的桶,桶的數量是M*R,其中M是Map任務的個數,R是Reduce任務的個數。

其次,Map任務產生的結果會根據所設置的分區演算法填充到每個桶中。這裡的分區演算法是可自定義的,當然預設的演算法是根據鍵哈希到不同的桶中。

當Reduce任務啟動時,它會根據自己任務的ID和所依賴的Map任務的ID從遠端或本地的存儲管理模塊中取得相應的桶作為任務的輸入進行處理。

Shuffle數據與RDD持久化的不同之處在於:

  • Shuffle數據塊必須是在磁碟上進行緩存的,而不能選擇在記憶體中緩存;
  • 在RDD基於磁碟的持久化中,每一個數據塊對應著一個文件,而在Shuffle數據塊持久化中,Shuffle數據塊的存儲有兩種方式:
    • 一種是將Shuffle數據塊映射成文件,這是預設的方式;
    • 另一種是將Shuffle數據塊映射成文件中的一段,這種方式需要將spark.shuffle.consolidateFiles設置為true。

預設的方式會產生大量的文件,如1000個Map任務和1000個Reduce任務,會產生1000000個Shuffle文件,這會對磁碟和文件系統的性能造成極大的影響,因此有了第二種是實現方式,將分時運行的Map任務所產生的Shuffle數據塊合併到同一個文件中,以減少Shuffle文件的總數。對於第二種存儲方式,示意圖如下:

圖5-7 Shuffle文件聚合示意圖

前面介紹了Shuffle數據塊的存取,下麵我們來介紹Shuffle數據塊的讀取和傳輸。Shuffle是將一組任務的輸出結果重新組合作為下一組任務的輸入這樣的一個過程,由於任務分佈在不同的節點上,因此為了將重組結果作為輸入,必然涉及Shuffle數據的讀取和傳輸。

在Spark存儲管理模塊中,Shuffle數據的讀取和傳輸有兩種方式:

  • 一種是基於NIO以socket連接去獲取數據;
  • 另一種是基於OIO通過Netty服務端獲取數據。

前者是預設的獲取方式,通過配置spark.shuffle.use.netty為true,可以啟用第二種獲取方式。之所以有兩種Shuffle數據的獲取方式,是因為預設的方式在一些情況下無法充分利用網路帶寬,用戶可以通過比較兩種方式在性能上的差異來自行決定選用哪種Shuffle數據獲取方式。

總的來說,Spark存儲管理模塊為Shuffle數據的持久化做了許多有別於RDD持久化的工作,包括存取Shuffle數據塊的方式,以及讀取和傳輸Shuffle數據塊的方式,所有這些實現都是為了使Shuffle獲得更好的性能和容錯。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 新浪微博:intsmaze劉洋洋哥。 storm框架中的kafkaspout類實現的是BaseRichSpout,它裡面已經重寫了fail和ack方法,所以我們的bolt必須實現ack機制,就可以保證消息的重新發送;如果不實現ack機制,那麼kafkaspout就無法得到消息的處理響應,就會在超時以 ...
  • 【等待事件】等待事件系列(5.1)--Enqueue(隊列等待) 1 BLOG文檔結構圖 2 前言部分 2.1 導讀和註意事項 各位技術愛好者,看完本文後,你可以掌握如下的技能,也可以學到一些其它你所不知道的知識,~O(∩_∩)O~: ① Enqueue隊列等待 ② Enq數據字典 ③ enq: A... ...
  • 一、使用分散式鎖要滿足的幾個條件: 二、應用的場景例子 管理後臺的部署架構(多台tomcat伺服器+redis【多台tomcat伺服器訪問一臺redis】+mysql【多台tomcat伺服器訪問一臺伺服器上的mysql】)就滿足使用分散式鎖的條件。多台伺服器要訪問redis全局緩存的資源,如果不使用 ...
  • 當在使用greenplum過程中有不當的操作時,可能會出現segment節點宕掉的情況(比如在greenplum運行的過程中停掉其中幾台segment節點的伺服器),通過下麵的方法可以恢復segment。 下麵是現場出現的故障情況: 可以看到有6個節點Failed,有2個節點的Primary和Mir ...
  • 背景 現在越來越多的企業、公司要求對於資料庫實現7*24小時的資料庫監控,一般情況下採用的就是第三方的平臺來實現郵件和手機簡訊的監測提醒。前幾日公司新上了一臺伺服器,急於部署程式還沒來得及搭建其他相關平臺,為了更好的監控資料庫,暫時用SQL Server自帶的郵件服務來實現對資料庫的監控和預警。下麵 ...
  • 1、打開mysql.exe(MySQL Command Line Client),輸入密碼 2、輸入:use mysql; 3、查詢host輸入: select user,host from user; 4、創建host(如果有"%"這個host值,則跳過這一步) 如果沒有"%"這個host值,就執 ...
  • 問題一: 第一次mysql啟動服務失敗,未返回報錯信息 解決方法: 執行mysqld -console命令,查看error信息,對症下藥 但一般情況下,主要是因為mysql目錄下的data文件夾中內容不正確,解決方法有以下兩個 1.在開啟服務前執行初始化命令 mysqld --initalize 然 ...
  • ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...