在大数据领域中,有很多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 简单样例的更多相关文章

  1. extern外部方法使用C#简单样例

    外部方法使用C#简单样例 1.添加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...

  2. spring事务详解(二)简单样例

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  3. velocity简单样例

    velocity简单样例整体实现须要三个步骤,详细例如以下: 1.创建一个Javaproject 2.导入须要的jar包 3.创建须要的文件 ============================= ...

  4. 自己定义隐式转换和显式转换c#简单样例

    自己定义隐式转换和显式转换c#简单样例 (出自朱朱家园http://blog.csdn.net/zhgl7688) 样例:对用户user中,usernamefirst name和last name进行 ...

  5. VC6 鼠标钩子 最简单样例

    Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它能够截获并处理送给其它应用程序的消息,来完毕普通应用程序 ...

  6. gtk+3.0的环境配置及基于gtk+3.0的python简单样例

    /*********************************************************************  * Author  : Samson  * Date   ...

  7. java 使用tess4j实现OCR的最简单样例

    网上很多教程没有介绍清楚tessdata的位置,以及怎么配置,并且对中文库的描述也存在问题,这里介绍一个最简单的样例. 1.使用maven,直接引入依赖,确保你的工程JDK是1.8以上 <dep ...

  8. 使用SALT-API进入集成开发的简单样例

    测试的时候,可以CURL -K,但真正作集成的时候,却是不可以的. 必须,不可以让TOKEN满天飞吧. 现在进入这个阶段了.写个样例先: import salt import salt.auth im ...

  9. VB.net数据库编程(03):一个SQLserver连接查询的简单样例

    这个样例,因为在ADO.net入门已经专门学了,再次进行复习 一下. 主要掌握连接字串的情况. 过程就是: 1.引用System.Data.SqlClient.而Access中引用 的是System. ...

随机推荐

  1. CentOS7 部署 ElasticSearch7.0.1 集群

    环境 主机名 IP 操作系统 ES 版本 test1 192.168.1.2 CentOS7.5 7.0.1 test2 192.168.1.3 CentOS7.5 7.0.1 test3 192.1 ...

  2. 通过php安装Imagick扩展给动态gif图片打水印

    通过php安装Imagick扩展给动态gif图片打水印 一直以来php处理图片都是以gd为主流,直到近些年Imagick的使用才渐渐变多. gd通常用来缩放图片,给图片打水印等基本功能,对于复杂效果如 ...

  3. 2019-2020-1 20199302《Linux内核原理与分析》第三周作业

    云班课学习内容 一.C语言中嵌入汇编代码 1.内嵌汇编语法 (1)C语言中嵌入汇编代码的写法: asm( 汇编语句模板: 输出部分: 输入部分: 破坏描述部分): 说明:输出部分和输入部分对应着C语言 ...

  4. Linux学习建议[转]

    端正学习态度学linux不会为了当黑客或者骇客,如果你为了当黑客或骇客而学习Linux,那么你离进监狱不远了,只是时间早晚而已.很多小白都知道“黑客攻击工具”很多来源与Linux平台上的,我也曾指导过 ...

  5. 100: cf 878C set+并查集+链表

    $des$Berland要举行 $n$ 次锦标赛,第一次只有一个人,之后每一次会新加入一个人.锦标赛中有 $k$ 种运动项目,每个人在这 $k$ 种项目上都有一个能力值,每次会选择任意两个还未被淘汰的 ...

  6. POJ 1927 Area in Triangle

    Area in Triangle Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1674   Accepted: 821 D ...

  7. ELK教程1:ElasticSearch集群的部署ELK

    在分布式系统中,应用数量众多,应用调用链复杂,常常使用ELK作为日志收集.分析和展示的组件.本篇文章将讲讲解如何部署ELK,然后讲解如何使用Filebeat采集Spring Boot的日志输出到Log ...

  8. rapidxml学习

    参考: 官网http://rapidxml.sourceforge.net/ https://blog.csdn.net/wqvbjhc/article/details/7662931 http:// ...

  9. 像母语者一样说美语 How to Improve Spoken American English - Sound like a Native Speaker

    视频讲解: 视频详情见:https://www.bilibili.com/video/av75075387/ 总结分析: 001 要点总结: 1. 本富兰克林方法: 要你写下一切听到的东西 2. 辅音 ...

  10. macbook ios recovery and mount hfs+ journal and revert

    sudo fsck.hfsplus -fryd /dev/sdc2 /sbin/fsck_hfs -yprd /dev/partitionName---can not fix b-tree node ...