尚硅谷-flink

一、介绍

1.简介

  flink是一个开源的分布式流处理框架

  优势:高性能处理高度灵活window操作有状态计算的Exactly-once

  详情简介,参考官网:https://flink.apache.org/flink-architecture.html

       中文参考:https://flink.apache.org/zh/flink-architecture.html

  flink组件介绍:

  

  1)部署:支持本地、集群(支持yarn资源管理)、云

  2)核心层:提供了计算的核心

  3)API:提供了面向流处理的DataStream和面向批处理的DataSet

  4)类库:支持Table/SQL

   基本架构为 DataSource(数据源) -> Transfromation(算子处理数据) ->DataSink(数据目的)

分层API:

 ··

 

二、快速上手

wordcount:

1.新建maven项目:

 2.导入依赖(提交到服务区的,可以对flink的依赖使用<provided>)

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <flink.version>1.17.0</flink.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-streaming-java</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-clients</artifactId>
      <version>${flink.version}</version>
    </dependency>
  </dependencies>

3.创建用于测试的txt文件

 4.执行步骤

1、创建流处理环境:
2、从文件中读取数据:
3、进行WordCount操作:
4、打印结果到控制台:
5、执行任务:
代码如下:

package org.example;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;

/**
 * Hello world!
 */
public class App {
    public static void main(String[] args) throws Exception {
        // 创建flink执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 从文件读取数据
        DataStreamSource<String> source = env.readTextFile("input/word.txt");
        // 处理数据,执行wordcount操作
        SingleOutputStreamOperator<Tuple2<String, Integer>> summed = 
                source.flatMap(new Tokenizer())
                .keyBy(0)
                .sum(1);
        // 打印结果
        summed.print();
        // 启动执行
        env.execute("WordCount");
    }

    // 自定义FlatMapFunction,用于分词
    public static class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
        @Override
        public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
            // 将输入的字符串按空格分割
            String[] words = value.split("\\s+");

            // 遍历每个单词,并生成 (word, 1) 的元组
            for (String word : words) {
                out.collect(new Tuple2<>(word, 1));
            }
        }
    }
}

 三、flink集群

集群角色:

 四、运行时核心概念

并行度:特定算子的子任务的并行度,

并行度设置:

1.代码中设置:

SingleOutputStreamOperator<Tuple2<String, Integer>> summed =
        source.flatMap(new Tokenizer())
                .setParallelism(2) 
                .keyBy(0)
        .sum(1);

还可以通过env和提交时指定

算子 > env > 提交时设置

插槽、运行提交流程等。。。

 

五、DataStream API

是flink的核心API,flink的运行流程:

1、创建流处理环境:
2、读取数据:
3、转换操作:
4、输出结果:
5、执行任务:(程序是懒执行)

DS主要负责1和5

 

fromSource是新API

 

算子:

map-一进一出,改造完出来重新做人

// 获取运行环境(可以通过conf配置)
 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
 env.setParallelism(1);
 // 从集合中读取数据
 DataStreamSource<WaterSenor> source = env.fromElements(new WaterSenor("sensor_1", 1547718199L, 35),
         new WaterSenor("sensor_2", 1547718191L, 31),
         new WaterSenor("sensor_3", 1547718192L, 32));
 // 转换数据
 SingleOutputStreamOperator<String> map = source.map(s -> s.getId());
 map.print();

 // 执行
 env.execute();

记得执行的步骤!
当然,工作中一般建议定义一个类来实现,如果通过lambda表达式,很难通用,且改起来费劲。推荐的用法如下(用一个service包来进行算子转换)
实现MapFunction接口,两个泛型分别是输入输出类型:
package service;

import bean.WaterSenor;
import org.apache.flink.api.common.functions.MapFunction;

public class MyMapFunction implements MapFunction<WaterSenor, String> {
    @Override
    public String map(WaterSenor value) throws Exception {
        return value.getId() + ":" + value.getVc();
    }
}

 


使用的话new一个就行:
// 获取运行环境(可以通过conf配置)
 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
 env.setParallelism(1);
 // 从集合中读取数据
 DataStreamSource<WaterSenor> source = env.fromElements(new WaterSenor("sensor_1", 1547718199L, 35),
         new WaterSenor("sensor_2", 1547718191L, 31),
         new WaterSenor("sensor_3", 1547718192L, 32));
 // 转换数据
 SingleOutputStreamOperator<String> map = source.map(new MyMapFunction());
 map.print();

 // 执行
 env.execute();

 



filter过滤,为true则保留,否则过滤掉
同理,实现一个接口,泛型是要过滤的数据的类型:
package service;

import bean.WaterSenor;
import org.apache.flink.api.common.functions.FilterFunction;

public class MyFilterFunction implements FilterFunction<WaterSenor> {
    @Override
    public boolean filter(WaterSenor value) throws Exception {
        return "sensor_1".equalsIgnoreCase(value.getId());
    }
}

使用的时候使用.filter传入函数即可:

  // 获取运行环境(可以通过conf配置)
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        // 从集合中读取数据
        DataStreamSource<WaterSenor> source = env.fromElements(new WaterSenor("sensor_1", 1547718199L, 35),
                new WaterSenor("sensor_2", 1547718191L, 31),
                new WaterSenor("sensor_3", 1547718192L, 32));
        // 转换数据
        SingleOutputStreamOperator<WaterSenor> map = source.filter(new MyFilterFunction());
        map.print();

        // 执行
        env.execute();

flatMap,扁平映射,一进多出,比如wordcount的时候,一行返回多个单词

也是实现一个类,泛型表示输入输出类型:

package service;

import bean.WaterSenor;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.util.Collector;

public class MyFlatMapFunction implements FlatMapFunction<WaterSenor, String> {
    @Override
    public void flatMap(WaterSenor value, Collector<String> out) throws Exception {
        if ("sensor_1".equalsIgnoreCase(value.getId())) {
            out.collect(value.getTs().toString());
        } else if ("sensor_2".equalsIgnoreCase(value.getId())){
            out.collect(value.getTs().toString());
            out.collect(value.getVc().toString());
        }

    }
}

使用的时候,new一个类,这里flatmap可以0输出,所以这里的sensor_3不输出,不处理:

  // 获取运行环境(可以通过conf配置)
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        // 从集合中读取数据
        DataStreamSource<WaterSenor> source = env.fromElements(new WaterSenor("sensor_1", 1547718199L, 35),
                new WaterSenor("sensor_2", 1547718191L, 31),
                new WaterSenor("sensor_3", 1547718192L, 32));
        // 转换数据
        SingleOutputStreamOperator<String> map = source.flatMap(new MyFlatMapFunction());
        map.print();

        // 执行
        env.execute();

 

posted @ 2024-09-24 15:43  ---江北  阅读(46)  评论(0编辑  收藏  举报
TOP