Flink(一)初识Flink 通过简单案例 轻松了解Flink可以用来做什么 了解如何被资本家按在地上剁手

想写Flink相关内容很长时间了,因为总是查询不到我想要的资料,花费了较多的时间,尝试提供一些我认为有用的资料。又或许是我的学习方式有问题,但依然要不断前行,不断试错,寻找一个正确的方式。


背景

这次的技术选型没有我的参与,我是被告知要使用Flink,需要去学习一下Flink相关内容。加上本身我对流式计算也未曾了解过,所以这一部分的知识,对我来说更像是另一个新世界。对于新事物,我的内心是激动的,所以最近挺长一段时间,我是在一边学习,一边应用它,期间也走了许多的弯路。这个系列的文章,一个是去介绍我使用过的一些特性(内容很多,不可能面面具到,且顺利入门后,便可以自主地去了解需要的内容。),同时又是一个再学习的过程。


计算引擎的前世今生

上面文章对整个计算引擎的发展进行了比较详细的介绍。可以了解到Flink是一个 流式 计算引擎,可拆分为计算和流式进行理解。

计算

通过一条sql直接了当地了解一下 计算引擎 是什么

select count(*) from t_user where age > 18;

上面这段sql的目的是计算出表中年龄大于18岁的有多少人

得到结果的这个过程,可称之为计算。

流式

计算的前提可以有两种
一种是招生结束已经开始关门上课了,统计一个班级里有多少个大于18岁的学生。(批处理)
一种是还在暑假,招生未满,时刻统计一个班级里有多少个大于18岁的学生。(流式处理)

把这两种情况,分别理解成批处理流处理

因为Flink中剔除了批处理的概念,但是它同样能批处理计算。因此将流分成了 有界流无界流

了解到这里,我想至少现在可以知道项目使用Flink来做计算-流式计算,此时再进入Flink官网进行学习。

