最新Flink处理函数实战之五:CoProcessFunction(双流处理)(1),Github标星5.3K

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

Mybatis源码解析

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

import org.apache.flink.streaming.api.functions.co.CoProcessFunction;

/**

  • @author will

  • @email zq2599@gmail.com

  • @date 2020-11-09 17:33

  • @description 串起整个逻辑的执行类,用于体验CoProcessFunction

*/

public abstract class AbstractCoProcessFunctionExecutor {

/**

  • 返回CoProcessFunction的实例,这个方法留给子类实现

  • @return

*/

protected abstract CoProcessFunction<

Tuple2<String, Integer>,

Tuple2<String, Integer>,

Tuple2<String, Integer>> getCoProcessFunctionInstance();

/**

  • 监听根据指定的端口,

  • 得到的数据先通过map转为Tuple2实例,

  • 给元素加入时间戳,

  • 再按f0字段分区,

  • 将分区后的KeyedStream返回

  • @param port

  • @return

*/

protected KeyedStream<Tuple2<String, Integer>, Tuple> buildStreamFromSocket(StreamExecutionEnvironment env, int port) {

return env

// 监听端口

.socketTextStream(“localhost”, port)

// 得到的字符串"aaa,3"转成Tuple2实例,f0=“aaa”,f1=3

.map(new WordCountMap())

// 将单词作为key分区

.keyBy(0);

}

/**

  • 如果子类有侧输出需要处理,请重写此方法,会在主流程执行完毕后被调用

*/

protected void doSideOutput(SingleOutputStreamOperator<Tuple2<String, Integer>> mainDataStream) {

}

/**

  • 执行业务的方法

  • @throws Exception

*/

public void execute() throws Exception {

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

// 并行度1

env.setParallelism(1);

// 监听9998端口的输入

KeyedStream<Tuple2<String, Integer>, Tuple> stream1 = buildStreamFromSocket(env, 9998);

// 监听9999端口的输入

KeyedStream<Tuple2<String, Integer>, Tuple> stream2 = buildStreamFromSocket(env, 9999);

SingleOutputStreamOperator<Tuple2<String, Integer>> mainDataStream = stream1

// 两个流连接

.connect(stream2)

// 执行低阶处理函数,具体处理逻辑在子类中实现

.process(getCoProcessFunctionInstance());

// 将低阶处理函数输出的元素全部打印出来

mainDataStream.print();

// 侧输出相关逻辑,子类有侧输出需求时重写此方法

doSideOutput(mainDataStream);

// 执行

env.execute(“ProcessFunction demo : CoProcessFunction”);

}

}

  • 关键点之一:一共有两个数据源,每个源的处理逻辑都封装到buildStreamFromSocket方法中;

  • 关键点之二:stream1.connect(stream2)将两个流连接起来;

  • 关键点之三:process接收CoProcessFunction实例,合并后的流的处理逻辑就在这里面;

  • 关键点之四:getCoProcessFunctionInstance是抽象方法,返回CoProcessFunction实例,交给子类实现,所以CoProcessFunction中做什么事情完全由子类决定;

  • 关键点之五:doSideOutput方法中啥也没做,但是在主流程代码的末尾会被调用,如果子类有侧输出(SideOutput)的需求,重写此方法即可,此方法的入参是处理过的数据集,可以从这里取得侧输出;

子类决定CoProcessFunction的功能

  1. 子类CollectEveryOne.java如下所示,逻辑很简单,将每个源的上游数据直接输出到下游算子:

package com.bolingcavalry.coprocessfunction;

import org.apache.flink.api.java.tuple.Tuple2;

import org.apache.flink.streaming.api.functions.co.CoProcessFunction;

import org.apache.flink.util.Collector;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class CollectEveryOne extends AbstractCoProcessFunctionExecutor {

private static final Logger logger = LoggerFactory.getLogger(CollectEveryOne.class);

@Override

protected CoProcessFunction<Tuple2<String, Integer>, Tuple2<String, Integer>, Tuple2<String, Integer>> getCoProcessFunctionInstance() {

return new CoProcessFunction<Tuple2<String, Integer>, Tuple2<String, Integer>, Tuple2<String, Integer>>() {

@Override

public void processElement1(Tuple2<String, Integer> value, Context ctx, Collector<Tuple2<String, Integer>> out) {

logger.info(“处理1号流的元素:{},”, value);

out.collect(value);

}

@Override

public void processElement2(Tuple2<String, Integer> value, Context ctx, Collector<Tuple2<String, Integer>> out) {

logger.info(“处理2号流的元素:{}”, value);

out.collect(value);

}

};

}

public static void main(String[] args) throws Exception {

new CollectEveryOne().execute();

}

}

  1. 上述代码中,CoProcessFunction后面的泛型定义很长:<Tuple2<String, Integer>, Tuple2<String, Integer>, Tuple2<String, Integer>> ,一共三个Tuple2,分别代表一号数据源输入、二号数据源输入、下游输出的类型;

