自定义数据源DataSource
前言:
- DataStream API介绍
Flink 中的 DataStream 程序是对数据流(例如过滤、更新状态、定义窗口、聚合)进行转换的常规程序。数据流的起始是从各种源(例如消息队列、套接字流、文件)创建的。结果通过sink返回,例如可以将数据写入文件或标准输出(例如命令行终端)。Flink 程序可以在各种上下文中运行,可以独立运行,也可以嵌入到其它程序中。任务执行可以运行在本地 JVM 中,也可以运行在多台机器的集群上。
基于 DataStream 派生新的流,并使用 map、filter 等 API 方法把 DataStream 和派生的流连接在一起。

- Flink程序剖析:
-
获取一个
执行环境(execution environment); -
加载/创建初始数据;
-
指定数据相关的转换;
-
指定计算结果的存储位置;
-
触发程序执行
模拟传感器读取的温度
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env =StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
DataStream<SensorReading> dataStream = env.addSource(new MySensorSource());
dataStream.print();
env.execute();
}
private static class MySensorSource implements SourceFunction<SensorReading> {
//定义一个标识位,用来控制数据的产生
private boolean running = true;
@Override
public void run(SourceContext<SensorReading> ctx) throws Exception {
//定义一个随机数发生器
Random random = new Random();
//设置10个传感器的初始温度
HashMap<String, Double> sensorTempMap = new HashMap<>();
for (int i = 0; i < 10; i++) {
sensorTempMap.put("sensor_"+(i+1), 60 + random.nextGaussian()*20);
}
while(running){
for(String sensorID : sensorTempMap.keySet()){
//在当前温度基础上随机波动
Double newtemp = sensorTempMap.get(sensorID)+ random.nextGaussian();
sensorTempMap.put(sensorID,newtemp);
ctx.collect(new SensorReading(sensorID,System.currentTimeMillis(),newtemp));
}
//控制输出频率
Thread.sleep(1000L);
}
}
@Override
public void cancel() {
running = false;
}
}
分析
添加数据源的方法,需要传入一个function,SourceFunction是定义的一个接口,传入的function需要实现该接口
public <OUT> DataStreamSource<OUT> addSource(SourceFunction<OUT> function) {
return addSource(function, "Custom Source");
}
因此,自定义一个类MySensorSource实现SourceFunction接口,而最后输出的数据是自定义的SensorReading类,所以SourceFunction的泛型是<SensorReading>。之后重写run和cancel方法
在run方法中,读取hashmap中的10个数据,最后收集的结果为ID,时间戳,温度
有一行代码最为关键
ctx.collect(new SensorReading(sensorID,System.currentTimeMillis(),newtemp));
debug开始:
进入这个函数,发现跳到了NonTimestampContext类里的collect方法,因此可以推断出调用run函数的时候,传入了NonTimestampContext类的实例对象
public void run(SourceContext<SensorReading> ctx)
回到调用run函数之前,如下图

果然,在调用run函数之前,ctx通过getSourceContext函数变成了NonTimestampContext类的实例对象,调用run函数时传入了NonTimestampContext类对象,因此在run函数里的ctx变成了NonTimestampContext类的实例对象

打印出来的结果如下:

5279

被折叠的 条评论
为什么被折叠?



