将数据保存到mysql,需要用到jdbc。为了提高保存速度,我写了一个连接池

1.保存到mysql的代码

package test05

import org.apache.log4j.{Level, Logger}
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.types._
import org.apache.spark.sql._
import org.apache.spark.streaming.dstream.DStream
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.kafka.KafkaUtils object SaveDataToMysql {
def main(args: Array[String]): Unit = { // 屏蔽不必要的日志 ,在终端上显示需要的日志
Logger.getLogger("org.apache.spark").setLevel(Level.OFF)
Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
Logger.getLogger("org.apache.kafka.clients.consumer").setLevel(Level.OFF) //初始化sparkStreaming
val conf = new SparkConf().setAppName("SaveDataToMysql").setMaster("local[*]")
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc, Seconds(10))
    //连接s3需要的key和密码
ssc.sparkContext.hadoopConfiguration.set("fs.s3a.access.key","aws的key")
ssc.sparkContext.hadoopConfiguration.set("fs.s3a.secret.key","aws的密码")
ssc.sparkContext.hadoopConfiguration.set("fs.s3a.endpoint", "s3.cn-north-1.amazonaws.com.cn") //设置连接Kafka的配置信息
val zkQuorum = "192.168.1.112:2181" //zookeeper集群的IP:port,IP:port,IP:port
val group = "testgroup" //在consumer.properties配置group.id
val topics = "huiliyang" //选择要连接的producer,它是以topic来区分每个producer的。例如:我这里的创建的topic是huiliyang
val numThreads = 2 //线程
val topicpMap = topics.split("\n").map((_,numThreads.toInt)).toMap //这个是有可能有好几个topic同时提供数据,那么我们要把它用空格分割开,然后映射成(topic,2),再转换成map集合
    ssc.checkpoint("checkpoint"
    val lines: DStream[String] = KafkaUtils.createStream(ssc,zkQuorum,group,topicpMap).map(_._2)    //创建流

    lines.print()

    //保存到mysql
lines.map(x=>x.split(",")).foreachRDD(line =>{
line.foreachPartition(rdd =>{
val conn = ConnectPoolUtil.getConnection //
ConnectPoolUtil是我创建的一个数据库连接池,getConnection是它的一个方法 conn.setAutoCommit(false); //设为手动提交
        val  stmt = conn.createStatement()
rdd.foreach(word=>{
stmt.addBatch("insert into test_log2(time, ip, user_id, user_type, source, scene) values('" + word(0)+"','"+word(1)+"','"+word(2)+"','"+word(3)+"','"+word(4)+"','"+word(5) + "')")
})
stmt.executeBatch()
conn.commit()
conn.close()
})
})
ssc.start()
ssc.awaitTermination()
  }

}

数据库连接池代码:
package test05

import java.sql.{Connection, PreparedStatement, ResultSet}
import org.apache.commons.dbcp.BasicDataSource object ConnectPoolUtil { private var bs:BasicDataSource = null /**
* 创建数据源
* @return
*/
def getDataSource():BasicDataSource={
if(bs==null){
bs = new BasicDataSource()
bs.setDriverClassName("com.mysql.jdbc.Driver")
bs.setUrl("jdbc:mysql://localhost:3306/school")
bs.setUsername("root")
bs.setPassword("123456")
bs.setMaxActive(200) //设置最大并发数
bs.setInitialSize(30) //数据库初始化时,创建的连接个数
bs.setMinIdle(50) //最小空闲连接数
bs.setMaxIdle(200) //数据库最大连接数
bs.setMaxWait(1000)
bs.setMinEvictableIdleTimeMillis(60*1000) //空闲连接60秒中后释放
bs.setTimeBetweenEvictionRunsMillis(5*60*1000) //5分钟检测一次是否有死掉的线程
bs.setTestOnBorrow(true)
}
bs
} /**
* 释放数据源
*/
def shutDownDataSource(){
if(bs!=null){
bs.close()
}
} /**
* 获取数据库连接
* @return
*/
def getConnection():Connection={
var con:Connection = null
try {
if(bs!=null){
con = bs.getConnection()
}else{
con = getDataSource().getConnection()
}
} catch{
case e:Exception => println(e.getMessage)
}
con
} /**
* 关闭连接
*/
def closeCon(rs:ResultSet ,ps:PreparedStatement,con:Connection){
if(rs!=null){
try {
rs.close()
} catch{
case e:Exception => println(e.getMessage)
}
}
if(ps!=null){
try {
ps.close()
} catch{
case e:Exception => println(e.getMessage)
}
}
if(con!=null){
try {
con.close()
} catch{
case e:Exception => println(e.getMessage)
}
}
}
} pom文件
<properties>
<scala.version>2.11.8</scala.version>
<spark.version>2.2.0</spark.version>
<hadoop.version>2.7.2</hadoop.version>
<spark.pom.scope>compile</spark.pom.scope>
</properties> <dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${spark.version}</version>
<!--<scope>${spark.pom.scope}</scope>-->
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming-kafka-0-8_2.11</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>${spark.version}</version>
<!--<scope>${spark.pom.scope}</scope>-->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
 

 

