SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量
SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量
通过MySQL保存kafka的偏移量,完成直连方式读取数据
使用scalikeJDBC,访问数据库。
1. ScalikeJDBC
ScalikeJDBC 是一款Scala 开发者使用的简洁 DB 访问类库,它是基于 SQL 的,使用者只需要关注 SQL 逻辑的编写,所有的数据库操作都交给 ScalikeJDBC。这个类库内置包含了JDBC API,并且给用户提供了简单易用并且非常灵活的 API。并且,QueryDSL(通用查询查询框架)使你的代码类型安全的并且可重复使用。我们可以在生产环境大胆地使用这款 DB 访问类库。
2.配置文件
//配置数据库信息
//使用IDEA,在resources文件夹下新建文件File文件名为application.conf
db.default.driver="com.mysql.jdbc.Driver"
db.default.url="jdbc:mysql://hadoop01:3306/kafkaOffset?characterEncodeing=utf-8"
db.default.user="root"
db.default.password="root"

3.导入依赖的jar包
<!--Maven依赖-->
<!--通过mysql保存偏移量-->
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.scalikejdbc</groupId>
<artifactId>scalikejdbc_2.11</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.scalikejdbc</groupId>
<artifactId>scalikejdbc-core_2.11</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.scalikejdbc</groupId>
<artifactId>scalikejdbc-config_2.11</artifactId>
<version>2.5.0</version>
</dependency>
4.源码测试
import kafka.common.TopicAndPartition
import kafka.message.MessageAndMetadata
import kafka.serializer.StringDecoder
import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.dstream.InputDStream
import org.apache.spark.streaming.kafka.KafkaCluster.Err
import org.apache.spark.streaming.kafka.{HasOffsetRanges, KafkaCluster, KafkaUtils, OffsetRange}
import org.apache.spark.streaming.{Duration, StreamingContext}
import scalikejdbc.{DB, SQL}
import scalikejdbc.config.DBs
/*
将偏移量保存到MySQL中
*/
object SparkStreamingOffsetMySql {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("medd").setMaster("local[2]")
val ssc = new StreamingContext(conf,Duration(5000))
//配置一系列基本配置
val groupid = "GPMMCC"
val topic = "mysqlDemo"
val brokerList = "hadoop01:9092,hadoop02:9092,hadoop03:9092"
// val zkQuorum = "hadoop01:2181,hadoop02:2181,hadoop03:2181"
val topics = Set(topic)
//设置kafka的参数
val kafkaParams = Map(
"metadata.broker.list"->brokerList,
"group.id"->groupid,
"auto.offset.reset"->kafka.api.OffsetRequest.SmallestTimeString
)
//加载配置 application.conf
DBs.setup()
//不需要查询zk中的offset啦,直接查询MySQL中的offset
val fromdbOffset:Map[TopicAndPartition,Long]=
DB.readOnly{
implicit session=>{
//查询每个分组下面的所有消息
SQL(s"select * from offset where groupId = '${groupid}'" +
//将MySQL中的数据赋值给元组
s"").map(m=>(TopicAndPartition(m.string("topic"),m.string("partitions").toInt),m.string("untilOffset").toLong))
.toList().apply()
}.toMap //最后toMap ,应为前面的返回值已经给定
}
//创建一个DStream,用来获取数据
var kafkaDStream : InputDStream[(String,String)] = null
//从MySql中获取数据进行判断
if(fromdbOffset.isEmpty){
kafkaDStream = KafkaUtils.createDirectStream[String,String,StringDecoder,
StringDecoder](ssc,kafkaParams,topics)
}else{
//1\ 不能重复消费
//2\ 保证偏移量
var checkOffset = Map[TopicAndPartition,Long]()
//加载kafka的配置
val kafkaCluster = new KafkaCluster(kafkaParams)
//首先获得kafka中的所有的topic和partition Offset
val earliesOffset: Either[Err, Map[TopicAndPartition, KafkaCluster.LeaderOffset]
] = kafkaCluster.getEarliestLeaderOffsets(fromdbOffset.keySet)
//然后开始比较大小,用mysql中的offset和kafka中的offset进行比较
if(earliesOffset.isRight){
//去到需要的 大Map
//物取值
val tap: Map[TopicAndPartition, KafkaCluster.LeaderOffset] =
earliesOffset.right.get
//比较,直接进行比较大小
val checkOffset = fromdbOffset.map(f => {
//取kafka中的offset
//进行比较,不需要重复消费,取最大的
val KafkatopicOffset = tap.get(f._1).get.offset
if (f._2 > KafkatopicOffset) {
f
} else {
(f._1, KafkatopicOffset)
}
})
checkOffset
}
val messageHandler=(mmd:MessageAndMetadata[String,String])=>{
(mmd.key(),mmd.message())
}
//不是第一次启动的话 ,按照之前的偏移量取数据的偏移量
kafkaDStream = KafkaUtils.createDirectStream[String,String,StringDecoder
,StringDecoder,(String,String)](ssc,kafkaParams,checkOffset
,messageHandler)
}
var offsetRanges = Array[OffsetRange]()
kafkaDStream.foreachRDD(kafkaRDD=>{
offsetRanges = kafkaRDD.asInstanceOf[HasOffsetRanges].offsetRanges
val map: RDD[String] = kafkaRDD.map(_._2)
map.foreach(println)
//更新偏移量
DB.localTx(implicit session =>{
//去到所有的topic partition offset
for (o<- offsetRanges){
/*SQL("update offset set groupId=? topic=?,partition=?," +
"untilsOffset=?").bind(groupid,o.topic,o.partition,o.untilOffset).update().apply()*/
SQL("replace into offset(groupId,topic,partitions,untilOffset) values(?,?,?,?)").bind(
groupid,o.topic,o.partition.toString,o.untilOffset.toString
).update().apply()
}
})
})
ssc.start()
ssc.awaitTermination()
}
}
SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量的更多相关文章
- Java基础知识强化之网络编程笔记16:Android网络通信之 使用Http的Get方式读取网络数据(基于HTTP通信技术)
使用Http的Get方式读取网络数据,使用Get方式与网络通信是最常见的Http通信,建立链接之后就可以通过输入流读取网络数据. 详见:Android(java)学习笔记209:采用get请求提交数据 ...
- flume 读取kafka 数据
本文介绍flume读取kafka数据的方法 代码: /************************************************************************* ...
- spark读取kafka数据 createStream和createDirectStream的区别
1.KafkaUtils.createDstream 构造函数为KafkaUtils.createDstream(ssc, [zk], [consumer group id], [per-topic, ...
- 使用 Http 的 Get 方式读取网络数据
作为移动平台的应用,一定避免不了与网络交换数据,不论是读取网页数据,还是调用API接口,都必须掌握Http通信技术 代码如下: package zw1; import java.io.Buffered ...
- flink 读取kafka 数据,partition分配
每个并发有个编号,只会读取kafka partition % 总并发数 == 编号 的分区 如: 6 分区, 4个并发 分区: p0 p1 p2 p3 p4 p5 并发: 0 1 2 3 ...
- jxl读写excel, poi读写excel,word, 读取Excel数据到MySQL
这篇blog是介绍: 1. java中的poi技术读取Excel数据,然后保存到MySQL数据中. 2. jxl读写excel 你也可以在 : java的poi技术读取和导入Excel了解到写入Exc ...
- 关于mapreducer 读取hbase数据 存入mysql的实现过程
mapreducer编程模型是一种八股文的代码逻辑,就以用户行为分析求流存率的作为例子 1.map端来说:必须继承hadoop规定好的mapper类:在读取hbase数据时,已经有现成的接口 Tabl ...
- java的poi技术读取Excel数据到MySQL
这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...
- php+phpspreadsheet读取Excel数据存入mysql
先生成Excel模板,然后导入Excel数据到mysql,每条数据对应图片上传到阿里云 <?php /** * Created by PhpStorm. * User: Administrato ...
随机推荐
- Thymeleaf语法总结 | 笔记分享
Thymeleaf语法总结 一.Thymeleaf介绍 Thymeleaf是Spring boot推荐使用的模版引擎,直接以html显示,前后端可以很好的分离. 二.Thymeleaf语法(Thy ...
- 进程描述符(PCB)
进程描述符(PCB) 概述 CPU作为计算机的核心部件,我们当然希望它能一直工作,充分提高它的使用效率.对于上层软件来说,我们不可能直接去操控CPU(我们没这能力也没必要),因为操作系统是夹在计算机硬 ...
- vue vue-cli postcss-sprites 配置
vue-cli2.x创建完项目 安装postcss-sprites yarn add postcss-sprites -D 根目录配置postcss.config.js配置中,需要注意,1:当有用px ...
- 四、hive安装
一.安装方式(内嵌模式,本地模式远程模式) 安装环境以及前提说明: Hive是依赖于hadoop系统的,因此在运行Hive之前需要保证已经搭建好hadoop集群环境. 本例中使用的hadoop版本为2 ...
- C#:使用连接字符串连接数据库
前言:在上学期选择专业时候,选择的是互联网(还有物联网),这学期相关课程便是使用c#完成一个管理系统:最近的作业是完成一个对数据库操作类,操作数据库?虽然是很简单的一个作业,但也是懵逼了很久,在网上找 ...
- 第12章 DOM操作
目录 *1. 向DOM中注入HTML 1.1 将HTNL字符串转换成DOM 预处理HTML源字符串 包装HTML 1.2 将DOM元素插入到文档中 2. DOM的特性和属性 通过DOM方法和属性访问特 ...
- linux系统修改Swap分区【转】
在装完Linux系统之后自己去修改Swap分区的大小(两种方法) 在安装完Linux系统后,swap分区太小怎么办,怎么可以扩大Swap分区呢?有两个办法,一个是从新建立swap分区,一个是增加swa ...
- docker迁入迁出mysql
docker迁出mysql数据库 测试环境: docker服务器 mysql服务器 IP 192.168.163.19 192.168.163.16 操作系统 CentOS7.8 CentOS7.8 ...
- 惠普电脑(HP PHILIPS系列)安装ubuntu后无法连接WIFI解决方案(手动安装8821CE驱动)
一步一步来, 先说环境: 我的电脑是HP PHILIPS系列,ubuntu版本是16.04 背景: win10安装ubuntu后发现无法连接wifi(但win10系统可以连接WIFI),在ubuntu ...
- 小白的经典CNN复现(二):LeNet-5
小白的经典CNN复现(二):LeNet-5 各位看官大人久等啦!我胡汉三又回来辣(不是 最近因为到期末考试周,再加上老板临时给安排了个任务,其实LeNet-5的复现工作早都搞定了,结果没时间写这个博客 ...