Spark定制功能的流组

时间:2016-02-21 17:08:52

标签: scala apache-spark spark-streaming

我有输入行如下

t1, file1, 1, 1, 1
t1, file1, 1, 2, 3
t1, file2, 2, 2, 2, 2
t2, file1, 5, 5, 5
t2, file2, 1, 1, 2, 2

我想实现下面的行输出,这是相应数字的垂直添加。

file1 : [ 1+1+5, 1+2+5, 1+3+5 ]
file2 : [ 2+1, 2+1, 2+2, 2+2 ]

我处于火花流式传输环境中,我很难找到按文件名聚合的方式。

似乎我需要使用类似下面的内容,我不知道如何获得正确的语法。任何输入都会有所帮助。

myDStream.foreachRDD(rdd => rdd.groupBy())myDStream.foreachRDD(rdd => rdd.aggregate())

我知道如何处理给定数字的数组的垂直和,但我不知道如何将该函数提供给聚合器。

def compute_counters(counts : ArrayBuffer[List[Int]]) = {
  counts.toList.transpose.map(_.sum)
}

2 个答案:

答案 0 :(得分:2)

首先,您需要从逗号分隔的字符串中提取相关的键和值,解析它们,并创建一个包含键的元组,以及使用InputDStream.map的整数列表。然后,使用PairRDDFunctions.reduceByKey应用每个密钥的总和:

dStream
.map(line => {
  val splitLines = line.split(", ")
  (splitLines(1), splitLines.slice(2, splitLines.length).map(_.toInt))
})
.reduceByKey((first, second) => (first._1, Array(first._2.sum + second._2.sum))
.foreachRDD((key, sum) => println(s"Key: $key, sum: ${sum.head}")

reduce将产生一个(String, Array[Int])元组,其中字符串包含id(是“test1”或“test2”),以及一个包含单个值的数组,包含每个键的总和。

答案 1 :(得分:1)

感谢Yuval,我能够用你的方法做到这一点。更新我的最终工作代码:

def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("HBaseStream")
    val sc = new SparkContext(conf)
    // create a StreamingContext, the main entry point for all streaming functionality
    val ssc = new StreamingContext(sc, Seconds(2))
    val inputStream = ssc.socketTextStream("hostname", 9999)
    val parsedDstream = inputStream
      .map(line => {
        val splitLines = line.split(",")
        (splitLines(1), splitLines.slice(2, splitLines.length).map(_.trim.toInt))
      })
      .reduceByKey((first, second) => {
        val listOfArrays = ArrayBuffer(first, second)
        listOfArrays.toList.transpose.map(_.sum).toArray
      })
      .foreachRDD(rdd => rdd.foreach(Blaher.blah))
}