Spark streaming手动保存offset到zk java实现

基于PySpark整合Spark Streaming与Kafka 本文介绍了基于PySpark整合Spark Streaming和Kafka实现实时消息处理的方案。首先搭建了单机Kafka环境(版本2.11-2.4.0),配置了Zookeeper和Kafka服务,并测试了消息生产消费功能。然后详细说明了Spark Streaming连接Kafka所需的两个关键JAR包,给出了PySpark程序示例,演示了如何通过KafkaUtils.createDirectStream接口实时消费Kafka消息并进行单词计数。程序采用Direct API模式,每5秒统计一次单词频率并输出 阅读详情

前言

网上有部分案例是关于手动设置kafka中offset的,不过大多采用的是0.8的kafka版本,采用scala的编写,kafka-0.10版本的鲜有提及,或者都不完整。0.10版本是可以兼容之前的,但是新版本的api确实要更简洁易用。找不到可以直接拿来就用的,所以这里抽时间看官网api,写个较为完整的JAVA测试用例,希望对大家有帮助。

pom依赖版本

	<dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-core_2.11</artifactId>
      <version>2.2.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-streaming_2.11</artifactId>
      <version>2.2.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
      <version>2.2.0</version>
    </dependency>

Demo

话不多说上代码。注释较少,不过代码命名就是很好的注释了。

import org.I0Itec.zkclient.ZkClient;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.spark.SparkConf;
import org.apache.spark.streaming.Durations;
import org.apache.spark.streaming.api.java.JavaDStream;
import org.apache.spark.streaming.api.java.JavaInputDStream;
import org.apache.spark.streaming.api.java.JavaPairDStream;
import org.apache.spark.streaming.api.java.JavaStreamingContext;
import org.apache.spark.streaming.kafka010.*;
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
import org.apache.spark.streaming.kafka010.LocationStrategies;
import scala.Tuple2;

import java.util.*;
public class WordCount {
    private static String groupId = "group1";

    private static Map<TopicPartition,Long> offsets = new HashMap<>();
    // 消费者组根路径
    private static Collection<String> topics = Arrays.asList( "mytest-topic","dc01");

    private static String zkServerUrls = "dc-sit-225:2181";
	// 实际应用中需要序列化存储,不然zkCli.sh读取会乱码,相关组件也无法识别
    private static ZkClient zkClient = new ZkClient(zkServerUrls);
    // 消费者组根路径,kafka-manage会读取该路径
    private static String rootPath = "/consumers" + groupId + "/offsets/";

    public static void main(String[] args) throws InterruptedException {
        SparkConf conf = new SparkConf().setMaster("local[2]").setAppName("KafkaWordCount");
        JavaStreamingContext jssc = new JavaStreamingContext(conf, Durations.seconds(5));
        initOffset(zkClient);
        JavaInputDStream<ConsumerRecord<String, String>> stream =
                KafkaUtils.createDirectStream(
                        jssc,
                        LocationStrategies.PreferConsistent(),
                        // 配置主题,kafka参数,offsets
                        ConsumerStrategies.<String, String>Subscribe(topics, initKafkaParams(),offsets)
                );
        JavaDStream<String> words = stream.flatMap(x -> updateOffset(x));
        // Count each word in each batch
        JavaPairDStream<String, Integer> pairs = words.mapToPair(s -> new Tuple2<>(s, 1));
        JavaPairDStream<String, Integer> wordCounts = pairs.reduceByKey((i1, i2) -> i1 + i2);
        wordCounts.print();
        jssc.start();              // Start the computation
        jssc.awaitTermination();   // Wait for the computation to terminate
    }

    public static void initOffset(ZkClient zkClient){
        if (!zkClient.exists(rootPath)){
            for (String topic : topics){
                String path = rootPath + "/" + topic ;
                zkClient.createPersistent(path,true);
            }
        }else {
            List<String> topicSet = zkClient.getChildren(rootPath);
            for (String topic : topicSet){
                String topicPath = rootPath + "/" + topic;
                List<String> partitionSet = zkClient.getChildren(topicPath);
                for (String partition : partitionSet){
                    Long offset = zkClient.readData(topicPath + "/" + partition);
                    TopicPartition topicPartition = new TopicPartition(topic, Integer.valueOf(partition));
                    // 注意这里offset需要往后移一位,不然会出现重复消费
                    if (offset != 0){
                        offset += 1;
                    }
                    offsets.put(topicPartition,offset);
                }
            }
        }
    }

