这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
概述
概念
分布式处理引擎, 用于对无界和有界数据流进行有效态计算,以内存执行速度和任意规模来执行计算。
特点
- 批流一体: 统一批处理,流处理
- 分布式: Flink程序可以运行在多台机器上
- 高性能: 处理性能比较高
- 高可用: 支持高可用性(HA)
- 准确: 数据处理的准确性
核心组成
- API & Libraries: DataStreamAPI(Stream Processing) DataSet API (Batch Processing) CEP Table FinkML Gelly Table
- core: Runtime(Distributed Streaming Dataflow)
- deploy: Local(Single JVM) Cluster(standalone, YARN) Cloud(GCE, EC2)
处理模型: 流处理与批处理
Flink专注于无限流处理, 有限流处理是无限流处理的一种特殊情况, 封装了DataStream进行流处理, 封装了DataSet进行批处理, 是批流一体的处理引擎, 提供了Table API/SQL 统一了批处理和流处理
应用场景
- 实时ETL
- 实时报表
- 监控预警
- 在线系统
体系
角色
JobManager
- 协调分布式执行,调度task,协调检查点(checkPoint), 协调失败后恢复
- Flink运行时至少存在一个master处理器,配置高可用可能存在多个, 其中一个是leader, 其它是standby
TaskManager
- worker, 主要职责是从JobManager接到任务, 部署和启动任务, 接收上游的数据并处理
- JVM中的一个或多个线程中执行任务的工作节点
体系结构
程序构成
Flink 程序的基本构建块是流和转换,流是数据记录流,转换是将一个或多个流输入, 产生一个或多个输出流
-
Source
数据源, 定义Flink从哪里加载数据, 主要四种: 基于本地的source, 基于文件的source, 基于套接字的source,自定义的source
-
Transformation
数据转换的各种操作, 也称之为算子, 有Map/FlatMap/Filter/KeyBy/Reduce/Window等, 可以将数据转换计算成想要的数据
-
Sink
接收器, Flink将转换计算后的数据发送的地点, 定义了结果数据的输出方向, 常用的有写入文件, 打印出来, 写入socket,自定义的sink
Task和SubTask
- Task是一个阶段多个功能相同SubTask的集合
- SubTask是Flink中任务最小执行单元, 是一个Java类的实例
Operator Chain(操作链)
Flink的所有操作都成为Operator, 客户端在提交任务时会对Operator进行优化, 能进行合并的Operator会合并为一个Operator, 合并后的Operator成为Operator chain, 每个执行链会在TaskManager上一个独立的线程执行
任务槽和槽共享
为了控制一个worker能接受多少个task, worker通过task slot来控制(至少一个)
-
任务槽
标识TaskManger拥有资源的固定大小的子集, 一般来说槽的个数和CPU的核数相等.将内存划分多个槽中(平分)。
内存被划分不同的slot之后可以获得好处:
- 最多能同时并发执行的任务可以控制
- slot有独占的内存空间, 作业之间不受影响, 内存独占,但CPU共享
-
槽共享
shuffle会有网络操作和IO开销,默认情况下, Flink允许子任务共享插槽,只要来自同一个作业, 槽可以保存整个作业的管道
部署
Flink 支持多种安装模式
- Local: 单机模式, 一般本地开发调试
- Standalone: 独立, Flink自带集群, 自己管理资源调度
- Yarn模式: 计算资源统一由Hadoop YARN 管理, 生产环境应用较多
基础环境
- JDK1.8及以上(配置JAVA_HOME环境变量)
- ssh免密码登录
standalone
-
下载文件并解压到相关目录
-
修改配置文件
## flink-conf.yaml jobmanager.rpc.address: 192.168.1.3 taskmanager.numberofTaskSlots:2 ## masters 192.168.1.3: 8081 ## slaves 192.168.1.3 192.168.1.4 192.168.1.5 -
发送到另外两台节点上
scp -r flink-1.13.1 192.168.1.5:$PWD -
配置环境变量
vim /etc/profile export FLINK_HOME=/opt/flink/flink-1.13.1 export PATH=.:$PATH:$JAVA_HOME/bin:$FLINK_HOME/bin . /etc/profile cd /flink-1.13.1/bin ./start-cluster.sh部署成功
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </filter> </filters> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>7</source> <target>7</target> </configuration> </plugin> </plugins>
最简单案例
批处理
pom 文件依赖导入
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_2.12</artifactId>
<version>1.13.0</version>
</dependency>
具体代码
这里需要注意的是FlatMapFunction类不能用lambda表达式,会缺失泛型信息,报错
public class WordCountBatch {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
String input ="C:\\Users\\Administrator\\Desktop\\word.txt";
DataSource<String> dataSource = env.readTextFile(input);
FlatMapOperator<String, Tuple2<String, Integer>> wordDealOpt = dataSource.flatMap(new SplitFunc());
UnsortedGrouping<Tuple2<String, Integer>> wordGroup = wordDealOpt.groupBy(0);
DataSet<Tuple2<String, Integer>> sum = wordGroup.sum(1);
sum.writeAsText("C:\\Users\\Administrator\\Desktop\\output");
env.execute("word Count");
}
static class SplitFunc implements FlatMapFunction<String, Tuple2<String , Integer>> {
@Override
public void flatMap(String value, Collector<Tuple2<String, Integer>> collector) throws Exception {
String[] words = value.split(" ");
for (String word: words){
Tuple2<String, Integer> wordDeal = new Tuple2<>(word, 1);
collector.collect(wordDeal);
}
}
}
}
流处理
前置准备
-
安装netcat
yum install -y nc nc -lk 10000 nc 192.168.1.3 10000
pom文件依赖导入
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.12</artifactId>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_2.12</artifactId>
<version>1.13.0</version>
</dependency>
具体代码
public class WordCountStream {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> streamSource = env.socketTextStream("192.168.1.3", 10000);
SingleOutputStreamOperator<Tuple2<String, Integer>> singleOutputStreamOperator = streamSource.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
@Override
public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
for (String word : value.split(" ")) {
out.collect(Tuple2.of(word, 1));
}
}
});
SingleOutputStreamOperator<Tuple2<String, Integer>> result = singleOutputStreamOperator.keyBy(0).sum(1);
result.print();
env.execute("word Count");
}
}