1. 写在前面

Flink被誉为第四代大数据计算引擎组件,即可以用作基于离线分布式计算,也可以应用于实时计算。Flink的核心是转化为流进行计算。Flink三个核心:Source,Transformation,Sink。其中Source即为Flink计算的数据源,Transformation即为进行分布式流式计算的算子,也是计算的核心,Sink即为计算后的数据输出端。Flink Source原生支持包括Kafka,ES,RabbitMQ等一些通用的消息队列组件或基于文本的高性能非关系型数据库。而Flink Sink写原生也只支持类似Redis,Kafka,ES,RabbitMQ等一些通用的消息队列组件或基于文本的高性能非关系型数据库。而对于写入关系型数据库或Flink不支持的组件中,需要借助RichSourceFunction去实现,但这部分性能是比原生的差些,虽然Flink不建议这么做,但在大数据处理过程中,由于业务或技术架构的复杂性,有些特定的场景还是需要这样做,本篇博客就是介绍如何通过Flink RichSourceFunction来写关系型数据库,这里以写mysql为例。

2. 引入依赖的jar包

flink基础包

flink-jdbc包

mysql-jdbc包

3. 继承RichSourceFunction包将jdbc封装读mysql

package com.run;

import java.sql.DriverManager;
import java.sql.ResultSet; import org.apache.flink.api.java.tuple.Tuple10;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.source.RichSourceFunction; import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement; public class Flink2JdbcReader extends
RichSourceFunction<Tuple10<String, String, String, String, String, String, String, String, String, String>> {
private static final long serialVersionUID = 3334654984018091675L; private Connection connect = null;
private PreparedStatement ps = null; /*
* (non-Javadoc)
*
* @see org.apache.flink.api.common.functions.AbstractRichFunction#open(org.
* apache.flink.configuration.Configuration) to use open database connect
*/
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
Class.forName("com.mysql.jdbc.Driver");
connect = (Connection) DriverManager.getConnection("jdbc:mysql://192.168.21.11:3306", "root", "flink");
ps = (PreparedStatement) connect
.prepareStatement("select col1,col2,col3,col4,col5,col6,col7,col8,col9,col10 from flink.test_tb");
} /*
* (non-Javadoc)
*
* @see
* org.apache.flink.streaming.api.functions.source.SourceFunction#run(org.
* apache.flink.streaming.api.functions.source.SourceFunction.SourceContext)
* to use excuted sql and return result
*/
@Override
public void run(
SourceContext<Tuple10<String, String, String, String, String, String, String, String, String, String>> collect)
throws Exception {
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
Tuple10<String, String, String, String, String, String, String, String, String, String> tuple = new Tuple10<String, String, String, String, String, String, String, String, String, String>();
tuple.setFields(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3),
resultSet.getString(4), resultSet.getString(5), resultSet.getString(6), resultSet.getString(7),
resultSet.getString(8), resultSet.getString(9), resultSet.getString(10));
collect.collect(tuple);
} } /*
* (non-Javadoc)
*
* @see
* org.apache.flink.streaming.api.functions.source.SourceFunction#cancel()
* colse database connect
*/
@Override
public void cancel() {
try {
super.close();
if (connect != null) {
connect.close();
}
if (ps != null) {
ps.close();
}
} catch (Exception e) {
e.printStackTrace();
} } }

4. 继承RichSourceFunction包将jdbc封装写mysql

package com.run;

import java.sql.DriverManager;

