一个消费者组可以消费多个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的更多相关文章

  1. SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量

    SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量 1. ScalikeJDBC 2.配置文件 3.导入依赖的jar包 4.源码测试 通过MySQL保存kafka的偏移量 ...

  2. kafka全部数据清空与某一topic数据清空

    1. Kafka全部数据清空 kafka全部数据清空的步骤为: 停止每台机器上的kafka: 删除kafka存储目录(server.properties文件log.dirs配置,默认为“/tmp/ka ...

  3. spring整合kafka(配置文件方式 消费者)

    Kafka官方文档有   https://docs.spring.io/spring-kafka/reference/htmlsingle/ 这里是配置文件实现的方式 先引入依赖 <depend ...

  4. Spark+Kafka的Direct方式将偏移量发送到Zookeeper实现(转)

    原文链接:Spark+Kafka的Direct方式将偏移量发送到Zookeeper实现 Apache Spark 1.3.0引入了Direct API,利用Kafka的低层次API从Kafka集群中读 ...

  5. spring整合kafka项目生产和消费测试结果记录(一)

    使用spring+springMVC+mybatis+kafka做了两个web项目,一个是生产者,一个是消费者. 通过JMeter测试工具模拟100个用户并发访问生产者项目,发送json数据给生产者的 ...

  6. Kafka学习笔记之Kafka自身操作日志的清理方法(非Topic数据)

    0x00 概述 本文主要讲Kafka自身操作日志的清理方法(非Topic数据),Topic数据自己有对应的删除策略,请看这里. Kafka长时间运行过程中,在kafka/logs目录下产生了大量的ka ...

  7. Kafka 是如何管理消费位点的?

    Kafka 是一个高度可扩展的分布式消息系统,在实时事件流和流式处理为中心的架构越来越风靡的今天,它扮演了这个架构中核心存储的角色.从某种角度说,Kafka 可以看成实时版的 Hadoop 系统.Ha ...

  8. Dubbo直连方式

    目录 一.dubbo概述 1. 基本架构 2. dubbo 支持的协议 二.直连方法 三.创建服务提供者 1. 思路 1. 创建maven web 2. pom.xml 3. 创建实体 4. 创建服务 ...

  9. 【Java面试】Kafka 怎么避免重复消费

    Hi,大家好,我是Mic 一个工作5年的粉丝找到我. 他说: "Mic老师,你要是能回答出这个问题,我就佩服你" 我当场就懵了,现在打赌都这么随意了吗? 我问他问题是什么,他说&q ...

随机推荐

  1. Codeforces Round #243 (Div. 1)

    ---恢复内容开始--- A 枚举l,r #include <iostream> #include<cstdio> #include<cstring> #inclu ...

  2. Ionic之ui-sref引入图片,图片部分挡住解决方案

    ionic图片设置大小跟图片像素相同,但是使用ui-sref="parkInfo"上半部分图片会挡住,增加height的高度,就可以显示原本图片 页面: <ion-conte ...

  3. 洛谷P2774 方格取数问题(最小割)

    题意 $n \times m$的矩阵,不能取相邻的元素,问最大能取多少 Sol 首先补集转化一下:最大权值 = sum - 使图不连通的最小权值 进行黑白染色 从S向黑点连权值为点权的边 从白点向T连 ...

  4. 【学习笔记】后端中的MVC和前端MVVM的关系

  5. ArcGIS二次开发之读取遥感图像像素值的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 首先是读取遥感图像的R.G.B波段数据的做法.读取R.G.B波段数据的像素值主要通过IRaster接口的Read方法在 ...

  6. iOS 播放本地,网络视频

    /** *  创建媒体播放控制器MPMoviePlayerControlle 可以控制尺寸 * *  @return 媒体播放控制器 */ -(MPMoviePlayerController *)mo ...

  7. 计算1至n的k次方的和

    package com.ywx.count; import java.util.Scanner; /** * @author Vashon * date:20150410 * 题目:计算1至n的k次方 ...

  8. 【HEVC简介】CTU、CU、PU、TU结构

     参考文献:见<High Efficiency Video Coding (HEVC)>Block Structures and Parallelism Features in HEVC章 ...

  9. Smart Contracts

    A smart contract is a computer code running on top of a blockchain containing a set of rules under w ...

  10. 数据库_11_1~10总结回顾+奇怪的NULL

    校对集问题: 比较规则:_bin,_cs,_ci利用排序(order by) 另外两种登录方式: 奇怪的NULL: NULL的特殊性: