[英]is rdd.contains function in spark-scala expensive
我从星火流中的Kafka流中收到了数百万条消息。 有15种不同类型的消息。 消息来自单个主题。 我只能通过其内容来区分消息。 所以我正在使用rdd.contains方法来获取不同类型的rdd。
样本信息
{“ a”:“ foo”,“ b”:“ bar”,“ type”:“ first” .......}
{“ a”:“ foo1”,“ b”:“ bar1”,“ type”:“ second” .......}
{“ a”:“ foo2”,“ b”:“ bar2”,“ type”:“ third” .......}
{“ a”:“ foo”,“ b”:“ bar”,“ type”:“ first” .......}
..............
...............
.........
依此类推
码
DStream.foreachRDD { rdd =>
if (!rdd.isEmpty()) {
val rdd_first = rdd.filter {
ele => ele.contains("First")
}
if (!rdd_first.isEmpty()) {
insertIntoTableFirst(hivecontext.read.json(rdd_first))
}
val rdd_second = rdd.filter {
ele => ele.contains("Second")
}
if (!rdd_second.isEmpty()) {
insertIntoTableSecond(hivecontext.read.json(rdd_second))
}
.............
......
same way for 15 different rdd
有什么办法可以从kafka主题消息中获得不同的rdd?
没有rdd.contains
。 这里使用的函数contains
应用于RDD
的String
。
像这儿:
val rdd_first = rdd.filter {
element => element.contains("First") // each `element` is a String
}
此方法不可靠,因为String中的其他内容可能满足比较要求,从而导致错误。
例如
{"a":"foo", "b":"bar","type":"second", "c": "first", .......}
解决此问题的一种方法是,首先将JSON数据转换为适当的记录,然后对这些记录应用分组或过滤逻辑。 为此,我们首先需要数据的架构定义。 使用该架构,我们可以将记录解析为json并在此之上进行任何处理:
case class Record(a:String, b:String, `type`:String)
import org.apache.spark.sql.types._
val schema = StructType(
Array(
StructField("a", StringType, true),
StructField("b", StringType, true),
StructField("type", String, true)
)
)
val processPerType: Map[String, Dataset[Record] => Unit ] = Map(...)
stream.foreachRDD { rdd =>
val records = rdd.toDF("value").select(from_json($"value", schema)).as[Record]
processPerType.foreach{case (tpe, process) =>
val target = records.filter(entry => entry.`type` == tpe)
process(target)
}
}
该问题未指定每种记录类型需要采用哪种逻辑。 这里介绍的是解决任何自定义逻辑都可以表示为Dataset[Record] => Unit
函数的通用方法。
如果逻辑可以表示为聚合,则Dataset
聚合功能可能更合适。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.