    public static Map initKafkaParams(){
        Map<String, Object> kafkaParams = new HashMap<>();
        kafkaParams.put("bootstrap.servers", "dc-sit-225:9092");
        kafkaParams.put("key.deserializer", StringDeserializer.class);
        kafkaParams.put("value.deserializer", StringDeserializer.class);
        kafkaParams.put("group.id", groupId);
        kafkaParams.put("auto.offset.reset", "earliest");
        kafkaParams.put("enable.auto.commit", false);
        return kafkaParams;
    }

    public static Iterator<String> updateOffset(ConsumerRecord<String,String> consumerRecord){
        String path = rootPath + "/" + consumerRecord.topic() + "/" + consumerRecord.partition();
        if (!zkClient.exists(path)){
            zkClient.createPersistent(path,true);
        } else{
            zkClient.writeData(path, consumerRecord.offset());
        }
        return Arrays.asList(consumerRecord.value().split(" ")).iterator();
    }
}
Spark整合Kafka并手动维护offset Spark整合Kafka两种模式说明 开发中我们经常会利用SparkStreaming实时地读取kafka中的数据然后进行处理,在Spark1.3版本后,KafkaUtils里面提供了两种创建DStream的方法: 1.Receiver接收方式:KafkaUtils.createDstream 有一个Receiver作为常驻的Task运行在Executor等待数据,但是一个Receiver效率低,... 阅读详情

相关推荐

Spark Streaming offset的管理那些事!

Spark Streaming offset的管理那些事! 1.Kafka 消息的管理办法 (1) topic topic中包含多个分区,建议分区是Kafka broker的整数倍,或者是磁盘的整数倍 分区数是Kafka存储的主要概念,key的Hash&numPartition,在分区里存储的时候,offset-msg 消费者 消费消息 首先会自己确定offset的范围,然后使用该范围去k...

weixin_43390992的博客 440

使用SparkStreaming获取Kafka中的流式数据并指定手动提交offset

概述 本篇文章主要有三个示例代码,第一个主要功能是使用sparkstreaming获取kafka中的流式数据,第二个主要解决自动提交偏移量的解决方法:指定检查点,第三个示例是使用手动提交的方式解决自动提交过程中可能出错的问题。还可以指定存储器实现精准一一致性,后续再补上! 题外话:sparkstreaming毕竟不是真正的实时计算,底层原理是将数据流离散化为一个一个的微批次,在精准一致消费流式数据上远没有flink方便!!!所以sparkstreamign只建议使用在对实时性要求在秒级查询得场景!!! 一、

weixin_42796403的博客 2181

手把手教你搞定Pattern Recognition Letters的LaTeX投稿(附elsarticle.cls生成避坑指南)

本文详细指导如何在Pattern Recognition Letters(PRL)期刊上使用LaTeX进行投稿,特别针对elsarticle.cls文件的生成与常见问题提供避坑指南。从模板准备、文件上传到投稿后的验证,系统梳理全流程技术要点,帮助研究者高效完成学术论文投稿。

weixin_33824385的博客 430

SparkStreaming实现Exactly Once语义(将offset交给zk托管)

声明下使用的框架使用的版本 spark - 2.3.4 spark-streaming-kafka-0-10_2.11 - 2.3.4 zookeeper - 3.4.14 kafka - 2.3.1 看了下源码好多老的API都不能使用了。 KafkaCluster不存在了,ZKUtils 也 替换为 AdminClient 了。 接着上次实现的自定义分区消费来做Exactly Once 官网...

weixin_41008393的博客 278

《UE4游戏开发》之 《查cook资源失败,问题记录》

当项目打包时,cook出错,但是从原始引擎提供的信息中,没有提示具体的那个资源出错,要查到出错资源,还是非常麻烦。 下面就材质cook出错,增加一些日志,方便查找问题做简单记录 材质cook的一个阶段,是收集MaterialShaderMap,如果在这个阶段收集的信息出错,将会在FShaderMapContent::GetOutdatedTypes函数中,因为Shaders指针指向的内存有问题而出错,通过断点发现,FShaderMapContent这个类对象指针为null,而这个类对象的来源于AllMat.

qq_21919621的博客 2580

