我遇到了以下用于处理Spark Streaming中消息的代码:
val listRDD = ssc.socketTextStream(host, port)
listRDD.foreachRDD(rdd => {
rdd.foreachPartition(partition => {
// Should I start a separate thread for each RDD and/or Partition?
partition.foreach(message => {
Processor.processMessage(message)
})
})
})
这对我有用,但我不确定这是不是最好的方法。据我所知,DStream包括"一对多" RDD,但是这个代码依次顺序处理RDD,对吧?难道我没有更好的方法 - 方法或函数 - 我可以使用它来使DStream中的所有RDD并行处理?我应该为每个RDD和/或分区启动一个单独的线程吗?我是否误解了此代码在Spark下的工作原理?
不知何故,我认为这段代码没有利用Spark中的并行性。
答案 0 :(得分:2)
为了方便和高效,Streams在小RDD中进行分区(检查micro-batching。但是你真的不需要将每个RDD分解为分区,甚至不需要将流分解为RDD。
这完全取决于Processor.processMessage
到底是什么。如果它是单个转换函数,您只需执行listRDD.map(Processor.processMessage)
即可获得处理消息的结果流,并行计算,无需您执行其他操作。
如果Processor
是一个保持状态(例如,计算消息数量)的可变对象,那么事情会更复杂,因为您需要定义许多此类对象以解决并行问题,并且还需要以某种方式稍后合并结果。