Flink学习笔记-基础

  • 简单介绍
  • 特点
  • 功能特性
  • `Flink`架构分层
  • `Flink`的基本组件
  • 应用场景
  • 流式计算框架对比
  • 工作中如何选择实时框架
  • 一个简单的入门案例
  • 环境
  • 代码:


简单介绍

Flink项目大数据计算领域冉冉升起的新星,大数据计算引擎的发展经历了几个过程,从第一代的MapReduce,到第二代基于有向无环图的Tez,第三代基于内存计算的Spark,再到第四代的Flink,因为Flink可以基于Hadoop进行开发和使用,所以Flink并不会取代Hadoop,而是和Hadoop紧密结合。

Flink主要包括DataStream API,Data Set API,Table API,SQL,Graph API,FlinkML等,现在Flink也有自己的生态圈,涉及离线数据处理,实时数据处理,SQL操作,图计算和机器学习库等

Flink主要由Java代码实现,它同时支持实时流处理和批处理。此外Flink还支持迭代计算,内存管理和程序优化,这是它的原生特性。

特点

  1. 分布式:Flink程序可以运行在多台机器上;
  2. 高性能:处理性能比较高;
  3. 高可用:由于Flink程序本身是稳定的,因此它支持高可用性(High Availability,HA);
  4. 准确:Flink可以保证数据处理的准确性;

功能特性

  1. 流式优先:Flink可以连续处理流式数据;
  2. 容错:Flink提供有状态的计算,可以记录数据的处理状态,当数据处理失败的时候,能够无缝地从失败中恢复,并保持Exactly-once
  3. 可伸缩:Flink中的一个集群支持上千个节点;
  4. 性能:Flink支持高吞吐,低延迟。

Flink架构分层

Flink架构分为四层,其中包括Deploy层,Core层,API层,Library

  1. Deploy层:该层主要涉及Flink的部署模式,Flink支持多种部署模式比如本地,集群(Standalone/YARN)和云服务器(GCE/EC2)
  2. Core层:该层提供了支持Flink计算的全部核心实现,为API层提供基础服务。
  3. API层:该层主要实现了面向无界Stream的流处理和面向Batch的批处理API,其中流处理对应DataStream API,批处理对应DataSet API
  4. Library层:该层也被称为Flink应用框架层,根据API层的划分,在API层之上构建的满足特定应用的实现计算框架,也分别对应面向流处理和批处理两类,面向流处理支持CEP(负责事件处理),基于SQL-Like的操作(基于Table的关系操作);面向批处理支持FlinkML(机器学习库),(Gelly 图处理)Table操作。

Flink的基本组件

flink和Hadoop版本 flink hadoop_学习

由上我们可以看出想要组装一个Flink Job,至少需要三个组件

  1. DataSource:表示数据源组件,主要用来接收数据,目前官网提供了readTextFile,socketTextStream,fromCollection以及一些第三方的Source
  2. Transformation:表示算子,主要用来对数据进行处理,比如Map,FlatMap,Filter,Reduce,Aggregation等;
  3. DataSlink:表示输出组件,主要用来把计算的结果输出到其他存储介质中,比如writeAsText以及Kafka,RedisElasticsearch等第三方slink组件;

应用场景

  1. 实时ETL:集成流计算现有的诸多数据通道和SQL灵活的加工能力,对流式数据进行实时清洗,归并和结构化处理,同时,对离线数据仓库进行有效的补充和优化,并未数据实时传输提供可计算通道;
  2. 实时报表:实时化采集,加工流式数据存储,实时监控和展现业务,客户各类指标,让数据化运营实时化;
  3. 监控预警:对系统和用户行为进行实时监测和分析,以便及时发现危险行为。
  4. 在线系统:实时计算各类数据指标,并利用实时结果及时调整在线系统的相关策略,在各类内容投放,无线智能推送领域有大量的应用。

流式计算框架对比

产品

模型

API

保证次数

容错机制

状态管理

延时

吞吐量

Storm

Native(数据进入立即处理)

组合式(A基础PI)

At-least-once(至少一次)

Record ACK(ACK机制)




Trident

Micro-Batching(划分为小批处理)

组合式

Exactly-once(仅此一次)

Record ACK

基于操作(每次操作都有一个状态)

中等

中等

Spark Streaming

Micro-Batching

声明式(提供封装后的高阶函数,如count函数)

Exactly-once

RDD CheckPoint(基于RDD做CheckPoint)

基于DStream

中等


Flink

Native

声明式

Exactly-once

CheckPoint(Flink的一种快照)

基于操作



工作中如何选择实时框架

  1. 需要关注数据是否需要进行状态管理,如果是那么只能在Trident,Spark StreamingFlink之中选择一个。
  2. 需要考虑项目对At-least-once(至少一次)或者Exactly-one(仅此一次)消息投递模式是否有特殊要求,如果必须要保证仅一次,也不能选择Storm
  3. 对于小型独立项目,并且需要低延迟的场景,建议使用Storm,这样比较简单。
  4. 如果你的项目已经使用了Spark,并且秒级别的实时处理可以满足需求的话,建议使用Spark Streaming
  5. 要求消息投递语义为Exactly-once;数据需求量较大,要求高吞吐低延迟,需要进行状态管理或者窗口统计,这是建议使用Flink

一个简单的入门案例

环境

  1. 开发工具:IntelliJ IDEA 2022.3.2 (Ultimate Edition)
  2. mavenapache-maven-3.9.0
  3. JDKcorretto-1.8
  4. Flink1.16.1
  5. pom文件:
<dependencies>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-java</artifactId>
            <version>1.16.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-java</artifactId>
            <version>1.16.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-clients</artifactId>
            <version>1.16.1</version>
        </dependency>
    </dependencies>

代码:

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.DataSet;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector;

public class WordCount {

  public static void main(String[] args) throws Exception {
    ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
    DataSet<String> text = env.fromElements(
            "Hello World",
            "Hello Flink",
            "Flink is a powerful big data processing framework");

    DataSet<Tuple2<String, Integer>> counts =
            text.flatMap(new Tokenizer())
                    .groupBy(0)
                    .sum(1);

    counts.print();
  }

  public static class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
    @Override
    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
      for (String word : value.split(" ")) {
        out.collect(new Tuple2<>(word, 1));
      }
    }
  }
}

这是一个很简单的案例先让大家感受一下使用Flink