一个消费者组可以消费多个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. [在读]javascript框架设计

    司徒正美的书,内容我觉得不错,国内的书很少会讲这些.当然也有很多人吐槽它只贴代码没有解释,文笔不够优美啥啥的,我想说,不要在意这些细节,反正是值得买的一本.

  2. CGI和Servlet的比较

    转载自:http://www.maxhis.info/java/cgi-vs-servlet/ 概括来说,CGI和Servlet可以完成相同的功能. CGI(Common Gateway Interf ...

  3. Visual Studio Code配置 HTML 开发环境

    Visual Studio Code配置 HTML 开发环境 https://v.qq.com/x/page/l0532svf47c.html?spm=a2h0k.11417342.searchres ...

  4. 搭建Sql Server AlwaysOn 视频教程

    本人搭建关于Sql Server 2012 AlwaysOn 的视频系列教程. 教程一: 观看及下载地址:https://pan.baidu.com/s/1QAvhgFTSyvpR5xQZbKHO3w ...

  5. 【前端】jQurey Plugin

    ; (function ($, window, document, undefined) { "use strict"; var defaults = { name: " ...

  6. [转]合理使用ArrayMap代替HashMap

    合理使用ArrayMap代替HashMap 2016年07月08日 15:34:44 阅读数:5938 转载请标注: 披萨大叔的博客 http://blog.csdn.net/qq_27258799/ ...

  7. guanbi selinux

    编辑/etc/sysconfig/selinux,把第一条选项改为 disabled

  8. 读取Chrome书签文件

    使用C#读取Chrome浏览器的本地书签文件,当前文件在C盘下用户文件夹\AppData\Local\Google\Chrome\User Data\Default\下的Bookmarks 打开这个文 ...

  9. Navicat工具备份还原mysql数据库详细图解

    Navicat是个很不错的MYSQL数据库管理工具,我们常用的还web形式的phpmyadmin和font这三种了,都是非常不错的mysql管理工具.因为Navicat工具兼容性比较好,操作也比较简单 ...

  10. 中间件及tomcat的内存溢出调优

    主要是这三个选项的调整需要根据主机的内存配置 以及业务量的使用情况调节 -Xmx4g -Xms4g -Xmn2g xmx 与xms一般设置为一样 xmn大致设置为xmx xms的三分之一   可以使用 ...