这可能是一个愚蠢的问题,但我似乎无法找到任何用纯英语澄清这一点的文件(好的,夸大的),在阅读官方文档和一些博客后,我仍然对驱动程序和执行者工作。
这是我目前的理解:
1)驱动程序定义转换/计算。
2)一旦我们调用SparkContext.start()
,驱动程序就会将定义的转换/计算发送给所有执行程序,这样每个执行程序都知道如何处理传入的RDD流数据。
好的,这里有一些令人困惑的问题:
1)驱动程序是否仅将定义的转换/计算发送给所有执行程序 ONCE AND FOR ALL ?
如果是这种情况,我们就没有机会重新定义/更改计算,对吗?
例如,我做一个与此one类似的字数统计工作,但是我的工作有点复杂,我想只计算前60年代以字母J
开头的单词,以及然后只有在接下来的60年代以字母K
开头的单词,然后只有以......开头的单词,继续。
那么我应该如何在驱动程序中实现此流媒体作业?
2)或者在每批数据完成后,驱动程序是否重新启动/重新安排所有执行程序?
后续
要解决1)问题,我想我可以使用一些外部存储介质,比如redis
,我的意思是我可以在驱动程序中实现处理函数count_fn
,每次都可以调用此count_fn
,它将从redis读取以获取起始字母,然后在RDD流中计数,这是正确的方法吗?
答案 0 :(得分:2)
驱动程序是否将定义的转换/计算发送给所有人 执行者只有ONCE和FOR ALL?
不,每个任务都被序列化并每批次迭代发送给所有工作人员。想想当你有一个在转换中使用的类的实例时会发生什么,Spark必须能够将具有所有状态的同一个实例发送给每个要执行的执行器。
如果是这种情况,我们将没有机会重新定义/更改 计算,对吧?
转换定义中的逻辑是不变的,但这并不意味着您无法查询存储影响转换中数据的信息的第三方。
例如,假设您有一些外部来源,表明您应该过滤哪些字母。然后你可以在DStream上调用transform
来从驱动程序中获取有关要过滤哪个字母的数据。
或者驱动程序在每个执行程序之后重新启动/重新计划所有执行程序 批量数据完成了吗?
它不会重新启动,它只是每批次间隔启动一个新作业。如果您将StreamingContext
批处理持续时间定义为60秒,则每60秒新作业(微批处理)将开始处理数据。
根据您的跟进,是的,这就是我的方式。