我正在寻找一种在Scala 2.11上使用Spark on Dataproc的方法。我想使用2.11,因为我的作业引入了~10个BigQuery表,而我正在使用新的反射库将相应的对象映射到case类。 (新的反射类和并发性存在一个错误,只在Scala 2.11中修复)我尝试通过将executor-cores设置为1来解决这个问题,但性能降低是痛苦的。有没有更好的办法?
答案 0 :(得分:1)
通常,将executor-cores设置为1是解决并发问题的合理方法,因为经常会发生可能包含在Spark作业中的第三方库也存在线程安全问题;这里的关键是你应该能够将执行程序的大小调整为每个只有1个核心,而不会真正牺牲性能(较大的调度开销和纱线开销可能意味着大约10%的性能下降,但肯定没什么难以管理的)
我假设您指的是一些乘法因素性能下降,例如,仅使用8核VM上的8个核中的2个(默认情况下,每个VM的Dataproc包2个执行程序)。解决此问题的方法只是按比例调整spark.executor.memory
以匹配1核心。例如,在群集配置(gcloud dataproc clusters describe your-cluster-name
)中,如果使用4核VM,则可能会出现类似以下内容:
spark:spark.executor.cores: '2'
spark:spark.executor.memory: 5586m
YARN打包完全基于内存,而不是内核,因此这意味着5586m
被设计为适合半个YARN节点,因此对应于2个内核。如果你打开你的群集,如:
gcloud dataproc clusters create \
--properties spark:spark.executor.cores=1,spark:spark.executor.memory=2000m
然后你最终会得到一个仍然使用所有核心的设置,但没有并发问题(仅在每个执行程序进程中有一个工作线程)。
在这种情况下我没有使用5586/2
因为你必须考虑spark:spark.yarn.executor.memoryOverhead
,所以基本上你必须在memoryOverhead中加上,然后除以2,然后减去memoryOverhead再次确定新的执行程序大小,除此之外,分配也会循环到基本块大小的下一个倍数,我相信这是512米。
通常,您可以通过在每个内核的内存分配上稍低一点来使用反复试验,然后在发现需要更多内存空间时增加它。
您不必重新部署群集来检查这些;您可以在作业提交时指定这些,而不是更快的周转时间:
gcloud dataproc jobs submit spark \
--properties spark.executor.cores=1,spark.executor.memory=2000m