kafka直连方式消费多个topic
一个消费者组可以消费多个topic,以前写过一篇一个消费者消费一个topic的,这次的是一个消费者组通过直连方式消费多个topic,做了小测试,结果是正确的,通过查看zookeeper的客户端,zookeeper记录了偏移量
package day04
/*
消费多个topic
*/
import kafka.common.TopicAndPartition
import kafka.message.MessageAndMetadata
import kafka.serializer.StringDecoder
import kafka.utils.{ZKGroupTopicDirs, ZkUtils}
import scala.collection.mutable.ListBuffer
import org.I0Itec.zkclient.ZkClient
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.InputDStream
import org.apache.spark.streaming.kafka.{HasOffsetRanges, KafkaUtils, OffsetRange}
import org.apache.spark.streaming.{Duration, StreamingContext}
object OrderDemoYY1 {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("yy").setMaster("local[*]")
val ssc = new StreamingContext(conf,Duration(5000))
//消费3个topic
val topic1 = "wc"
val topic2 ="wc1"
val topic3 ="wc2"
//组名
val groupid ="GPMMVV"
//zookeeper地址
val zkQuorum = "hadoop01:2181,hadoop02:2181,hadoop03:2181"
//brokerList
val brokerList = "hadoop01:9092,hadoop02:9092,hadoop03:9092"
//把消费的分区放到Set集合中,可以在第一次读取时作为参数传入
val topics = Set(topic1,topic2,topic3)
//ListBuffer时有序的,按下标有序
val topicsList = ListBuffer[String](topic1,topic2,topic3)
//设置kafka的参数
val kafkaParams = Map(
"metadata.broker.list"->brokerList,
"groupid"->groupid,
"auto.offset.reset"->kafka.api.OffsetRequest.SmallestTimeString
//默认时从头开始读的
)
//new ListBuffer用来存放ZKGroupTopicDirs, 用来保存偏移量的地址
//因为有多个topic,对应的也就有多个ZKGroupTopicDirs
var zkGTList:ListBuffer[ZKGroupTopicDirs] =new ListBuffer[ZKGroupTopicDirs]()
//根据topicList 新建 ZKGroupTopicDirs 添加到zkGTList
for(tp <- topicsList){
val topicDirs = new ZKGroupTopicDirs(groupid,tp)
zkGTList += topicDirs
}
//新建zkClient,用来获取偏移量和更新偏移量
val zkClient = new ZkClient(zkQuorum)
//新建一个InputDStream,要是var,因为有两种情况,消费过? 没有消费过? 根据情况赋值
var kafkaDStream :InputDStream[(String,String)] = null
//创建一个Map,(key,value)-》( 对应的时Topic和分区 ,偏移量)
var fromOffset = Map[TopicAndPartition,Long]()
//获取每个topic是否被消费过
var childrens:ListBuffer[Int] =new ListBuffer[Int]()
var flag = false //有topic被消费过则为true
for (topicDir <- zkGTList){ //循环存放偏移量的
//通过zkClient.countChidren来获取每个topic对应的分区中的偏移量ZKGroupTopicDirs的对象
val child: Int = zkClient.countChildren(topicDir.consumerOffsetDir)
childrens +www.mhylpt.com= child
if(child>0){
flag = true
}
}
if(flag){//消费过
for(z <- 0 until topics.size){ //根据topicsList的的下表获取相应的child和ZKGroupTopicDirs
val child = childrens(z)
val gpDirs = zkGTList(z)
val topicn = topicsList(z)
for(i <- 0 until child)www.mcyllpt.com/{
//循环child, 根据使用zkClient.readData方法,u获取topic的每个分区的偏移量
val offset = zkClient.readData[String](gpDirs.consumerOffsetDir+"/"+i)
val tp = new TopicAndPartition(www.michenggw.com/ topicn,i)
fromOffset += tp -> offset.toLong
}
}
//返回的而结果是 kafka的key,默认是null, value是kafka中的值
val messageHandler =www.gcyl159.com/ (mmd:MessageAndMetadata[String,String])=www.gcyl152.com>{
(mmd.key(),mmd.message())
}
//创建kafkaDStream
kafkaDStream = KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder,(String,String)](
ssc,kafkaParams,fromOffset,messageHandler
)
}else{//以前没有读取过
kafkaDStream = KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder](
ssc,kafkaParams,topics
)
}
/*val children1 = zkClient.countChildren(zKGroupTopicDirs1.consumerOffsetDir)
val children2 = zkClient.countChildren(zKGroupTopicDirs2.consumerOffsetDir)
if(children1>0 || children2>0){
if(children1>0){
for (i <- 0 until children1){
val offset = zkClient.readData[String](zKGroupTopicDirs1.consumerOffsetDir+"/"+i)
val tp = new TopicAndPartition(topic1,i)
fromOffset += tp ->offset.toLong
}
}
if(children2>0){
for (i <- 0 until children1){
val offset = zkClient.readData[String](zKGroupTopicDirs2.consumerOffsetDir+"/"+i)
val tp = new TopicAndPartition(topic2,i)
fromOffset += tp ->offset.toLong
}
}
val messageHandler =(mmd:MessageAndMetadata[String,String])=>{
(mmd.key(),mmd.message())
}
kafkaDStream = KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder,(String,String)](ssc,
kafkaParams,fromOffset,messageHandler)
}else{
kafkaDStream = KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder](ssc,kafkaParams,topics)
}*/
var offsetRanges = Array[OffsetRange]www.hjpt521.com() //用来记录更新的每个topic的分区偏移量
kafkaDStream.foreachRDD(kafkaRDD=>{
//kafkaRDD是一个KafkaRDD,可以转换成HasOffsetRanges对象,从而获取offsetRanges
offsetRanges= kafkaRDD.asInstanceOf[HasOffsetRanges].offsetRanges
kafkaRDD.foreach(println)www.365soke.com //打印
for(o <- offsetRanges){
val topicNN: String = o.topic //获取topic
val offset: Long = o.untilOffset //获取偏移量
val partition: Int = o.partition //获取分区
val i = topicsList.indexOf(topicNN) //通过topicList查找topic的下标,找到与之对应的ZKGroupTopicDirs
val gpDir = zkGTList(i)
//通过ZkUtils更新偏移量
ZkUtils.updatePersistentPath(zkClient,gpDir.consumerOffsetDir+"/"+partition,offset.toString)
/*if(topicNN.equals(topic1)){
ZkUtils.updatePersistentPath(zkClient,zKGroupTopicDirs1.consumerOffsetDir+"/"+partition,offset.toString)
}else if(topicNN.equals(topic2)){
ZkUtils.updatePersistentPath(zkClient,zKGroupTopicDirs2.consumerOffsetDir+"/"+partition,offset.toString)
}*/
}
})
ssc.start()
ssc.awaitTermination(www.dfgjyl.cn)
可以通过zookeeper的客户端,在/consumers中查看偏移量,
我的3个topic中,其中wc和wc1只有1个分区,可以通过下图可看出wc1的0分区偏移量13
kafka直连方式消费多个topic的更多相关文章
- SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量
SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量 1. ScalikeJDBC 2.配置文件 3.导入依赖的jar包 4.源码测试 通过MySQL保存kafka的偏移量 ...
- kafka全部数据清空与某一topic数据清空
1. Kafka全部数据清空 kafka全部数据清空的步骤为: 停止每台机器上的kafka: 删除kafka存储目录(server.properties文件log.dirs配置,默认为“/tmp/ka ...
- spring整合kafka(配置文件方式 消费者)
Kafka官方文档有 https://docs.spring.io/spring-kafka/reference/htmlsingle/ 这里是配置文件实现的方式 先引入依赖 <depend ...
- Spark+Kafka的Direct方式将偏移量发送到Zookeeper实现(转)
原文链接:Spark+Kafka的Direct方式将偏移量发送到Zookeeper实现 Apache Spark 1.3.0引入了Direct API,利用Kafka的低层次API从Kafka集群中读 ...
- spring整合kafka项目生产和消费测试结果记录(一)
使用spring+springMVC+mybatis+kafka做了两个web项目,一个是生产者,一个是消费者. 通过JMeter测试工具模拟100个用户并发访问生产者项目,发送json数据给生产者的 ...
- Kafka学习笔记之Kafka自身操作日志的清理方法(非Topic数据)
0x00 概述 本文主要讲Kafka自身操作日志的清理方法(非Topic数据),Topic数据自己有对应的删除策略,请看这里. Kafka长时间运行过程中,在kafka/logs目录下产生了大量的ka ...
- Kafka 是如何管理消费位点的?
Kafka 是一个高度可扩展的分布式消息系统,在实时事件流和流式处理为中心的架构越来越风靡的今天,它扮演了这个架构中核心存储的角色.从某种角度说,Kafka 可以看成实时版的 Hadoop 系统.Ha ...
- Dubbo直连方式
目录 一.dubbo概述 1. 基本架构 2. dubbo 支持的协议 二.直连方法 三.创建服务提供者 1. 思路 1. 创建maven web 2. pom.xml 3. 创建实体 4. 创建服务 ...
- 【Java面试】Kafka 怎么避免重复消费
Hi,大家好,我是Mic 一个工作5年的粉丝找到我. 他说: "Mic老师,你要是能回答出这个问题,我就佩服你" 我当场就懵了,现在打赌都这么随意了吗? 我问他问题是什么,他说&q ...
随机推荐
- 利用贝塞尔曲线绘制(UIBezierPath)自定义iOS动态速度表,可以自定义刻度,刻度值,进度条样式
GitHub的Demo下载地址 使用UIBezierPath画图步骤: 创建一个UIBezierPath对象 调用-moveToPoint:设置初始线段的起点 添加线或者曲线去定义一个或者多个子路径 ...
- hihocoder1133 二分·二分查找之k小数
思路: 类似于快排的分治算法. 实现: #include <iostream> #include <cstdio> #include <algorithm> #in ...
- docker最新版本以及docker-compose安装脚本
docker最新版本以及docker-compose编排工具安装脚本 git clone https://github.com/luckman666/shell_scripts.git cd shel ...
- 洛谷 P1548 棋盘问题
题目描述 设有一个N*M方格的棋盘(l<=N<=100,1<=M<=100)(30%) 求出该棋盘中包含有多少个正方形.多少个长方形(不包括正方形). 例如:当 N=2, M= ...
- Django创建第一个应用
一.创建第一个应用,并在settings.py中添加. python manage.py startapp article 二.创建第一个模型 class Article(models.Model): ...
- 腾讯AI开放平台的接口调用指南
最近无意发现腾讯AI开放平台上提供了大量好玩的人工智能云服务,而且是完全免费的.只需要用QQ号登录即可.这么好的东西,作为一个程序员,当然要试试了! 从上图可以看出腾讯AI开放平台提供的人工智能服务主 ...
- JQuery 获得绝对,相对位置的坐标方法
获取页面某一元素的绝对X,Y坐标,可以用offset()方法:(body属性设置margin :0;padding:0;) var X = $('#DivID').offset().top; var ...
- (三)docker 的启动,重启,关闭命令
docker启动命令,docker重启命令,docker关闭命令 启动 systemctl start docker 守护进程重启 sudo systemctl daemon-reload 重 ...
- java 随机数 <%=System.currentTimeMillis() %>
java 随机数<c:set var="version" value="<%=System.currentTimeMillis() %>"/& ...
- CAD交互绘制圆(网页版)
CAD绘制图像的过程中,画圆的情况是非常常见的,用户可以在控件视区点取任意一点做为圆心,再动态点取半径绘制圆. 主要用到函数说明: _DMxDrawX::DrawCircle 绘制一个圆.详细说明如下 ...