今天被同事问了一个简单又不简单的问题,一个spark app里面有两个job,那么,他们可以并行执行吗?
首先我们要了解一点,我们写的代码同一个线程都是按照顺序执行的,那么我们的job应该都是串行一个个执行。。。但真是这样么?
理论上,我们写spark core都不会用到多线程,那个代码的执行确实是一条线下去,当遇到action算子时会被阻塞,开始解析并执行这个spark任务,当任务执行完才会继续往下走。我们可以想想平时提交多job的任务,在webui上是不是一开始只看见一个job,一个执行完了才会有下一个。
那么如何并行呢?其实我们可以通过简单的多线程实现,只要我们的driver能读到多个action,那么他会把任务都提交上去,也就实现了我们job并行。
这个其实很好理解,完全符合我们一般写代码的逻辑,但是如果把这个扩展到spark streaming,可能就不是那么好使了,为什么呢?我们知道流处理是不间断的,会一遍又一遍重复去执行你的任务,这个时候如果你说是一条线程从头到尾,那就玩不下去了,那么这个时候spark是怎么处理的呢?我们可以简单这么理解,他会先将我们的代码逻辑解析出来,放到一个集合,然后在写个死循环,每隔一段时间去把集合里面的逻辑执行一遍。这样一来spark streaming就不局限于单个线程执行了,因为所有job都解析好了,我只是要去执行job,那我当然可以开启一个线程池,直接去执行任务了,而事实上,如果你看它底层实现,也确实是这样,并且提供了spark.streaming.concurrentJobs参数给我们配置job的并发度,也就不用我们自己去写多线程了,当然,默认是1,也就是串行执行。