flink学习-4(Data Sink/Transformation)

Flink Data sink

sink 下沉,在flink数据处理过程中是为了将数据沉淀下来,换句话说,flink通过data source接入数据,然后在flink进行相关计算,然后操作后将计算后的数据结果sink到某个地方。

Data transformation

一般flink数据从source作为数据源,然后经过Transformation,所谓的transformation 就是数据转换的各种操作,有Map / FlatMap / Filter / KeyBy / Reduce / Fold / Aggregations / Window / WindowAll / Union / Window join / Split / Select / Project 等,操作很多,可以将数据转换为自己想要的数据。

  1. map
    相对比较简单的转换之一,其中数据是个数据流,输出也是个数据流,举例:
SingleOutputStreamOperator<Student> map = student.map(new MapFunction<Student, Student>() {
   @Override
   public Student map(Student value) throws Exception {
       Student s1 = new Student();
       s1.id = value.id;
       s1.name = value.name;
       s1.password = value.password;
       s1.age = value.age + 5;
       return s1;
   }
});

简单将每个对象中age数据+5

  1. FlatMap
    采用一条记录并输出0个,1个或多个记录。
SingleOutputStreamOperator<Student> flatMap = student.flatMap(new FlatMapFunction<Student, Student>() {
   @Override
   public void flatMap(Student value, Collector<Student> out) throws Exception {
       if (value.id % 2 == 0) {
           out.collect(value);
       }
   }
});
  1. Fliter
    函数根据条件判断出结果
SingleOutputStreamOperator<Student> filter = student.filter(new FilterFunction<Student>() {
   @Override
   public boolean filter(Student value) throws Exception {
       if (value.id > 95) {
           return true;
       }
       return false;
   }
});
  1. KeyBy
    KeyBy 在逻辑上是基于 key 对流进行分区。在内部,它使用 hash 函数对流进行分区。它返回 KeyedDataStream 数据流。
KeyedStream<Student, Integer> keyBy = student.keyBy(new KeySelector<Student, Integer>() {
   @Override
   public Integer getKey(Student value) throws Exception {
       return value.age;
   }
});
  1. Reduce
    Reduce 返回单个的结果值,并且 reduce 操作每处理一个元素总是创建一个新值。常用的方法有 average, sum, min, max, count,使用 reduce 方法都可实现。
SingleOutputStreamOperator<Student> reduce = student.keyBy(new KeySelector<Student, Integer>() {
   @Override
   public Integer getKey(Student value) throws Exception {
       return value.age;
   }
}).reduce(new ReduceFunction<Student>() {
   @Override
   public Student reduce(Student value1, Student value2) throws Exception {
       Student student1 = new Student();
       student1.name = value1.name + value2.name;
       student1.id = (value1.id + value2.id) / 2;
       student1.password = value1.password + value2.password;
       student1.age = (value1.age + value2.age) / 2;
       return student1;
   }
});
  1. Fold
    Fold 通过将最后一个文件夹流与当前记录组合来推出 KeyedStream。 它会发回数据流。
KeyedStream.fold("1", new FoldFunction<Integer, String>() {
   @Override
   public String fold(String accumulator, Integer value) throws Exception {
       return accumulator + "=" + value;
   }
})
  1. Aggregations
    DataStream API 支持各种聚合,例如 min,max,sum 等。 这些函数可以应用于 KeyedStream 以获得 Aggregations 聚合
KeyedStream.sum(0) 
KeyedStream.sum("key") 
KeyedStream.min(0) 
KeyedStream.min("key") 
KeyedStream.max(0) 
KeyedStream.max("key") 
KeyedStream.minBy(0) 
KeyedStream.minBy("key") 
KeyedStream.maxBy(0) 
KeyedStream.maxBy("key")
  1. Window
    Window 函数允许按时间或其他条件对现有 KeyedStream 进行分组。
inputStream.keyBy(0).window(Time.seconds(10));

Flink 定义数据片段以便(可能)处理无限数据流。 这些切片称为窗口。 此切片有助于通过应用转换处理数据块。 要对流进行窗口化,我们需要分配一个可以进行分发的键和一个描述要对窗口化流执行哪些转换的函数

要将流切片到窗口,我们可以使用 Flink 自带的窗口分配器。 我们有选项,如 tumbling windows, sliding windows, global 和 session windows。 Flink 还允许您通过扩展 WindowAssginer 类来编写自定义窗口分配器。 这里先预留下篇文章来讲解这些不同的 windows 是如何工作的。

  1. WindowAll
    windowAll 函数允许对常规数据流进行分组。 通常,这是非并行数据转换,因为它在非分区数据流上运行。

与常规数据流功能类似,我们也有窗口数据流功能。 唯一的区别是它们处理窗口数据流。 所以窗口缩小就像 Reduce 函数一样,Window fold 就像 Fold 函数一样,并且还有聚合。

inputStream.keyBy(0).windowAll(Time.seconds(10));
  1. Union
    Union 函数将两个或多个数据流结合在一起。 这样就可以并行地组合数据流。 如果我们将一个流与自身组合,那么它会输出每个记录两次。
