如何解决一个执行器中有多少个并发任务,以及Spark如何在一个执行器中处理多个任务之间的多线程?
在Spark中,一次并行执行多少个任务?讨论位于 How are stages split into tasks in Spark?和 How DAG works under the covers in RDD?
但是我在那里找不到明确的结论。
请考虑以下情形(假设spark.task.cpus = 1
,为简单起见,忽略vcore
概念)
- 10个执行程序(2个内核/执行程序),10个分区=>我认为一次并发任务的数量为 10
- 10个执行程序(2个内核/执行程序),2个分区=>我认为一次并发任务的数量为 2
- 10个执行程序(2个内核/执行程序),20个分区=>我认为一次并发任务的数量是 20
- 10个执行程序( 1 内核/执行程序),20个分区=>我认为一次并发任务的数量为 10
我正确吗?关于第三种情况,是否会考虑在一个执行程序内部使用多线程(即2个线程,因为有2个内核),就 20 ?
UPDATE1
如果第三种情况正确,则表示:
- 当执行器中的空闲核心可用时,Spark可以自动决定触发该执行器中的多线程
- 当执行器中只有一个内核时,该执行器中不会发生多线程。
如果是这样,执行器中Spark的行为是否有点不确定(单线程与多线程)?
请注意,从驱动程序传送到执行程序的代码可能未考虑使用例如已同步关键字。
Spark如何处理?
解决方法
我认为您是对的,这取决于您的执行程序编号和内核,一个分区创建一个在一个内核上运行的任务。
,我认为所有4种情况都是正确的,而第4种情况在现实中是有意义的(“ overbook”核心)。通常我们应该考虑nb的2到4倍。分区,即nb。分区数等于nb的2到4倍。集群中的总CPU核心数量。
关于线程,并发运行的一个执行程序中的2个任务应该不存在有关多线程的问题,因为每个任务都在处理自己的RDD
集。
如果设置了spark.task.cpus = 2
,这意味着每个任务2个cpu内核,则IMO可能存在竞争条件问题(如果存在var
),但通常我们会处理{{ 1}},所以也应该只有问题。