簡體   English   中英

如何在 Spark 中確定最佳 shuffle 分區數

[英]How to identify the optimum number of shuffle partition in Spark

我正在 EMR 中運行 spark 結構化流式傳輸作業(每天反彈)。 執行幾個小時后,我的應用程序出現 OOM 錯誤並被殺死。 以下是我的配置和火花 SQL 代碼。 我是 Spark 的新手,需要您的寶貴意見。

EMR 有 10 個實例,16 核和 64GB memory。

Spark-提交 arguments:

   num_of_executors: 17
   executor_cores: 5
   executor_memory: 19G
   driver_memory: 30G

Job 以 30 秒的間隔從 Kafka 讀取輸入作為微批次。 每批讀取的平均行數為 90k。

  spark.streaming.kafka.maxRatePerPartition: 4500
  spark.streaming.stopGracefullyOnShutdown: true
  spark.streaming.unpersist: true
  spark.streaming.kafka.consumer.cache.enabled: true
  spark.hadoop.fs.s3.maxRetries: 30 
  spark.sql.shuffle.partitions: 2001

Spark SQL 聚合代碼:

dataset.groupBy(functions.col(NAME),functions.window(functions.column(TIMESTAMP_COLUMN),30))
            .agg(functions.concat_ws(SPLIT, functions.collect_list(DEPARTMENT)).as(DEPS))
            .select(NAME,DEPS)
            .map((row) -> {
              Map<String, Object> map = Maps.newHashMap();
              map.put(NAME, row.getString(0));
              map.put(DEPS, row.getString(1));
              return new KryoMapSerializationService().serialize(map);
            }, Encoders.BINARY());

來自驅動程序的一些日志:

20/04/04 13:10:51 INFO TaskSetManager: Finished task 1911.0 in stage 1041.0 (TID 1052055) in 374 ms on <host> (executor 3) (1998/2001)
20/04/04 13:10:52 INFO TaskSetManager: Finished task 1925.0 in stage 1041.0 (TID 1052056) in 411 ms on  <host> (executor 3) (1999/2001)
20/04/04 13:10:52 INFO TaskSetManager: Finished task 1906.0 in stage 1041.0 (TID 1052054) in 776 ms on  <host> (executor 3) (2000/2001)
20/04/04 13:11:04 INFO YarnSchedulerBackend$YarnDriverEndpoint: Disabling executor 3.
20/04/04 13:11:04 INFO DAGScheduler: Executor lost: 3 (epoch 522)
20/04/04 13:11:04 INFO BlockManagerMasterEndpoint: Trying to remove executor 3 from BlockManagerMaster.
20/04/04 13:11:04 INFO BlockManagerMasterEndpoint: Removing block manager BlockManagerId(3,  <host>, 38533, None)
20/04/04 13:11:04 INFO BlockManagerMaster: Removed 3 successfully in removeExecutor
20/04/04 13:11:04 INFO YarnAllocator: Completed container container_1582797414408_1814_01_000004 on host:  <host> (state: COMPLETE, exit status: 143)

順便說一句,我在我的 forEachBatch 代碼中使用了 collectasList

  List<Event> list = dataset.select("value")
        .selectExpr("deserialize(value) as rows")
        .select("rows.*")
        .selectExpr(NAME, DEPS)
        .as(Encoders.bean(Event.class))
        .collectAsList();

使用這些設置,您可能會導致自己的問題。

   num_of_executors: 17
   executor_cores: 5
   executor_memory: 19G
   driver_memory: 30G

您基本上是在此處創建額外的容器,以便在它們之間進行洗牌。 相反,從 10 個執行器、15 個內核、60g memory 開始。 如果這行得通,那么您可以試玩一下以嘗試優化性能。 我通常嘗試將容器分成兩半(但自 spark 2.0 以來我也不需要這樣做)。

讓 Spark SQL 將默認值保持為 200。您將其分解得越多,Spark 計算洗牌時所做的數學運算就越多。 如果有的話,我會嘗試 go 與您的執行程序具有相同數量的並行度,所以在這種情況下只有 10 個。當 2.0 出來時,這就是您調整 hive 查詢的方式。 讓工作復雜到分手會把所有的負擔都放在主人身上。

使用數據集和編碼通常也不像直接使用 DataFrame 操作那樣高效。 對於 dataframe 操作,我發現在性能方面有很大提升。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM