Flink基础学习笔记(二)常用算子

写在前面

本节主要介绍Flink中常用的算子,后续随着深入学习过程将会不断更新。整体上来说,Flink的算子可以从DataStream/DataSet、Sink/Source/Transformation/共享变量、keyBy/groupBy/noKey、RichFunction/ParallelFunciton/Function等角度划分,实际使用过程中也是需要考虑以上这些点。

1.Source算子

1.1已经实现的Source

  • 基于文件的:readTextFile(path),读取文本文件,文件遵循TextInputFormat 读取规则,逐行读取并返回。
  • 基于socket:socketTextStream,从socker中读取数据,元素可以通过一个分隔符切开。
  • 基于集合:fromCollection(Collection),通过java 的collection集合创建一个数据流,集合中的所有元素必须是相同类型的。
  • 扩展数据源:addSource, 可以实现读取第三方数据源的数据,系统内置提供了一批connectors,连接器会提供对应的source支持。常用的包括:DataStream Connectors

1.2自定义Source

单并行度数据源:SourceFunction;多并行度数据源:ParallelSourceFunction。
此外,一般带RichXXXFunction里面可以实现更多的方法(包括初始化…等操作)。
ParallelSourceFunction举例说明
每秒产生一个number

public class ExampleSource implements ParallelSourceFunction<Long> {
    private long number = 1L;
    private boolean isRunning = true;
    
    @Override
    public void run(SourceContext<Long> ctx) throws Exception {
        while (isRunning){
            ctx.collect(number);
            number++;
            Thread.sleep(1000);
        }

    }
    @Override
    public void cancel() {
        isRunning = false;
    }
}

2.Transformation算子

2.1常见算子概述

注意这些算子本身底层实现存在相互调用过程,这里的大部分算子和Spark中都是类似的,平时使用过程中注意灵活运用。

  • map、flatMap、mapPartition
    map:输入一个元素,然后返回一个元素,中间可以做一些清洗转换等操作;
    flatMap:对集合中每个元素进行操作然后再扁平化。
    mapPartition:类似map,一次处理一个分区的数据【如果在进行map处理的时候需要获取第三方资源链接,建议使用MapPartition,但是注意OOM问题】
  • filter
    filter:过滤函数,对传入的数据进行判断,符合条件的数据会被留下。
  • reduce、aggregate
    reduce:每流入一个新元素,新元素与中间数据两两合一,生成新的中间数据。
    aggregate:先缓存所有元素,等到触发条件后对窗口内的全量元素执行计算。
  • join、cross、union、connect
    union:合并多个流,新的流会包含所有流中的数据,但是union是一个限制,就是所有合并的流类型必须是一致的。
    connect:和union类似,但是只能连接两个流,两个流的数据类型可以不同,会对两个流中的数据应用不同的处理方法。
    cross:获取两个数据集的笛卡尔积。
    join:内连接。

2.2自定义算子

和自己实现Source算子类似,这里给出一个简单的案例

public class FlatMapFunctionDemo implements FlatMapFunction<String, Tuple2<String, Integer>> {

    @Override
    public void flatMap(String line, Collector<Tuple2<String, Integer>> out) throws Exception {
        String[] fields = line.split(",");
        for (String word : fields) {
            out.collect(new Tuple2<String, Integer>(word, 1));
        }
    }
}

3.Sink算子

3.1常见的Sink算子

  • print() / printToErr():打印每个元素的toString()方法的值到标准输出或者标准错误输出流中
  • writeAsText()、writeAsCSV():写入文本或者CSV中
  • 扩展数据源:见Source算子

3.2自定义Sink算子

略,参考Source部分的定义,回头遇到合适的再补充。

4.共享变量

4.1广播变量

把一个dataset 数据集广播出去,然后不同的task在节点上都能够获取到,这个数据在每个节点上只会存在一份。如果不使用broadcast,则在每个节点中的每个task中都需要拷贝一份dataset数据集,比较浪费内存(也就是一个节点中可能会存在多份dataset数据)。

注意点

  • 广播出去的变量存在于每个节点的内存中,所以这个数据集不能太大。因为广播出去的数据,会常驻内存,除非程序执行结束。
  • 广播变量在初始化广播出去以后不支持修改,这样才能保证每个节点的数据都是一致的。

使用过程
1、初始化数据

DataSet<Integer> toBroadcast = env.fromElements(1, 2, 3)

2、广播数据

myDataSet.withBroadcastSet(toBroadcast, "broadCastMapName");

3、获取数据

Collection<Integer> broadcastSet = getRuntimeContext().getBroadcastVariable("broadcastSetName");

4.2累加器

Accumulator即累加器,与Mapreduce counter的应用场景差不多,都能很好地观察task在运行期间的数据变化,可以在Flink job任务中的算子函数中操作累加器,但是只能在任务执行结束之后才能获得累加器的最终结果

Counter是一个具体的累加器(Accumulator)实现,具体包括IntCounter, LongCounter 和 DoubleCounter

使用过程

  1. 创建累加器
private IntCounter numLines = new IntCounter();
  1. 注册累加器
getRuntimeContext().addAccumulator("num-lines", this.numLines);
  1. 使用累加器
this.numLines.add(1);
  1. 获取累加器的结果
myJobExecutionResult.getAccumulatorResult("num-lines")
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值