spark scala 实时解析Json 数组
实时数据源Kafka
大数据接入实时数据早已大势已去,很多大厂更是实时数据常态化,但是最近发现网上并没有类似的数据处理过程推荐,这里是我结合工作场景写的一篇文章,有很多不足,烦请指正,谢谢
JSON数组是各个业务系统最喜欢生成的文件,平日里有许多log文件95%以上都是json格式的数据,最近SDK系统产生的数据放入kafka中,提供大数据中心来消费
先看数据
这是一个业务线每天产生的数据,数据在kafka中有同样的数据,这里使用flume备份到hdfs上,我们看一下详细数据,可以看到每一行都是json数组
取一条数据数据,这json格式数据多变的,每条数据有0.1K到10K不等,如下是一条数据
由于sdk部门时间过于宝贵,我们的所有json数组都放在一个topic中,下面进行实地解析
数据解析
我们先消费所有数据,同时提取有用的数据,
某库ID(contain_id):3332374c-7777e8s
我们就需要这个数据其他的排除
环境准备
code实现
import com.google.gson.JsonParser
import com.Until._
import com.OBJ.Product
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.spark.sql.SparkSession
import org.apache.spark.streaming.dstream.InputDStream
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.kafka010.{ConsumerStrategies, LocationStrategies}
import scala.collection.mutable.ListBuffer
object LocalKafkaTest {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master("local[2]")
.appName("LocalKafka")
.config("spark.sql.authorization.enabled", value = true)
.getOrCreate()
//指定topic
val topics = Array("test")
val context = spark.sparkContext
val ssc = new StreamingContext(context, Seconds(15))
// 创建stream流
val stream: InputDStream[ConsumerRecord[String, String]] =
org.apache.spark.streaming.kafka010.KafkaUtils.createDirectStream(
ssc,
LocationStrategies.PreferConsistent,
ConsumerStrategies.Subscribe(topics, getkafkaParms()))
// 这里用flatmap把所有数组扁平化
val filterRdd = stream.map(_.value()).flatMap(lines => {
val buffer = new ListBuffer[Product]
val asJsonArray = new JsonParser().parse(lines).getAsJsonArray
for (index <- 0 until asJsonArray.size()) {
val asJsonObject = asJsonArray.get(index).getAsJsonObject
if (new objGetType().GetType(asJsonObject).equals("product")) {
//把每一条明细,结构化为对象,方便转化为DF或者DSet
buffer += new JSONToProduct().JSONToProduct(asJsonObject)
}
}
buffer
}).filter(r => r != null)
filterRdd.foreachRDD(x=>x.foreach(y=>println(y.toString)))
ssc.start()
ssc.awaitTermination()
}
//kafka相关的配置参数
//http://kafka.apache.org/documentation.html#consumerconfigs
def getkafkaParms(): collection.Map[String, Object] = {
val kafkaParam = new scala.collection.mutable.HashMap[String, Object]()
kafkaParam.put("bootstrap.servers", "localhost:9092")
kafkaParam.put("group.id", "Kafkahbase")
kafkaParam.put("max.partition.fetch.bytes", "500000000")
kafkaParam.put("auto.offset.reset","latest")
kafkaParam.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
kafkaParam.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
kafkaParam
}
}
kafka插入数据
[{“tenant_id”:674,“container”:{“update_time”:1611903560741,“create_time”:1611866047201,“custom_properties”:{“resource_source”:“SUBSCRIBE”,“from”:“00000000-0000-0000-0000-000000000000,7772374c-92a5-4179-bd1d-7b6ae3337e8d,93846ed3-ce3a-405d-a3c5-2d2bd1603691”},“updater”:“zBhx84v59cg616sRv584”},“container_ext_info”:{"__name":“上海市人工智能”},“resource_type_code”:“questions”,“resource_id”:“102b629d-dec8-4dcd-86f6-92bee691c334”,“change_type”:“UPDATE”,“container_custom_properties”:{“owner”:“uid:205021”,“creator”:“10006945”,“default_sync_policy”:[“wx-product”],“restypes_config”:{},“file_sync_policy”:[“wx-product”],"__name":“上海市人工智能”},“container_id”:“7772374c-92a5-4179-bd1d-7b6ae3337e8d”},{“tenant_id”:674,“container”:{“update_time”:1611903560741,“create_time”:1611866047201,“custom_properties”:{“resource_source”:“SUBSCRIBE”,“from”:“00000000-0000-0000-0000-000000000000,7772374c-92a5-4179-bd1d-7b6ae3337e8d,93846ed3-ce3a-405d-a3c5-2d2bd1603691”},“updater”:“zBhx84v59cg616sRv584”},“container_ext_info”:{"__name":“上海市人工智能”},“resource_type_code”:“questions”,“resource_id”:“102b629d-dec8-4dcd-86f6-92bee691c334”,“change_type”:“UPDATE”,“container_custom_properties”:{“owner”:“uid:205021”,“creator”:“10006945”,“default_sync_policy”:[“wx-product”],“restypes_config”:{},“file_sync_policy”:[“wx-product”],"__name":“上海市人工智能”},“container_id”:“7772374c-92a5-4179-bd1d-7b6ae3337e8d”}]
解析结果
备注:
1code实现是Google JSON解析包,因为阿里JSON突然出现了漏洞,后续的话会改回来
2数据如果有雷同,纯属巧合