我最近在使用我的一個 spark 作業時遇到了問題,我正在讀取一個包含數十億條記錄的 hive 表,由于磁盤利用率高導致作業失敗,但是在添加 AWS EBS 卷后,作業運行沒有任何問題。雖然它解決了問題,但我幾乎沒有懷疑,我嘗試進行了一些研究,但找不到任何明確的答案。所以我的問題是?
當 spark SQL 讀取 hive 表時,如果我沒有明確指定任何內容,那么最初存盤資料用于處理的位置以及資料的整個生命周期是什么?以及如何添加 EBS 卷解決該問題?
uj5u.com熱心網友回復:
最初,資料位于 HDFS/S3/etc 中的表位置。如果資料不適合記憶體,Spark 會將資料溢位到本地存盤。
閱讀Apache Spark 常見問題解答
Does my data need to fit in memory to use Spark?
不可以。如果資料不適合記憶體,Spark 的運算子會將資料溢位到磁盤,使其能夠在任何大小的資料上運行良好。同樣,不適合記憶體的快取資料集要么溢位到磁盤,要么在需要時動態重新計算,這取決于 RDD 的存盤級別。
uj5u.com熱心網友回復:
每當 spark 從 hive 表中讀取資料時,它都會將其存盤在 RDD 中。我想在這里澄清的一點是,hive 只是一個倉庫,所以它就像一個位于 HDFS 之上的層,當 spark 與 hive 互動時,hive 為 spark 提供了 hdfs 位置存在的位置。
因此,Spark 從 HDFS 讀取檔案,它為單個輸入拆分創建單個磁區。輸入拆分由 Hadoop 設定(無論用于讀取此檔案的 InputFormat 是什么。例如:如果您使用 textFile(),它將是 Hadoop 中的 TextInputFormat,它將為您回傳單個 HDFS 塊的單個磁區(注意:拆分磁區之間將在行拆分上完成,而不是確切的塊拆分),除非您有像 Avro/parquet 這樣的壓縮檔案格式。
如果您手動添加 rdd.repartition(x) 它將執行從您在 rdd 中擁有的 N 個磁區到您想要擁有的 x 個磁區的資料的洗牌,磁區將在回圈的基礎上完成。
如果您有一個 10GB 的未壓縮文本檔案存盤在 HDFS 上,那么在默認的 HDFS 塊大小設定(256MB)下,它將存盤在 40 個塊中,這意味著您從該檔案中讀取的 RDD 將有 40 個磁區。當您呼叫 repartition(1000) 時,您的 RDD 將被標記為已重新磁區,但實際上只有當您在此 RDD 之上執行操作時才會將其改組為 1000 個磁區(惰性執行概念)
現在完全取決于 Spark 在執行延遲評估時如何處理資料,在進行處理之前,spark 準備一個 DAG 以進行最佳處理。還有一點 spark 需要配置驅動程式記憶體、內核數、執行器數等,如果配置不合適,作業將失敗。
一旦它準備好 DAG ,它就會開始處理資料。因此,它將您的作業劃分為階段,將階段劃分為任務。每個任務將進一步使用特定的執行器, shuffle , partitioning 。因此,在您處理數十億條記錄的情況下,您的配置可能不足以進行處理。還有一點,當我們說 spark 將資料加載到 RDD/Dataframe 中時,它由 spark 管理,可以選擇將資料保留在記憶體/磁盤/記憶體中等等 ref - storage_spark。
簡要地,
Hive-->HDFS-->SPARK>>RDD(存盤取決于它的惰性評估)。
您可以參考以下鏈接:Spark RDD - 磁區總是在 RAM 中嗎?
uj5u.com熱心網友回復:
Spark 將讀取資料,如果它不適合記憶體,它會將其溢位到磁盤上。
需要注意的幾點:
- 記憶體中的資料被壓縮,從我讀到的,你獲得了大約 20%(例如,一個 100MB 的檔案將只占用 80MB 的記憶體)。
- 攝取將在您啟動后立即開始
read(),它不是 DAG 的一部分,您可以限制在 SQL 查詢本身中攝取的數量。讀取操作由執行器完成。這個例子應該給你一個提示:https : //github.com/jgperrin/net.jgp.books.spark.ch08/blob/master/src/main/java/net/jgp/books/spark/ch08/lab300_advanced_queries/ MySQLWithWhereClauseToDatasetApp.java - 在最新版本的 Spark 中,您可以向下推過濾器(例如,如果您在攝取后立即進行過濾,Spark 會知道并優化攝取),我認為這僅適用于 CSV、Avro 和 Parquet。對于資料庫(包括 Hive),我建議使用前面的示例。
- 存盤必須可以從執行程式看到/訪問,因此如果您有 EBS 卷,請確保它們可以從執行程式/作業程式運行的集群看到/訪問,而不是驅動程式運行的節點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/347524.html