暂且不急着安装,不急着上手,先看看概览
点进去,一脸懵逼,别急,我也一样,不用一下子都懂,大概了解点!
说是应用程序的开发提供了不同级别的抽象。
API 最底层的抽象为 有状态 实时流处理有状态是什么?现在不用明白,甚至这一层现在都不用明白,有的人说我就要明白,我想说,等明白了不就TM已经学完了,总的来说,暂且可以不用明白的内容不影响继续往下学习就好。
第二层抽象是 Core APIs( 核心API
DataStream API(应用于有界/无界数据流场景)
DataSet API(应用于有界数据集场景)
这里的核心接口,在我看来也是比较主要的部分了。现在只需理解,就是这两个类中的方法,后面的编程主要是围绕 DataStream。
再往上两层就是表和sql,也就是其程序实现可以使用 SQL 查询表达式来编程 。能写sql,我是没试过,回头看到教程就跟着玩一下。
在这里插入图片描述
我觉得,看到这有点不耐烦了,实验才能带来兴趣,下面先来看一个典型的案例

WordCount

Flink程序主要有三个部分,分别是 数据源 Source 算子 Operators 输出 Sink

代码在下面,自行copy就能跑,不能跑到话,emmm,再说了。

代码中提到的算子:map,keyby,window,reduce,我想在让代码跑起来,在流程中慢慢灌输概念。

流程

将输入的字符串,通过空格分割成多个词汇,计算每个词出现的个数。

Source
Socket 127.0.0.1 6666
Oprator
map:String转换成WordWithCount- - >>
keyby:通过WordWithCount的word属性分组 - - >>
window:开窗,50秒一次窗口 1秒计算一次 - - >>
reduce: 聚合计数
Sink
print

Source(Socket 127.0.0.1:6666)----> Oprator(map-> keyby ) ----> Sink

输入源(Socket)

nc -l 6666(Linux) nc -l -p 6666 (Windows)
这里的输入源方式我采用的是本机创建socket连接,端口配置的是6666 ,有需要修改的自行修改。

在这里插入图片描述

此时可以启动样例WordCount.main(),本篇作为开篇会在流程上描述得较为详细,因为第一篇更多的是面向初次使用者,为的是少在环境上占用时间。

此时可以尝试输入一些字符串例如:

Antry is a handsome handsome handsome handsome guy

在这里插入图片描述
可以看到控制台会一直(每秒一次)(直到最后一次输入的50秒之后)输出统计结果:
可以明显看到统计结果中handsome有四个,说明我非常的帅
在这里插入图片描述

算子

看了上面的运行结果,此时可以开始了解一下 keyBy window reduce

  • keyby
    从英文意思上不难看出是分组,没错,就是将每个相同的单词放在一起。
    例如上面的handsome,它们四个相同则为一组,其他只有一个,也都各为一组。
    如果你输入26个字母分别空格隔开,那就是26组。
  • window
    开窗其实也很好理解,就是只计算这个窗口中的数据。
    在这个样例中,就是只计算近50秒之内输入的字符串。想试一下的话,可以自己随便多输入几行看下效果。
    可以应用的场景很多,例如判断一个用户刷淘宝最近五分钟浏览的类别,接下来就多推送一些该类别的特价产品,让他经不住诱惑购买。
    可恶的资本家,可恶的大数据。
  • reduce
    聚合就是计算的部分,前面只是将数据收集,控制收集什么样的数据。

输出

本次的案例就是输出在控制台,输出有很多种方式,推到Es,kafka,数据库,等等,这部分内容网上很丰富。不是本章介绍的重点。

结束语

本章的内容到这里就结束了,下一章将介绍集群以及运行过程。很多教程一开始就是各种原理,我个人是觉得很不舒服,所以我想先了解这些前置知识,再进入后面的学习。

代码

引入Flink相关依赖

 <!-- Flink 的 Java api -->
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-java</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <!-- Flink Streaming 的 Java api -->
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <!-- Flink 的 Web UI -->
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-runtime-web_${scala.binary.version}</artifactId>
      <version>${flink.version}</version>
    </dependency>

WordCount.java

package org.antry.demo;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;
/**
 * @author T_Antry
 * @date 2022-04-10 18:36
 * @Help nc -l 12345 on Linux or nc -l -p 12345 on Windows
 */
public class WordCount {
    public static void main(String[] args) throws Exception {
        final String hostname = "127.0.0.1";
        final int port = 6666;
        // 获取运行环境
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 数据源
        DataStream<String> text = env.socketTextStream(hostname, port, "\n");
        //解析数据 统计数据-单词计数 hello lz hello world
        DataStream<WordWithCount> windowCounts = text.flatMap(new FlatMapFunction<String, WordWithCount>() {
                    public void flatMap(String s, Collector<WordWithCount> collector){
                        //按照空白符进行切割
                        for (String word : s.split("\\s")) {
                            //<单词,1>
                            collector.collect(new WordWithCount(word, 1L));
                        }
                    }
                })
                //按照key进行分组
                .keyBy("word")
                //设置窗口的时间长度 50秒一次窗口 1秒计算一次
                .timeWindow(Time.seconds(50), Time.seconds(1))
                //聚合,聚合函数
                .reduce(new ReduceFunction<WordWithCount>() {
                    public WordWithCount reduce(WordWithCount a, WordWithCount b) throws Exception {
                        //按照key聚合
                        return new WordWithCount(a.word, a.count + b.count);
                    }
                });
        // 输出
        windowCounts.print();
        //执行
        env.execute("Socket Window WordCount");
    }

    // ------------------------------------------------------------------------

    /** 数据类型. */
    public static class WordWithCount {

        public String word;
        public long count;

        @SuppressWarnings("unused")
        public WordWithCount() {}

        public WordWithCount(String word, long count) {
            this.word = word;
            this.count = count;
        }

        @Override
        public String toString() {
            return word + " : " + count;
        }
    }
}
  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值