使用Google CloudDataproc时是否仍然需要微调spark配置参数?

时间:2019-02-12 22:06:42

标签: apache-spark google-cloud-dataproc

详细说明:

  • 通常,在编写火花作业时,需要为不同的火花配置指定特定的值,以便以最佳方式使用群集资源。我们可以在初始化SparkSession时以编程方式进行操作:

    SparkSession.builder  .appName(SPARK_APP_NAME).config(“ spark.executor.memory”,“ 1G”)

  • 我想知道的是:使用Cloud Dataproc时我们仍然需要这样做吗?实际上,在创建Dataproc集群时,会初始化名为cluster.properies的属性文件,其中包含诸如spark\:spark.executor.memory=2688m之类的值。因此,我想知道Dataproc是否自动以最佳方式自动填充这些值。集群资源,在那种情况下,我们不必手动/编程地调整那些火花配置?

2 个答案:

答案 0 :(得分:6)

Dataproc确实提供了基于机器类型(甚至是自定义机器类型)和群集形状的智能默认值,旨在作为最佳的“一刀切”设置,在每个JVM的更多线程效率与以下限制之间取得平衡每个JVM共享资源池;大致来说,机器是经过精雕细琢的,以适合每台机器2个执行程序,并且每个执行程序都获得了一半的机器线程价值(因此,您期望2个执行程序每个能够在n1-standard-8上并行运行4个任务。 )。

请牢记incorrectly report vcores for multi-threaded Spark executors知道YARN,因此在Dataproc上运行大型Spark作业时,您可能只会看到两个YARN“ vcore”被占用,但是通过查看Spark可以验证是否确实使用了所有内核。 AppMaster页面,在工作线程上运行ps或在Dataproc云控制台页面上查看CPU使用率。

但是,这些类型的设置从来都不是100%“最佳”的,并且Dataproc尚未根据您实际运行的工作量或历史工作量自动预测设置。因此,对于群集上运行的所有工作负载,仅基于群集形状的任何设置都不能100%最优。

长话短说,在Dataproc上,您不必担心大多数情况下的显式优化,除非您试图真正地挤出每一盎司的效率,但与此同时,您始终可以随意覆盖Dataproc的设置如果需要,可以在群集创建或作业提交时使用您自己的属性。需要考虑的几点:

  • 如果与内存相比,cpu负载较大,请考虑使用“ highcpu”计算机类型,Dataproc将自动使每个执行程序为每个CPU分配更少的内存。
  • 如果您有更多的内存工作量,请考虑使用高内存类型
  • 如果输入不可拆分和/或高度压缩(如.csv.gz文件),则由于通常的并行计算将不知道输入数据是否会爆裂,您更有可能遇到内存问题大于预期。在这种情况下,您可能需要覆盖执行程序的内存,以使其更大
  • 如果您正在使用子进程或本机库,例如从工作人员任务中调用ffmpeg,则任务将消耗YARN / Spark所不了解的物理内存;在这些情况下,您可能还需要调整内存限制,方法是减少每个执行程序的内核数或增加执行程序的内存开销。
  • 如果您的内容受到IO的限制或在其他异步功能上受阻(例如,从任务中调用缓慢的外部Web终结点),则可能会受益于提高每个执行者的核心;那么Spark运行的任务将超过CPU的任务,但是如果任务仅在IO上等待,这将有助于提高效率。

答案 1 :(得分:0)

答案是肯定的。它取决于您的spark应用程序的行为,运行的虚拟机数量以及使用的虚拟机类型。以下是我的示例调整参数。

default_parallelism=512

PROPERTIES="\
spark:spark.executor.cores=2,\
spark:spark.executor.memory=8g,\
spark:spark.executor.memoryOverhead=2g,\
spark:spark.driver.memory=6g,\
spark:spark.driver.maxResultSize=6g,\
spark:spark.kryoserializer.buffer=128m,\
spark:spark.kryoserializer.buffer.max=1024m,\
spark:spark.serializer=org.apache.spark.serializer.KryoSerializer,\
spark:spark.default.parallelism=${default_parallelism},\
spark:spark.rdd.compress=true,\
spark:spark.network.timeout=3600s,\
spark:spark.rpc.message.maxSize=256,\
spark:spark.io.compression.codec=snappy,\
spark:spark.shuffle.service.enabled=true,\
spark:spark.sql.shuffle.partitions=256,\
spark:spark.sql.files.ignoreCorruptFiles=true,\
yarn:yarn.nodemanager.resource.cpu-vcores=8,\
yarn:yarn.scheduler.minimum-allocation-vcores=2,\
yarn:yarn.scheduler.maximum-allocation-vcores=4,\
yarn:yarn.nodemanager.vmem-check-enabled=false,\
capacity-scheduler:yarn.scheduler.capacity.resource-calculator=org.apache.hadoop.yarn.util.resource.DominantResourceCalculator
  "

gcloud dataproc clusters create ${GCS_CLUSTER} \
       --scopes cloud-platform \
       --image pyspark-with-conda-v2-365 \
       --bucket  spark-data \
       --zone  asia-east1-b  \
       --master-boot-disk-size  500GB \
       --master-machine-type n1-highmem-2 \
       --num-masters  1 \ 
        --num-workers  2 \
       --worker-machine-type n1-standard-8 \
       --num-preemptible-workers 2 \
       --preemptible-worker-boot-disk-size 500GB \
       --properties ${PROPERTIES}