Spark Streaming 中使用 zookeeper 保存 offset 并重用
来源:互联网 发布:excel数据统计分析方法 编辑:程序博客网 时间:2024/06/10 14:23
在 Spark Streaming 中消费 Kafka 数据的时候,有两种方式分别是 1)基于 Receiver-based 的 createStream 方法和 2)Direct Approach (No Receivers) 方式的 createDirectStream 方法,详细的可以参考 Spark Streaming + Kafka Integration Guide ,但是第二种使用方式中 kafka 的 offset 是保存在 checkpoint 中的,如果程序重启的话,会丢失一部分数据,可以参考 Spark & Kafka - Achieving zero data-loss 。
本文主要讲在使用第二种消费方式(Direct Approach)的情况下,如何将 kafka 中的 offset 保存到 zookeeper 中,以及如何从 zookeeper 中读取已存在的 offset。
大致思想就是,在初始化 kafka stream 的时候,查看 zookeeper 中是否保存有 offset,有就从该 offset 进行读取,没有就从最新/旧进行读取。在消费 kafka 数据的同时,将每个 partition 的 offset 保存到 zookeeper 中进行备份,具体实现参考下面代码
val topic : String = "topic_name" //消费的 topic 名字 val topics : Set[String] = Set(topic) //创建 stream 时使用的 topic 名字集合 val topicDirs = new ZKGroupTopicDirs("test_spark_streaming_group", topic) //创建一个 ZKGroupTopicDirs 对象,对保存 val zkTopicPath = s"${topicDirs.consumerOffsetDir}" 获取 zookeeper 中的路径,这里会变成 /consumers/test_spark_streaming_group/offsets/topic_name val zkClient = new ZkClient("10.4.232.77:2181") //zookeeper 的host 和 ip,创建一个 client val children = zkClient.countChildren(s"${topicDirs.consumerOffsetDir}") //查询该路径下是否字节点(默认有字节点为我们自己保存不同 partition 时生成的) var kafkaStream : InputDStream[(String, String)] = null var fromOffsets: Map[TopicAndPartition, Long] = Map() //如果 zookeeper 中有保存 offset,我们会利用这个 offset 作为 kafkaStream 的起始位置 if (children > 0) { //如果保存过 offset,这里更好的做法,还应该和 kafka 上最小的 offset 做对比,不然会报 OutOfRange 的错误 for (i <- 0 untilchildren) { val partitionOffset = zkClient.readData[String](s"${topicDirs.consumerOffsetDir}/${i}") val tp = TopicAndPartition(topic, i) fromOffsets += (tp -> partitionOffset.toLong) //将不同 partition 对应的 offset 增加到 fromOffsets 中 logInfo("@@@@@@ topic[" + topic + "] partition[" + i + "] offset[" + partitionOffset + "] @@@@@@") } val messageHandler = (mmd : MessageAndMetadata[String, String]) => (mmd.topic, mmd.message()) //这个会将 kafka 的消息进行 transform,最终 kafak 的数据都会变成 (topic_name, message) 这样的 tuple kafkaStream = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder, (String, String)](ssc, kafkaParam, fromOffsets, messageHandler) } else { kafkaStream = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParam, topics) //如果未保存,根据 kafkaParam 的配置使用最新或者最旧的 offset } var offsetRanges = Array[OffsetRange]() kafkaStream.transform{ rdd => offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges //得到该 rdd 对应 kafka 的消息的 offset rdd }.map(msg => Utils.msgDecode(msg)).foreachRDD { rdd => for (o <- offsetRanges) { val zkPath = s"${topicDirs.consumerOffsetDir}/${o.partition}" ZkUtils.updatePersistentPath(zkClient, zkPath, o.fromOffset.toString) //将该 partition 的 offset 保存到 zookeeper logInfo(s"@@@@@@ topic ${o.topic} partition ${o.partition} fromoffset ${o.fromOffset} untiloffset ${o.untilOffset} #######") } rdd.foreachPartition( message => { while(message.hasNext) { logInfo(s"@^_^@ [" + message.next() + "] @^_^@") } } ) }
使用上面的代码,我们可以做到 Spark Streaming 程序从 Kafka 中读取数据是不丢失
0 0
- Spark Streaming 中使用 zookeeper 保存 offset 并重用
- spark-streaming-[10]-Spark Streaming 中使用 zookeeper 保存 offset 并重用
- Spark Streaming 中使用kafka低级api+zookeeper 保存 offset 并重用 以及 相关代码整合
- Spark Streaming 中使用 zookeeper 保存 offset 并重用 Java版
- Spark Streaming 中使用kafka低级api+zookeeper 保存 offset 并重用 以及 相关代码整合
- Spark Streaming 中使用 zookeeper 保存 offset 并重用 Java版
- 将 Spark Streaming + Kafka direct 的 offset 保存进入Zookeeper
- Spark Streaming + Kafka direct 从Zookeeper中恢复offset
- 将 Spark Streaming + Kafka direct 的 offset 保存进入Zookeeper(二)
- Spark Streaming + Kafka direct 从Zookeeper中恢复offset(三)
- Spark Streaming createDirectStream保存kafka offset(JAVA实现)
- Spark Streaming +Kafka 使用底层API直接读取Kafka的Partition数据,手动更新Offset到Zookeeper集群
- spark streaming 读取kafka的offset
- spark streaming读取kafka数据,记录offset
- Spark Streaming 将数据保存在msyql中
- apach zeppelin中使用spark streaming:基本功能
- Spark Streaming 之 consumer offsets 保存到 Zookeeper 以实现数据零丢失
- Spark directStream保存/读取kafka offset
- idea创建一个maven项目
- css-列表图标兼容性
- 3月17日,GridLayoutDemo,每日20行。
- 生活中有哪些坏习惯一旦改正就能带来立竿见影的好处?
- 算法导论 练习题 3.1-1
- Spark Streaming 中使用 zookeeper 保存 offset 并重用
- CCF201312(3)ISBN号码校验
- 冒泡排序示例
- ***POJ 3180 Dollar Dayz【大数处理】
- 传智168期JavaEE Spring 姜涛 day38~day40笔记(by阿滔)(2017年3月17日20:17:13)
- 位运算的理解及使用
- Pillow和Numpy的图像基本操作
- 学习Lua笔记(二)
- QQ登录