import org.apache.flink.api.java.tuple.Tuple10;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction; import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement; public class Flink2JdbcWriter extends
RichSinkFunction<Tuple10<String, String, String, String, String, String, String, String, String, String>> {
private static final long serialVersionUID = -8930276689109741501L; private Connection connect = null;
private PreparedStatement ps = null; /*
* (non-Javadoc)
*
* @see org.apache.flink.api.common.functions.AbstractRichFunction#open(org.
* apache.flink.configuration.Configuration) get database connect
*/
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
Class.forName("com.mysql.jdbc.Driver");
connect = (Connection) DriverManager.getConnection("jdbc:mysql://192.168.21.11:3306", "root", "flink");
ps = (PreparedStatement) connect.prepareStatement("insert into flink.test_tb1 values (?,?,?,?,?,?,?,?,?,?)");
} /*
* (non-Javadoc)
*
* @see
* org.apache.flink.streaming.api.functions.sink.SinkFunction#invoke(java.
* lang.Object,
* org.apache.flink.streaming.api.functions.sink.SinkFunction.Context) read
* data from flink DataSet to database
*/
@Override
public void invoke(Tuple10<String, String, String, String, String, String, String, String, String, String> value,
Context context) throws Exception {
ps.setString(1, value.f0);
ps.setString(2, value.f1);
ps.setString(3, value.f2);
ps.setString(4, value.f3);
ps.setString(5, value.f4);
ps.setString(6, value.f5);
ps.setString(7, value.f6);
ps.setString(8, value.f7);
ps.setString(9, value.f8);
ps.setString(10, value.f9);
ps.executeUpdate();
} /*
* (non-Javadoc)
*
* @see org.apache.flink.api.common.functions.AbstractRichFunction#close()
* close database connect
*/
@Override
public void close() throws Exception {
try {
super.close();
if (connect != null) {
connect.close();
}
if (ps != null) {
ps.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

4. 代码解释

对于Flink2JdbcReader的读

里面有三个方法open,run,cancel,其中open方法是建立与关系型数据库的链接,这里其实就是普通的jdbc链接及mysql的地址,端口,库等信息。run方法是读取mysql数据转化为Flink独有的Tuple集合类型,可以根据代码看出其中的规律和Tuple8,Tuple9,Tuple10代表什么含义。cancel就很简单了关闭数据库连接

对于Flink2JdbcWriter的写

里面有三个方法open,invoke,close,其中open方法是建立与关系型数据库的链接,这里其实就是普通的jdbc链接及mysql的地址,端口,库等信息。invoke方法是将flink的数据类型插入到mysql,这里的写法与在web程序中写jdbc插入数据不太一样,因为flink独有的Tuple,可以根据代码看出其中的规律和Tuple8,Tuple9,Tuple10代表什么含义。close关闭数据库连接

5. 测试:读mysql数据并继续写入mysql

package com.run;

import java.util.Date;

import org.apache.flink.api.java.tuple.Tuple10;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; public class FlinkReadDbWriterDb {
public static void main(String[] args) throws Exception {。
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<Tuple10<String, String, String, String, String, String, String, String, String, String>> dataStream = env
.addSource(new Flink2JdbcReader()); // tranfomat dataStream.addSink(new Flink2JdbcWriter());
env.execute("Flink cost DB data to write Database"); }
}

6. 总结

从测试代码中可以很清晰的看出Flink的逻辑:Source->Transformation->Sink,可以在addSource到addSink之间加入我们的业务逻辑算子。同时这里必须注意env.execute("Flink cost DB data to write Database");这个必须有而且必须要放到结尾,否则整个代码是不会执行的,至于为什么在后续的博客会讲

Flink RichSourceFunction应用,读关系型数据(mysql)数据写入关系型数据库(mysql)的更多相关文章

  1. MYSQL添加新用户 MYSQL为用户创建数据库 MYSQL为新用户分配权限

    1.新建用户 //登录MYSQL @>mysql -u root -p @>密码 //创建用户 mysql> insert into mysql.user(Host,User,Pas ...

  2. ODP方式,大批量数据写入ORACLE数据库

    项目中在同步数据的时候,需要把获得的数据DataTable,写入oracle数据库 因为System.Data.OracleClient写入方式写入大批量数据特别慢,改用Oracle.DataAcce ...

  3. MySQL常用命令(数据库,表相关的命令)

    数据库相关命令 显示数据库列表 mysql> SHOW  DATABASES; 创建数据库 mysql> CREATE  DATABASE  库名; 如下,创建一个名为crashcours ...

  4. MySQL(一) -- MySQL学习路线、数据库的基础、关系型数据库、关键字说明、SQL、MySQL数据库、MySQL服务器对象、SQL的基本操作、库操作、表操作、数据操作、中文数据问题、 校对集问题、web乱码问题

    1 MySQL学习路线 基础阶段:MySQL数据库的基本操作(增删改查),以及一些高级操作(视图.触发器.函数.存储过程等). 优化阶段:如何提高数据库的效率,如索引,分表等. 部署阶段:如何搭建真实 ...

  5. Hadoop生态组件Hive,Sqoop安装及Sqoop从HDFS/hive抽取数据到关系型数据库Mysql

    一般Hive依赖关系型数据库Mysql,故先安装Mysql $: yum install mysql-server mysql-client [yum安装] $: /etc/init.d/mysqld ...

  6. Python3爬虫(九) 数据存储之关系型数据库MySQL

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 关系型数据库关系型数据库是基于关系模型的数据库,而关系模型是通过二维表来保存的,所以关系型数据库的存储方式就是行列 ...

  7. Flink 实践教程 - 入门(4):读取 MySQL 数据写入到 ES

    ​作者:腾讯云流计算 Oceanus 团队 流计算 Oceanus 简介 流计算 Oceanus 是大数据产品生态体系的实时化分析利器,是基于 Apache Flink 构建的具备一站开发.无缝连接. ...

  8. 【搜索引擎】Solr最新安装以及通过关系型数据库(MySQL,Oracle,PostgreSQL)导入数据

    版本号 最新的solr版本 : Solr 8.1.1下载地址:https://lucene.apache.org/solr/downloads.html solr-8.1.0.tgz for Linu ...

  9. 【大数据应用技术】作业九|安装关系型数据库MySQL 安装大数据处理框架Hadoop

    本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 1.安装MySql 按ctrl+alt+t打开终端窗口,安 ...

随机推荐

  1. python sorted函数多条件排序是怎么回事

    首先,要知道sorted 内部实现使用了归并排序,而归并排序是稳定的排序,就是说当元素比不出大小时,其相对位置是不变的. 那么,利用稳定排序的特性,key函数有几个返回值就排序几次,先排序次要条件,后 ...

  2. Phython中读写和存储.mat文件

    背景 在做deeplearning过程中,使用caffe的框架,一般使用matlab来处理图片(matlab处理图片相对简单,高效),用python来生成需要的lmdb文件以及做test产生结果.所以 ...

  3. C++:普通变量C++命名规则

    C++提倡使用拥有一定意义的变量名,使程序代码更有阅读性,命名是必须使用的几种简单的C++命名规则: 命名时只能使用:字母字符.数字和下划线(_); 第一个字符不能是数字: 区分大小写(C++对大小写 ...

  4. Spring Bean初始化之后执行指定方法

    转: Spring Bean初始化之后执行指定方法 2017年07月31日 15:59:33 vircens 阅读数:24807   Spring Bean初始化之后执行指定方法 在运用Spring进 ...

  5. Java基础 -- 字符串(格式化输出、正则表达式)

    一 字符串 1.不可变String String对象是不可变的,查看JDK文档你就会发现,String类中每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象,以包含修改后 ...

  6. (数组) leetcode 66. Plus One

    Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The ...

  7. python 速记正则使用(转)

    目录 python 速记正则使用(转) 正则表达式语法 字符与字符类 量词 组与捕获 断言与标记 条件匹配 正则表达式的标志 Python正则表达式模块 四大功能 两种方法 常用方法 匹配对象的属性与 ...

  8. idea 错误: 找不到或无法加载主类

    1.cmd进入项目目录 2.输入maven命令重构项目 mvn clean mvn idea:idea install

  9. python之路(8)常用模块

    目录 os模块 sys模块 json模块 pickle模块 xml模块 re模块 logging模块 configparser模块 hashlib模块 time模块 random模块 subproce ...

  10. linux学习------磁盘性能测试

    测试服务器  1核1G配置 下载后放在你想测试的目录下,执行preparefile.sh准备测试文件,完成后执行runTest.sh执行测试,等待测试结果完成. {sysbench_bin}> ...