[英]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.