这可能是一个愚蠢的问题,但我似乎找不到任何纯英文的文档来阐明这一点(好吧,夸张了),在阅读了官方文档和一些博客之后,我仍然对驱动程序和执行者工作。
这是我目前的理解:
1) 驱动程序定义转换/计算。
2) 一旦我们调用SparkContext.start(),驱动程序就会将定义的转换/计算发送给所有执行器,这样每个执行器就知道如何处理传入的RDD流数据。
好的,这是我有一些令人困惑的问题:
1) 驱动程序是否仅将定义的转换/计算发送给所有执行程序ONCE AND FOR ALL?
如果是这种情况,我们就没有机会重新定义/更改计算,对吧?
例如,我做的字数统计工作类似于 one ,但是我的工作有点复杂,我只想计算前 60 秒以字母 J 开头的单词,然后只计算接下来 60 秒以字母 K 开头的单词, 然后只有以......开头的单词,继续下去。
那么我应该如何在驱动程序中实现这个流式处理作业呢?
2) 或者在每批数据完成后,驱动程序是否重新启动/重新安排所有执行程序?
跟进
为了解决 1) 的问题,我想我可以利用一些外部存储介质,比如 redis,我的意思是我可以实现一个处理函数 count_fn driver,每次调用这个count_fn的时候,都会从redis中读取首字母,然后在RDD流中进行计数,这样的做法对吗?
请您参考如下方法:
Does the driver send the defined transformation/computation to all executors only ONCE AND FOR ALL?
不,每个任务都被序列化并发送给每个批处理迭代的所有工作人员。想一想当您有一个在转换中使用的类的实例时会发生什么,Spark 必须能够将同一个实例及其所有状态发送给每个执行程序以进行操作。
If this is the case, we wouldn't have any chance to redefine/change the computation, right?
转换定义中的逻辑是不变的,但这并不意味着您不能查询存储影响转换中数据的信息的第三方。
例如,假设您有一些外部来源指示您应该过滤哪些字母。然后,您可以调用 DStream 上的 transform 以从驱动程序中获取有关按哪个字母过滤的数据。
Or does the driver restart/reschedule all the executors after each batch of data is done?
它不会重新启动,它只是在每个批处理间隔开始一个新作业。如果您将 StreamingContext 批处理持续时间定义为 60 秒,则每 60 秒一个新作业(微批处理)将开始处理数据。
根据您的跟进,是的,我会这样做。