【ArcGIS】ArcMap中北京1954坐标系转WGS84的实战技巧与参数选择

本文详细解析了在ArcMap中将北京1954坐标系数据转换为WGS84坐标系的完整流程与核心技巧。针对常见的坐标偏移问题,文章首先强调了数据“归位”的重要性,并提供了处理假东、假北值的具体操作步骤。随后,重点阐述了地理变换参数(如Beijing_1954_To_WGS_1984_2)的选择逻辑及其对转换精度的决定性影响,并结合案例说明了参数选择、中央经线确认及结果验证等关键环节,旨在帮助用户高效、准确地完成坐标转换。

f6g7h8i9j的博客 329

spark-streaming-[10]-Spark Streaming 中使用 zookeeper 保存 offset 并重用

转载于:Spark Streaming 中使用 zookeeper 保存 offset 并重用 多谢分享 在 Spark Streaming 中消费 Kafka 数据的时候,有两种方式分别是 1)基于 Receiver-based 的 createStream 方法和 2)Direct Approach (No Receivers) 方式的 createDirectStream 方法,详

hjw199089的博客 1907

告别CANoe?手把手教你用Python+PCAN搭建汽车诊断脚本(附完整代码)

本文详细介绍了如何利用Python和PCAN硬件搭建高性价比的汽车诊断自动化方案,替代昂贵的CANoe工具。通过开源库python-can和udsoncan实现UDS诊断协议,涵盖硬件选择、环境配置、核心功能实现及性能优化,附完整代码示例,助力开发者快速构建诊断脚本。

weixin_42551227的博客 373

Spark Streaming 中使用 zookeeper 保存 offset 并重用 Java版

