flink源码分析_Flink基础:DataStream API

8a241659e75fd72aa13f96f60875d3dc.png

往期推荐:

Flink基础:入门介绍

Flink深入浅出:资源管理

Flink深入浅出:部署模式

Flink深入浅出:内存模型

Flink深入浅出:JDBC Source从理论到实战

Flink深入浅出:Sql Gateway源码分析

Flink深入浅出:JDBC Connector源码分析

本篇先介绍流中的数据,再通过一个完整的案例,介绍流处理应用中的几个重要组成部分。

流里面是什么

Flink的DataStream API可以基于Java或Scala编写,流内部支持很多种类型,比如Java的基础类型,如String、Long、Integer、Boolean、Array等;也支持复杂类型,如Tuples、POJOS、Scala Case class等。也支持使用Kryo或Avro进行序列化。Flink原生的序列化在tuple和pojo上效率更高,对于java flink定义了自己的tuple,最多支持25个列。

Tuple2<String, Integer> person = Tuple2.of("Fred", 35);

// 从0开始索引
String name = person.f0;
Integer age = person.f1;

也能自动识别POJO类型,但需要满足:类是public且不是静态内部类,类包含public的无参构造方法,所有非静态或非transient字段都是public修饰或包含public的getter setter方法。比如:

public class Person {
public String name;
public Integer age;
public Person() {};
public Person(String name, Integer age) {
. . .
};
}

Person person = new Person("Fred Flintstone", 35);

完整样例

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.api.common.functions.FilterFunction;

public class Example {

public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();

DataStream flintstones = env.fromElements(new Person("Fred", 35),new Person("Wilma", 35),new Person("Pebbles", 2));
DataStream adults = flintstones.filter(new FilterFunction() {@Overridepublic boolean filter(Person person) throws Exception {return person.age >= 18;
}
});
adults.print();
env.execute();
}public static class Person {public String name;public Integer age;public Person() {};public Person(String name, Integer age) {this.name = name;this.age = age;
};public String toString() {return this.name.toString() + ": age " + this.age.toString();
};
}
}

执行环境

每个Flink应用都需要一个执行环境,比如上面代码中的env,当调用env.execute() 时,背后会执行job图的编译,并发送到JM。在JM中把job图在编译成执行图,描述并行的执行过程,然后交由TM执行。每个算子的子任务会在task slot中并行执行。注意,如果不调用env.execute()任务就不会触发执行。

fd8735b0b008b3e18b05ce9553cac059.png

流的输入

上面的例子中,使用env.fromElements获取数据流,也可以使用fromCollection。如:

List people = new ArrayList();
people.add(new Person("Fred", 35));
people.add(new Person("Wilma", 35));
people.add(new Person("Pebbles", 2));
DataStream flintstones = env.fromCollection(people);

另一种简单的方式是通过socket获取数据:

DataStream<String> lines = env.socketTextStream("localhost", 9999)

也可以从文件中读取:

DataStream lines = env.readTextFile("file:///path");

在具体的应用中,最常见的数据源需要支持低延迟、高吞吐、支持回放,这样才能保证高性能和高可用,比如Kafka。

流的输出

在上面的例子中, adults.print会在taskmanager中输出日志,如果使用IDE会在控制台输出。在print中会把每条记录调用toString方法输出打印。如:

1> Fred: age 35
2> Wilma: age 35

前面的1>和2>代表具体的子任务(可能是不同的线程)。在生产环境,一般会使用StreamingFileSink,不同的数据库或者发布订阅系统。

调试

在生产环境,应用会运行在远程集群或容器中。JM和TM日志在失败时会很有用,但是如果在IDE中断点调试会更方便点。

总结

到此你可以开始编写flink的代码,并运行一个简单的应用流了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值