验证

  1. 分别开启本机的9998和9999端口,我这里是MacBook,执行nc -l 9998和nc -l 9999

  2. 启动Flink应用,如果您和我一样是Mac电脑,直接运行CollectEveryOne.main方法即可(如果是windows电脑,我这没试过,不过做成jar在线部署也是可以的);

  3. 在监听9998和9999端口的控制台分别输入aaa,111和bbb,222

  4. 以下是flink控制台输出的内容,可见processElement1和processElement1方法的日志代码已经执行,并且print方法作为最下游,将两个数据源的数据都打印出来了,符合预期:

12:45:38,774 INFO CollectEveryOne - 处理1号流的元素:(aaa,111),

(aaa,111)

12:45:43,816 INFO CollectEveryOne - 处理2号流的元素:(bbb,222)

(bbb,222)

更多

最后

经过日积月累, 以下是小编归纳整理的深入了解Java虚拟机文档,希望可以帮助大家过关斩将顺利通过面试。
由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。







由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

外链图片转存中…(img-yCAcPU9Z-1715626443760)]

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常感谢您的提问!如果您想要在Flink中获取MySQL多张表的信息,可以按照如下步骤进行: 1. 首先需要在Flink中使用JDBC连接器连接MySQL数据库,并创建一个JDBC输入源,以便从MySQL中读取数据。 2. 然后可以通过Flink的Table API或SQL API将多张表的数据进行连接或者关联,从而得到您需要的数据。 3. 最后可以使用自定义的Sink将数据写入MySQL中。下面就是一个简单的Java代码示例,可以帮助您实现该功能: ``` public class FlinkMySQLSink { public static void main(String[] args) throws Exception { // set up the execution environment StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // set up JDBC connection options String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = "password"; String driverName = "com.mysql.jdbc.Driver"; // create a JDBC input source to read multiple tables from MySQL JdbcInputFormat jdbcInputFormat = JdbcInputFormat.buildJdbcInputFormat() .setDrivername(driverName) .setDBUrl(url) .setUsername(username) .setPassword(password) .setQuery("SELECT * FROM table1; SELECT * FROM table2;") .finish(); // create a data stream from the JDBC input source DataStream<Tuple2<String, String>> inputDataStream = env.createInput(jdbcInputFormat); // use Table API or SQL API to join or combine multiple tables Table table = inputDataStream .map(new MapFunction<Tuple2<String, String>, Row>() { public Row map(Tuple2<String, String> value) throws Exception { return Row.of(value.f0, value.f1); } }) .toTable(new TableSchema(new String[]{"column1", "column2"}, new TypeInformation[]{Types.STRING, Types.STRING})); // create a custom Sink to write data back to MySQL JDBCOutputFormat jdbcOutputFormat = JDBCOutputFormat.buildJDBCOutputFormat() .setDrivername(driverName) .setDBUrl(url) .setUsername(username) .setPassword(password) .setQuery("INSERT INTO result_table (column1, column2) VALUES (?, ?)") .finish(); // write the data stream to the custom Sink table.writeToSink(jdbcOutputFormat); // execute the Flink job env.execute("Flink MySQL Sink Example"); } } ``` 在这个示例中,我们首先设置了JDBC连接器所需的参数,然后使用JdbcInputFormat创建了一个JDBC输入源,该源可以从MySQL中读取多个表的数据。 接下来,我们使用Table API或SQL API将多个表的数据连接或者关联起来,并生成一个包含所需数据的Table对象。 最后,我们使用自定义的JDBCOutputFormat创建一个Sink,将Table中的数据写回到MySQL中。在这个Sink中,我们需要指定要写入哪个表,以及如何将数据映射到表中的列。 希望这个示例可以帮助您实现获取MySQL多张表信息的功能!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值