最近中使用spark Streaming +kafka,由于涉及到金额,所以需要保证at only one, 而网上关于java版的kafka offset回写zk的资料少之又少,于是总结一下,希望可以为广大使用java的友友们提供参考!这里采用的是Direct Approach的方式. 各位看官,接下来让我们一起开始 offset的冒险之旅吧!(基于 spark 1.6 kafka 0

shengjk1的博客 3776

16. SAP Fiori Elements 应用里图片字段(Image)的显示原理介绍

很多朋友向我反映,学习了 一段时间的 SAP Fiori Elements 开发,但是感觉整套体系对于自己来说还是个黑盒子,很多技术点,看了 SAP 官方帮助文档后,觉得自己懂了,但是一旦需要自己动手做一些东西出来时,又觉得一片茫然。 其实笔者自己也经历过这个过程。究其原因,还是大家对 Fiori Elements 一些技术细节没有理解,对 SAP 官方的知识点仅仅停留在记忆,甚至是死记硬背上面。 不过没有关系,本教程笔者会刻意设置一些练习,让大家动手,在实战中逐渐熟悉 Fiori Elements 这

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 754

风电功率预测 | 基于RF随机森林的风电功率预测(附matlab完整源码)

风电功率预测 | 基于RF随机森林的风电功率预测(附matlab完整源码)

天天酷科研的博客 896

spark createDirectStream保存kafka offset(JAVA实现)

问题描述最近使用spark streaming处理kafka的数据,业务数据量比较大,使用了kafkaUtils的createDirectStream()方式,此方式跳过了zookeeper,并且没有receiver,能保证消息恰好一次语意。但是此种方式因为没有经过zk,topic不能自动保存offset,本文讨论在使用createDirectStream时如何保存kafka topic offset。

xueba207的专栏 1万+

【XCharts插件】3-1、制作图表及代码生成图表(v1.0)

XCharts插件是一款基于UGUI的功能强大、易用、参数可配置的数据可视化图表插件。【Unity3D插件】XCharts插件完全教程《全网最全》-专栏文章目录OK,这是v1.0版本的XCharts插件的创建图表,代码生成图表的教程。可能有人要问了,既然都更新到v3.0了,还写啥v1.0教程呢。因为有些项目就是用v1.0去制作图表了,也没有太多的精力去更新插件,所以就一直用的v1.0,而且v1.0已经能实现大部分的图标样式了,所以,博主还是单独写了一篇文章来介绍v1.0的功能。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 1293

将 Spark Streaming + Kafka direct 的 offset 保存进入Zookeeper

在上一遍《“Spark Streaming + Kafka direct + checkpoints + 代码改变” 引发的问题》中说到,当时是将 topic 的 partition 的 offset 保存到了 MySQL 数据库中,其存在一个问题,就是无法在现有的监控工具中进行体现(如:Kafka Manager)。那我们现在就来将此offset保存到zookeeper中,从而使用监控工具发挥其效

天天 debug 4001

816华为OD机试真题 新系统 - 电池充电时间计算 (Java/Py/C/C++/Js/Go)

816华为OD机试真题 新系统 - 电池充电时间计算 (Java/Py/C/C++/Js/Go)

算法大师! 470

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

spark streaming消费kafka数据手动管理偏移量offset到zookeeper,保证精准消费一次

Spark Streaming消费kafka数据手动管理偏移量offset到zookeeper,保证精准一致消费,最终的处理结果保存在mysql中。 spark的版本是2.1 kafka的版本是0.8 代码: /** * @author lhq * @date 2020/10/10 10:35 * @version 1.0 */ import java.sql.{Connection, DriverManager, PreparedStatement} import kafka.com

weixin_43806056的博客 726

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Spark Streaming createDirectStream保存kafka offset(JAVA实现)

问题描述(http://blog.youkuaiyun.com/xueba207/article/details/50381821) 最近使用spark streaming处理kafka的数据,业务数据量比较大,就使用了kafkaUtils的createDirectStream()方式,此方法直接从kafka的broker的分区中读取数据,跳过了zookeeper,并且没有receiver,是spa

2486

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

spark streaming kafka OffsetOutOfRangeException 异常分析与解决

job中使用Kafka DirectStream 读取topic中数据,然后做处理。其中有个测试job,停止了几天,再次启动时爆出了**kafka.common.OffsetOutOfRangeException**。下文记录下异常分析与解决过程。

xueba207的专栏 3万+

spark streaming kafka OffsetOutOfRangeException

spark streaming kafka OffsetOutOfRangeException 异常分析与解决 自从把spark 从1.3升级到1.6之后,kafka Streaming相关问题频出。最近又遇到了一个。 job中使用Kafka DirectStream 读取topic中数据,然后做处理。其中有个测试job,停止了几天,再次启动时爆出了kafka.common.OffsetOutO...

top8488.top大数据 544

Spark Streaming篇5:Spark Streaming自定义zookeeper管理offset

spark篇7:sparkstreaming自定义zookeeper管理offset 废话不多说,直接上干货 package com.iflytek.offset import org.apache.curator.framework.CuratorFrameworkFactory import org.apache.curator.retry.ExponentialBackoffRetry i...

qq_38740498的博客 292

spark streaming以direct方式将offset保存在zookeeper

direct_offset_zookeeper类: /** * * @description: 使用Spark-Kafka-0-10版本整合,并手动提交偏移量,维护到Zookeeper中 * @author: wanjintao * @time: 2020/6/27 13:48 * */ package com.offsetzookeeper import org.apache.kafka.common.TopicPartition import org.apache.kafka.commo

wjt199866的博客 562

[技术应用] 将 Spark Streaming + Kafka direct 的 offset 存入Zookeeper并重用

问题导读: 1. 使用Direct API时为什么需要见offset保存到Zookeeper中? 2. 如何将offset存入到Zookeeper中? 3. 如何解决Zookeeper中offset过期问题? 实现将offset存入Zookeeper 在 Spark Streaming 中消费 Kafka 数据的时候,有两种方式分别是 1)基于 Receiver-based 的 createS...

YZY_001的博客 531

Spark createDirectStream保存kafka offset(JAVA实现)

Spark createDirectStream保存kafka offset(JAVA实现) 问题描述 最近使用Spark streaming处理kafka的数据,业务数据量比较大,就使用了kafkaUtils的createDirectStream()方式,此方法直接从kafka的broker的分区中读取数据,跳过了zookeeper,并且没有receiver,是spa

Make progress step by step everyday..... 836

SparkStreaming Kafka 自动保存offset到zookeeper

spark使用的是1.6,SparkStreaming1.6时候使用的kafka jar包为0.8的,消费时候不记录消费到的信息,导致重复消费,故手动保存到zookeeper,SparkStreaming2.1.1时使用的kafka jar包为0.10,没有出现这种状况,以下是1.6版本的消费...

jast 470
上一篇: mybatis判断list集合是否包含指定数据
下一篇: clickhouse(三、查询同步远程集群)
yyoc97
博客等级 码龄12年 272粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值