Flink MysqlSink 简单样例
在大数据领域中,有很多nosql 的数据库,典型的 hbase,可以实现大数据量下的快速查询,但是关系型数据的地位还是没办法替代。比如上个项目中,计算完的结果数据,还是会输出到关系型数据库当中。Flink 中没有提供关系型数据的connector,看到有小伙伴在问,怎么实现,就写个简单的demo。
Flink sink,都有两种方式,对外输出数据:
继承RichSinkFunction
实现OutputFormat接口
这里继承RichSinkFunction 实现 往 mysql 输出数据的sink。
mysql 表结构如下:
mysql> desc user;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(32) | NO | UNI | NULL | |
| password | varchar(32) | NO | | NULL | |
| sex | int(11) | YES | | 0 | |
| phone | varchar(18) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
执行流程如下:
kafka source -> map -> mysqlSink
1、继承RichSinkFunction
主要代码如下:
env.addSource(source)
.map(li => {
val tmp = li.split(",")
new User(tmp(0), tmp(1), tmp(2)toInt, tmp(3))
})
.addSink(new MysqlSink)
MysqlSink:
import java.sql.{Connection, DriverManager, PreparedStatement, SQLException}
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.functions.sink.{RichSinkFunction, SinkFunction}
import org.slf4j.{Logger, LoggerFactory}
class MysqlSink extends RichSinkFunction[User] {
val logger: Logger = LoggerFactory.getLogger("MysqlSink")
var conn: Connection = _
var ps: PreparedStatement = _
val jdbcUrl = "jdbc:mysql://192.168.229.128:3306?useSSL=false&allowPublicKeyRetrieval=true"
val username = "root"
val password = "123456"
val driverName = "com.mysql.jdbc.Driver"
override def open(parameters: Configuration): Unit = {
Class.forName(driverName)
try {
Class.forName(driverName)
conn = DriverManager.getConnection(jdbcUrl, username, password)
// close auto commit
conn.setAutoCommit(false)
} catch {
case e@(_: ClassNotFoundException | _: SQLException) =>
logger.error("init mysql error")
e.printStackTrace()
System.exit(-1);
}
}
/**
* 吞吐量不够话,可以将数据暂存在状态中,批量提交的方式提高吞吐量(如果oom,可能就是数据量太大,资源没有及时释放导致的)
* @param user
* @param context
*/
override def invoke(user: User, context: SinkFunction.Context[_]): Unit = {
println("get user : " + user.toString)
ps = conn.prepareStatement("insert into async.user(username, password, sex, phone) values(?,?,?,?)")
ps.setString(1, user.username)
ps.setString(2, user.password)
ps.setInt(3, user.sex)
ps.setString(4, user.phone)
ps.execute()
conn.commit()
}
override def close(): Unit = {
if (conn != null){
conn.commit()
conn.close()
}
}
}
2、实现 OutputFormat 接口
主要代码如下:
env.addSource(source)
.map(li => {
val tmp = li.split(",")
new User(tmp(0), tmp(1), tmp(2)toInt, tmp(3))
})
// .addSink(new MysqlSink1)
.writeUsingOutputFormat(new MysqlSink1)
MysqlSink1
import java.sql.{Connection, DriverManager, PreparedStatement, SQLException}
import org.apache.flink.api.common.io.OutputFormat
import org.apache.flink.configuration.Configuration
import org.slf4j.{Logger, LoggerFactory}
class MysqlSink1 extends OutputFormat[User]{
val logger: Logger = LoggerFactory.getLogger("MysqlSink1")
var conn: Connection = _
var ps: PreparedStatement = _
val jdbcUrl = "jdbc:mysql://192.168.229.128:3306?useSSL=false&allowPublicKeyRetrieval=true"
val username = "root"
val password = "123456"
val driverName = "com.mysql.jdbc.Driver"
override def configure(parameters: Configuration): Unit = {
// not need
}
override def open(taskNumber: Int, numTasks: Int): Unit = {
Class.forName(driverName)
try {
Class.forName(driverName)
conn = DriverManager.getConnection(jdbcUrl, username, password)
// close auto commit
conn.setAutoCommit(false)
} catch {
case e@(_: ClassNotFoundException | _: SQLException) =>
logger.error("init mysql error")
e.printStackTrace()
System.exit(-1);
}
}
override def writeRecord(user: User): Unit = {
println("get user : " + user.toString)
ps = conn.prepareStatement("insert into async.user(username, password, sex, phone) values(?,?,?,?)")
ps.setString(1, user.username)
ps.setString(2, user.password)
ps.setInt(3, user.sex)
ps.setString(4, user.phone)
ps.execute()
conn.commit()
}
override def close(): Unit = {
if (conn != null){
conn.commit()
conn.close()
}
}
}
比较简单,就不贴测试结果了,如果吞吐量大,一定要改成批量提交的。
搞定
Flink MysqlSink 简单样例的更多相关文章
- extern外部方法使用C#简单样例
外部方法使用C#简单样例 1.添加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...
- spring事务详解(二)简单样例
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- velocity简单样例
velocity简单样例整体实现须要三个步骤,详细例如以下: 1.创建一个Javaproject 2.导入须要的jar包 3.创建须要的文件 ============================= ...
- 自己定义隐式转换和显式转换c#简单样例
自己定义隐式转换和显式转换c#简单样例 (出自朱朱家园http://blog.csdn.net/zhgl7688) 样例:对用户user中,usernamefirst name和last name进行 ...
- VC6 鼠标钩子 最简单样例
Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它能够截获并处理送给其它应用程序的消息,来完毕普通应用程序 ...
- gtk+3.0的环境配置及基于gtk+3.0的python简单样例
/********************************************************************* * Author : Samson * Date ...
- java 使用tess4j实现OCR的最简单样例
网上很多教程没有介绍清楚tessdata的位置,以及怎么配置,并且对中文库的描述也存在问题,这里介绍一个最简单的样例. 1.使用maven,直接引入依赖,确保你的工程JDK是1.8以上 <dep ...
- 使用SALT-API进入集成开发的简单样例
测试的时候,可以CURL -K,但真正作集成的时候,却是不可以的. 必须,不可以让TOKEN满天飞吧. 现在进入这个阶段了.写个样例先: import salt import salt.auth im ...
- VB.net数据库编程(03):一个SQLserver连接查询的简单样例
这个样例,因为在ADO.net入门已经专门学了,再次进行复习 一下. 主要掌握连接字串的情况. 过程就是: 1.引用System.Data.SqlClient.而Access中引用 的是System. ...
随机推荐
- Oracle建立DBLINK的详细步骤记录
测试条件:假设某公司总部在北京,新疆有其下属的一个分公司.在本次测试中,新疆的计算机为本地计算机,即本要的IP地址为:192.168.1.100 北京的总部有一个集中的数据库,其SID是SIDBJ,用 ...
- C#调用一下CMD
C#程序调用CMD执行命令 在windows环境下,命令行程序为cmd.exe,是一个32位的命令行程序,微软Windows系统基于Windows上的命令解释程序,类似于微软的DOS操作系统.输入 ...
- mysql 端口号被占用
开始-运行-cmd, 输入 netstat -ano, 看第一列,后面的就是端口,找到3306 ,记住对应的PID!! 然后打开任务管理器 查看 -> 选择列 -> 勾上 PID(进 ...
- nachos3.4 threads管理 (c++)
Main.cc //引导代码初始化操作系统内核.允许直接调用内部操作系统功能,简化调试和测试.在实践中,bootstrap代码只会初始化数据结构, //并启动一个用户程序来打印登录提示.//许多内容只 ...
- Tensorflow细节-P199-数据集
数据集的基本使用方法 import tempfile import tensorflow as tf input_data = [1, 2, 3, 5, 8] # 这不是列表吗,为什么书里叫数组 da ...
- YAML_14 tags给指定的任务定义一个调用标识,以后不用重复整个过程,只需要执行tags标签的部分
ansible]# vim adhttp.yml --- - hosts: cache remote_user: root tasks: - copy: src: /r ...
- 第02组 Alpha冲刺(2/6)
队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 任务分配.进度监督 提交记录(全组共用) 接下来的计划 沟通前后端成员,监督.提醒他们尽快完成各自的进度 还剩下哪些任务 ...
- return关键字
注意:如果一个函数的返回值类型是具体的数据类型,那么该函数就必须要保证在任意情况下都保证有返回值(除了返回值类型是void) return 关键字的作用: 1 返回数据给函数的调用者. ...
- STP生成树算法
生成树算法第一:决定谁是“根网桥”对比各个网桥ID,先对比ID中的优先级,优先级相同的时候对比网桥MAC地址,对比依据是谁的值最小,谁是“根网桥” 第二:决定哪些是“根端口”窍门——每个非根网桥上都有 ...
- V语言 基本使用
新手必看-如何安装配置vlang运行环境(linux,macOS篇) 前置条件 发稿截止前只有Linux 或者 macOS系统能编译通过. 你需要安装clang或gcc 如果是macOS上需运行xco ...