Spark Streaming消费Kafka Avro数据

场景

上游数据同步mysql的binlog数据并推到kafka,我们作为下游需要将数据接过来,进行处理,之后存入对外提供服务的数据库中。

方案

使用Spark Streaming消费kafka实现近实时的效果,使用kafka低级api direct的方式,来接收数据

direct 方式会周期性地查询Kafka,来获得每个topic+partition的最新的offset,从而定义每个batch的offset的范围。当开始处理数据时,会获取指定offset范围的数据,当前批数据完全处理完成之后,再将offset提交,可以保证至少一次的特性。

如果数据丢在kafka自身的环节,由于每个topic是有副本的,可以通过副本机制找回。

如果是消费程序挂掉导致的数据缺失,由于上次的偏移量范围对应的batch没有处理成功,再次重启程序的时候,只会从上次成功的offset出开始消费,以此实现至少一次的语义。

code
val topic = tables.map("bb_" + _).toSet[String]
//获得sparkContext对象
val sc = SparkConfig.getSparkSession(s"kafka-streaming").sparkContext
//创建streamingContext
val ssc = new StreamingContext(sc,Milliseconds(millSeconds))

//kafka 配置
val kafkaParams = Map[String,Object](
    "bootstrap.servers" -> "xxxx:9092,xxxx:9092,xxxx:9092",
    "group.id" -> "xxxx",
    "auto.offset.reset" -> "earliest",
    //上游数据是avro格式的,配置avro schema registry解析arvo数据
    "schema.registry.url" -> "http://192.168.100.182:8081",
    "key.deserializer" -> classOf[StringDeserializer],
    //值是avro数据,需要通过KafkaAvroDeserializer反序列化
    "value.deserializer" -> classOf[KafkaAvroDeserializer],
    //自己来决定什么时候提交offset
    "enable.auto.commit" -> (false: java.lang.Boolean)
)

//使用的kafka010版本的api
val kafkaStream = KafkaUtils.createDirectStream[String,Object](
    ssc,
    //持久化策略
    PreferConsistent,
    //订阅信息
    Subscribe[String,Object](topic, kafkaParams)
)

//处理每个微批的rdd
kafkaStream.foreachRDD( rdd => {
    if(rdd!=null && !rdd.isEmpty()){
        //获取偏移量
        val offsetRange = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
        //对每个分区分别处理
        rdd.foreachPartition( iterator  => {
            if( iterator != null && !iterator.isEmpty ){
                 //作相应的处理
            	 while (iterator.hasNext) {
                     //处理每一条记录
                     val next = iterator.next
                     //这个就是接收到的数据值对象,
                     val record = next.value().asInstanceOf[Record]
                 	//可以插入数据库,或者输出到别的地方
                     ...
                 }
            }
        })
        //将偏移量提交(偏移量是提交到kafka管理的)
        kafkaStream.asInstanceOf[CanCommitOffsets].commitAsync(offsetRange)
        println("submit offset!")
    }
})

ssc.start()
ssc.awaitTermination()
pom

列出了反序列化avro和sparkstreaming结合kafka010的依赖,备忘

<dependency>
    <groupId>io.confluent</groupId>
    <artifactId>kafka-avro-serializer</artifactId>
    <version>3.0.0</version>
</dependency>

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
    <version>2.3.1</version>
</dependency>
相关链接

spark官方文档: http://spark.apache.org/docs/latest/streaming-kafka-0-10-integration.html

sparkstreaming kafka demo: https://dongkelun.com/2018/06/20/sparkStreamingOffsetOnlyOnce/

kafka 08和010概述: https://blog.csdn.net/weixin_43228814/article/details/88889894

spark消费kafka两种方式的区别: https://blog.csdn.net/qq_41571900/article/details/84205181


简单的应用层面,如果有不对的地方欢迎指正。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值