消费kafka的消息,并将其SparkStreaming结果保存到mysql的更多相关文章

  1. 将sparkStreaming结果保存到Redshift数据库

    1.保存到redshift数据库的代码 package test05 import org.apache.log4j.{Level, Logger}import org.apache.spark.rd ...

  2. 17-Flink消费Kafka写入Mysql

    戳更多文章: 1-Flink入门 2-本地环境搭建&构建第一个Flink应用 3-DataSet API 4-DataSteam API 5-集群部署 6-分布式缓存 7-重启策略 8-Fli ...

  3. storm消费kafka实现实时计算

    大致架构 * 每个应用实例部署一个日志agent * agent实时将日志发送到kafka * storm实时计算日志 * storm计算结果保存到hbase storm消费kafka 创建实时计算项 ...

  4. Kafka创建&查看topic,生产&消费指定topic消息

    启动zookeeper和Kafka之后,进入kafka目录(安装/启动kafka参考前面一章:https://www.cnblogs.com/cici20166/p/9425613.html) 1.创 ...

  5. kafka创建topic,生产和消费指定topic消息

    启动zookeeper和Kafka之后,进入kafka目录(安装/启动kafka参考前面一章:https://www.cnblogs.com/cici20166/p/9425613.html) 1.创 ...

  6. SparkStreaming消费Kafka,手动维护Offset到Mysql

    目录 说明 整体逻辑 offset建表语句 代码实现 说明 当前处理只实现手动维护offset到mysql,只能保证数据不丢失,可能会重复 要想实现精准一次性,还需要将数据提交和offset提交维护在 ...

  7. kafka 保证消息被消费和消息只消费一次

    1. 保证消息被消费 即使消息发送到了消息队列,消息也不会万无一失,还是会面临丢失的风险. 我们以 Kafka 为例,消息在Kafka 中是存储在本地磁盘上的, 为了减少消息存储对磁盘的随机 I/O, ...

  8. kafka消费者客户端启动之后消费不到消息的原因分析

    如果你发现你的一个消费者客户端A已经启动了,但是就是不消费消息,此时你应该检查一下该消费者所在的组中(ConsumerGroup)是否还有其他的消费者,topic的分区可能被组中其他的消费者线程抢走( ...

  9. SparkStreaming消费kafka中数据的方式

    有两种:Direct直连方式.Receiver方式 1.Receiver方式: 使用kafka高层次的consumer API来实现,receiver从kafka中获取的数据都保存在spark exc ...

随机推荐

  1. Thinkphp5.0 自定义命令command的使用

    在app下的command文件中,定义命令所在的模块以及命名. 然后保存,打开cmd,php think 定义的那个command的名字,完整的命令行为:php think clearInvalidO ...

  2. webpack 学习三 模式

    开发环境(development)和生产环境(production)的构建目标差异很大.在开发环境中,我们需要具有强大的.具有实时重新加载(live reloading)或热模块替换(hot modu ...

  3. 一张图告诉你js为什么要加分号

    当js代码被压缩或者通过其他方式改变你的编码结构时,分号能够给编译器和解析器提供精准的语句拆分. 如图中m 和 c 的例子就能解释为什么这样做.

  4. MariaDB 建立连接

    与MariaDB建立连接的一种方法是在命令提示符下使用mysql二进制文件. MySQL脚本 查看下面给出的示例. [root@host]# mysql -u root -p Enter passwo ...

  5. c++ fork进程与同步锁

    首先定义在多进程环境中的锁,采用读写锁,即可以同时读,但只能单独写. 头文件processLock.h #ifndef PROCESSLOCK_H #define PROCESSLOCK_H #inc ...

  6. Codeforces #55D (数位dp+离散化)

    Description Volodya is an odd boy and his taste is strange as well. It seems to him that a positive ...

  7. ubuntu Linux下chromium无法使用flash解决方法

    Chromium作为谷歌的开源浏览器将不再支持Netscape浏览器插件API,Adobe公司的Flash将无法正常工作了.然而用户可以使用Pepper Flash Player,这是谷歌浏览器上一款 ...

  8. CCPC-Wannafly 秦皇岛 day5训练总结

    训练总结 今天开局先上去看到了J,粗略(>_<)的看了下题意,然后就觉得应该是个dp 就开始写,思路是个三维dp,开的10000*10*10  觉得就不会爆,时间上也没问题,后面陆续wa了 ...

  9. nginx 配置多服务器代理

    找到 nginx > conf目录中nginx.conf #user nobody; worker_processes 1; #error_log logs/error.log; #error_ ...

  10. sed 对文件进行操作

    首先我们想不进入一个文件 对文件进行操作 那么久需要用到sed了 在某个变量之前添加内容: sed -i 's/原内容/要添加内容/g' 文件名 sed -i 's/原内容/要添加内容&/' ...