我有一个Spark流程,从kafka读取数据, 进入DStream。
在我的管道中,我两次(一个接一个):
DStream.foreachRDD(转换RDD并插入目的地)。
(每次我进行不同的处理并将数据插入到不同的目的地)。
我想知道DStream.cache,在我读取Kafka工作的数据之后会怎样?有可能吗?
现在该过程实际上是从Kafka读取数据两次吗?
请记住,不可能将两个foreachRDD合二为一(因为两个路径完全不同,那里有状态转换 - 需要在DStream上应用...)
感谢您的帮助
答案 0 :(得分:4)
有两种选择:
使用AVC
将基础RDD标记为已缓存。在由Dstream.cache()
配置控制的超时后,Spark Streaming将负责解决RDD问题。
使用其他spark.cleaner.ttl
将foreachRDD
和cache()
副作用操作应用于DStream中的RDD:
例如:
unpersist(false)
请注意,如果这是一个选项,您可以将缓存合并为val kafkaDStream = ???
val targetRDD = kafkaRDD
.transformation(...)
.transformation(...)
...
// Right before the lineage fork mark the RDD as cacheable:
targetRDD.foreachRDD{rdd => rdd.cache(...)}
targetRDD.foreachRDD{do stuff 1}
targetRDD.foreachRDD{do stuff 2}
targetRDD.foreachRDD{rdd => rdd.unpersist(false)}
的第一个语句。
我更喜欢这个选项,因为它让我能够对缓存生命周期进行细粒度的控制,并让我在需要时立即清理内容,而不是依赖于ttl。