spark streaming kafka offset commit

    由于spark的

  rdd.asInstanceOf[HasOffsetRanges].offsetRanges

这个操作:

stream.foreachRDD { rdd =>
  val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
  rdd.foreachPartition { iter =>
    val o: OffsetRange = offsetRanges(TaskContext.get.partitionId)
    println(s"${o.topic} ${o.partition} ${o.fromOffset} ${o.untilOffset}")
  }
}

Note that the typecast to HasOffsetRanges will only succeed if it is done in the first method called on the result of createDirectStream, not later down a chain of methods. Be aware that the one-to-one mapping between RDD partition and Kafka partition does not remain after any methods that shuffle or repartition, e.g. reduceByKey() or window().


就是说获取ossset这个操作必须是createDirectStream 之后的第一个方法内才可以成功。后续的方法都不可以。需要注意的是,RDD的partion和Kafka的partion的一对一映射关系在任何的shuff或者repartition ,比如reduceByKey 和window操作之后,都是不可用的。

 那么这就会造成at most onece的问题,如果你在接收到数据的时候就进行commit。如何保证at least once的,就必须在处理完自己逻辑的时候,commit offset。所以必须在处理逻辑开始前保存 保存住所有parttion的offset,然后处理完成在commit offset。

这里介绍一个实现方式:

可以把当前parition的offset 存储到一个外存,比如 redis或者hbase。这样在处理完成的时候查出来就行提交,处理终断的时候就不提交。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sure, 我可以回答您关于SparkStreaming读取kafka案例的问题。 SparkStreaming通过集成Kafka来实现从Kafka中读取数据流,下面是一个实现的案例: 1.首先,在工程中加入以下依赖: ```xml <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-streaming-kafka-0-10_2.11</artifactId> <version>2.4.0</version> </dependency> ``` 2.然后,创建Kafka配置对象和SparkStreaming上下文对象。 ```scala import org.apache.spark.streaming.kafka010.KafkaUtils import org.apache.kafka.common.serialization.StringDeserializer import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe val kafkaParams = Map[String, Object]( "bootstrap.servers" -> "localhost:9092", "key.deserializer" -> classOf[StringDeserializer], "value.deserializer" -> classOf[StringDeserializer], "group.id" -> "test-group", "auto.offset.reset" -> "latest", "enable.auto.commit" -> (false: java.lang.Boolean) ) val ssc = new StreamingContext(sparkConf, Seconds(5)) ``` 3.接下来,通过SparkStreaming读取Kafka数据流,并对数据流进行处理。 ```scala val topics = Array("test") val stream = KafkaUtils.createDirectStream[String, String]( ssc, PreferConsistent, Subscribe[String, String](topics, kafkaParams) ) stream.map(record => (record.key, record.value)) .filter(x => x._2.contains("error")) .map(_._2.split(" ")(1)) .foreachRDD(rdd => { rdd.foreachPartition(records => { val jedis = new Jedis("localhost") records.foreach(record => { jedis.incr(record) }) jedis.close() }) }) ``` 4.最后,启动SparkStreaming程序。 ```scala ssc.start() ssc.awaitTermination() ``` 这就是一个简单的SparkStreaming读取Kafka数据流的实现案例。 希望我的回答对您有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值