Spark Streaming:如何使用多个输入来处理作业?

时间:2016-03-01 16:26:25

标签: hadoop apache-spark stream spark-streaming flink-streaming

输入1: KV数据流 输入2:一些静态数据分区(用于处理输入1中的流)
可以将问题建模为以下图像:
enter image description here
与HDFS / RDD分区共存位置:我们如何确保流媒体任务Map1,Map2和Map3在存在HDFS / RDD分区的计算机上运行?

图片说明:假设 K 是流式密钥(不是元组)。 First Map将其转换为元组(具有空值)并将其广播到3个Mappers。每个映射器都在包含RDD(或HDFS文件,第二个输入和静态数据)的不同分区的不同节点上运行。每个Mapper使用RDD分区来计算密钥的值。最后,我们想要聚合键的值(使用reduceByKey _ + _)。

2 个答案:

答案 0 :(得分:1)

如果我理解正确:

  1. K是您RDD通过***DStream工作获得的streaming。我不知道您的传入数据的来源。此数据基本上是密钥的array/seq/list
  2. 您提到的静态数据是PairedRDD形式的<K, Object>。在Object,您要为Val_n中的密钥提取incoming RDD
  3. 您希望在此shuffle(或查找)过程中避免/最小化join
  4. 为此,最好的策略是使用incoming RDDStatic RDD的{​​{3}}操作,两个RDD partitioned使用相同的Join。如果数据RDD中的任何一个比另一个小得多,您可以探索broadcasting较小的数据。我最近在我的项目中尝试了这个并在帖子中分享了经验:Partitioner

    修改:由于您要处理密钥,K(假设K =设置{K1,K2 ... Kn}),使用StaticRDD,对于分区,我建议采用如下方法。我没有检查语法和正确性,但你会得到意图。

    val kRddBroadcastVar = .... // broadcasted variable 
    val keyValRDD = staticRDD.mapPartitions {   
           iter => transformKRddToTuple2Events(iter, kRddBroadcastVar )
         }
    
    def transformKRddToTuple2Events( iter: Iterator[Object], kRddBroadcastVar: List[KeyObjectType] ) : Iterator[(keyObjectType, valueObjectType )] {    
         val staticList = iter.toList
         val toReturn   = kRddBroadcastVar.map ( k => getKeyValue(k, staticList) )    
         toReturn.iterator
    }
    
    val outRdd = keyValRDD.reduceByKey( _ + _ )
    

    如果这有意义,请接受此答案。

答案 1 :(得分:1)

您的静态RDD是否足够小以便缓存。在这种情况下,Spark将尝试在这些节点上运行流任务。虽然不能保证。

此外,如果参考数据的尺寸很小,为什么不广播该数据集。

我们一直在尝试解决有关数据存储SnappyData(http://www.snappydata.io/)中首选位置的类似问题,其中数据位置是一等公民。