我有输入行如下
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)
}
答案 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))
}