inputStream.union(inputStream1, inputStream2, ...);
  1. Window join
    可以通过一些 key 将同一个 window 的两个数据流 join 起来
inputStream.join(inputStream1)
          .where(0).equalTo(1)
          .window(Time.seconds(5))     
          .apply (new JoinFunction () {...});
  1. Split
    此功能根据条件将流拆分为两个或多个流。 当您获得混合流并且您可能希望单独处理每个数据流时,可以使用此方法。
SplitStream<Integer> split = inputStream.split(new OutputSelector<Integer>() {
    @Override
    public Iterable<String> select(Integer value) {
        List<String> output = new ArrayList<String>(); 
        if (value % 2 == 0) {
            output.add("even");
        }
        else {
            output.add("odd");
        }
        return output;
    }
});
  1. select
    此功能允许您从拆分流中选择特定流
SplitStream<Integer> split;
DataStream<Integer> even = split.select("even"); 
DataStream<Integer> odd = split.select("odd"); 
DataStream<Integer> all = split.select("even","odd");
  1. Project
    函数允许您从事件流中选择属性子集,并仅将所选元素发送到下一个处理流
DataStream<Tuple4<Integer, Double, String, String>> in = // [...] 
DataStream<Tuple2<String, String>> out = in.project(3,2);

参考文档

http://www.54tianzhisheng.cn/2018/11/04/Flink-Data-transformation/

好的,您可以按照以下的方式来编写docker-compose.yml文件: ``` version: '3.7' services: jobmanager: image: flink:1.17.0 command: jobmanager ports: - "8081:8081" taskmanager: image: flink:1.17.0 command: taskmanager depends_on: - jobmanager links: - jobmanager:jobmanager environment: - JOB_MANAGER_RPC_ADDRESS=jobmanager - FLINK_TASK_MANAGER_MEMORY_PROCESS_SIZE=1024m elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2 environment: - discovery.type=single-node ports: - "9200:9200" mysql: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=<your_password> - MYSQL_USER=<your_user> - MYSQL_PASSWORD=<your_password> - MYSQL_DATABASE=<your_database> ports: - "3306:3306" postgres: image: postgres:13.1 environment: - POSTGRES_USER=<your_user> - POSTGRES_PASSWORD=<your_password> - POSTGRES_DB=<your_database> ports: - "5432:5432" flink-job: image: flink:1.17.0 volumes: - ./flink-conf.yaml:/opt/flink/conf/flink-conf.yaml - ./lib/flink-sql-connector-elasticsearch7-3.0.1-1.17.jar:/opt/flink/lib/flink-sql-connector-elasticsearch7-3.0.1-1.17.jar - ./lib/flink-sql-connector-mysql-cdc-2.3.0.jar:/opt/flink/lib/flink-sql-connector-mysql-cdc-2.3.0.jar - ./lib/flink-sql-connector-postgres-cdc-2.3.0.jar:/opt/flink/lib/flink-sql-connector-postgres-cdc-2.3.0.jar command: jobmanager depends_on: - jobmanager - elasticsearch - mysql - postgres links: - elasticsearch:elasticsearch - mysql:mysql - postgres:postgres environment: - JOB_MANAGER_RPC_ADDRESS=jobmanager - FLINK_TM_HEAP_SIZE=1024m - FLINK_PROPERTIES= - FLINK_ENV_JAVA_OPTS= - FLINK_ENV_JAVA_TOOL_OPTIONS= - FLINK_CONF_DIR=/opt/flink/conf - FLINK_LIB_DIR=/opt/flink/lib - FLINK_PLUGINS_DIR=/opt/flink/plugins - FLINK_OPT_DIR=/opt/flink/opt - FLINK_LOG_DIR=/opt/flink/log - FLINK_HOME=/opt/flink volumes: - ./job.jar:/opt/flink/job.jar - ./flink-conf.yaml:/opt/flink/conf/flink-conf.yaml ``` 其中需要注意的是: 1. 在 `flink-job` 服务中,我们使用了 `volumes` 来挂载 `flink-conf.yaml` 和三个依赖的jar包到容器的 `/opt/flink/conf` 和 `/opt/flink/lib` 目录中。 2. 我们在 `flink-job` 服务的环境变量中设置了 `FLINK_PROPERTIES`,因为 Flink 在启动时会读取这个环境变量中的配置信息。 3. 我们在 `flink-job` 服务的环境变量中设置了 `FLINK_LIB_DIR`,这是因为 Flink 在启动时会从这个目录中加载依赖的jar包。 4. 我们在 `flink-job` 服务的环境变量中设置了 `FLINK_CONF_DIR`,这是因为 Flink 在启动时会读取这个目录中的配置文件。 5. 我们在 `flink-job` 服务的环境变量中设置了 `FLINK_HOME`,这是因为 Flink 在启动时需要知道它的安装路径。 上述的docker-compose.yml文件可以满足您的要求,在启动容器后,您可以使用以下的命令来进入到flink-job容器中: ``` docker-compose run flink-job /bin/bash ``` 然后,您可以在容器中运行Flink任务了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taotaobujuerulv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值