Flink 快速上手

我们将从一个小的应用实例开始,从设置Flink项目到在 IDE 或命令行上运行 Flink 流分析程序。

Wikipedia 提供了一个IRC频道,其中记录了对 Wiki 的所有编辑。Flink 程序读取此通道中实时数据,并计算 每个用户在给定时间窗口内编辑的字节数。这很容易使用 Flink 在几分钟内实现,但它将为您提供一个良好的基础,从而开始自己构建更复杂的分析程序。

设置 Maven 项目

要求是使用Maven 3.x 和 Java 8.x 安装。

我们将使用Flink Maven Archetype来创建项目结构。

Maven 创建项目

$ mvn archetype:generate \
    -DarchetypeGroupId=org.apache.flink \
    -DarchetypeArtifactId=flink-quickstart-java \
    -DarchetypeVersion=1.9.0 \
    -DgroupId=com.phlicode \
    -DartifactId=flink-tutorial \
    -Dversion=0.1 \
    -Dpackage=com.phlicode.wikiedits \
    -DinteractiveMode=false

您可以重新编辑 groupIdartifactIdversionpackage。使用上面的参数,Maven将创建一个如下所示的项目结构:

$ tree wikiedits
wikiedits
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── phlicode
        │           └── wikiedits
        │               ├── BatchJob.java
        │               └── StreamingJob.java
        └── resources
            └── log4j.properties

删除示例程序

我们的 pom.xml 文件已经在根目录中添加了 Flink 依赖项,并且有二个示例 Flink 程序(src/main/java/com/philcode/wikiedits)。可以删除示例程序,因为我们将从头开始:

$ rm wikiedits/src/main/java/com/philcode/wikiedits/*.java

设置 Flink 依赖项

需要将 Flink Wikipedia 连接器添加为依赖关系,以便可以在程序中使用它。编辑 pom.xml 文件的 dependencies 部分。

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients_${scala.binary.version}</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-connector-wikiedits_${scala.binary.version}</artifactId>
        <version>${flink.version}</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.7</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

注意:已添加好的 flink-connector-wikiedits_2.11 依赖项。(此示例和Wikipedia连接器的灵感来自 Apache Samza 的 Hello Samza 示例)

编写 Flink 程序

打开 IDEA 编辑器(推荐使用),并导入 Maven 项目,下载安装依赖包;

创建新文件 src/main/java/com/philcode/wikiedits/WikipediaAnalysis.java

package com.phlicode.wikiedits;

public class WikipediaAnalysis {

    public static void main(String[] args) throws Exception {

    }
}

  • 创建一个 StreamExecutionEnvironment(创建执行环境)
    这可用于设置执行参数并创建从外部系统读取的源,把它添加到 main 方法里。
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

  • 创建一个从 Wikipedia IRC 日志中读取的源(source)
    DataStream<WikipediaEditEvent> edits = env.addSource(new WikipediaEditsSource());

    这创建了一个可以进一步处理 **DataStream** 的 **WikipediaEditEvent 数据元**。
  • 通过 keyBy 创建键入流(KeySelector)(转换)

在我们的例子中,是确定每个用户在特定时间窗口中添加或删除的字节数,比如说五秒;窗口中编辑的字节数的总和,应该是每个唯一的用户;

首先必须指定我们要在用户名上键入流,也就是说此流上的算子操作应考虑用户名;

对于键入流,我们必须提供一个KeySelector。

    KeyedStream<WikipediaEditEvent, String> keyedEdits = edits
            .keyBy(new KeySelector<WikipediaEditEvent, String>() {
                @Override
                public String getKey(WikipediaEditEvent event) {
                    return event.getUser();
                }
            });

    这为我们提供了一个 WikipediaEditEvent 具有 String Key 的用户名。
  • 通过时间窗口计算每个用户编辑的字节数(转换)

在 KeyedStream 流上加上时间窗口,并根据这些窗口中的数据元计算结果;

窗口指定要在其上执行计算的 Stream 片;

在无限的数据元流上计算聚合时需要 Windows;

在我们的例子中,每五秒聚合一次每个用户所编辑的字节数总和。

    DataStream<Tuple2<String, Long>> result = keyedEdits
            .timeWindow(Time.seconds(5))
            .aggregate(new AggregateFunction<WikipediaEditEvent, Tuple2<String, Long>, Tuple2<String, Long>>() {
                @Override
                public Tuple2<String, Long> createAccumulator() {
                    return new Tuple2<>("", 0L);
                }

                @Override
                public Tuple2<String, Long> add(WikipediaEditEvent value, Tuple2<String, Long> accumulator) {
                    accumulator.f0 = value.getUser();
                    accumulator.f1  = value.getByteDiff();
                    return accumulator;
                }

                @Override
                public Tuple2<String, Long> getResult(Tuple2<String, Long> accumulator) {
                    return accumulator;
                }

                @Override
                public Tuple2<String, Long> merge(Tuple2<String, Long> a, Tuple2<String, Long> b) {
                    return new Tuple2<>(a.f0, a.f1   b.f1);
                }
            });

    第一个调用 **.timeWindow()** 指定有五秒钟的翻滚(非重叠)窗口。
    第二个调用 **.aggregate()** 为每个唯一键在每个窗口切片上指定一个聚合转换。
    在例子中,从初始值(“”,0L)开始,然后在该时间窗口内为用户添加每次编辑的字节差异。对于每个用户生成的 Stream 包含一个Tuple2<String,Long>,每五秒钟发出一次。
  • 将流打印到控制台(sink)
    result.print();

  • 执行 Flink 作业
    env.execute("flink stream job.");

    这是启动实际 Flink 作业所必需的。
    所有算子操作(例如创建源,转换和接收器)仅构建内部算子操作的图形。
    只有在execute()被调用时才会在集群上抛出或在本地计算机上执行此算子操作图。

完整的代码

package com.phlicode.wikiedits;

import org.apache.flink.api.common.functions.AggregateFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.connectors.wikiedits.WikipediaEditEvent;
import org.apache.flink.streaming.connectors.wikiedits.WikipediaEditsSource;

public class WikipediaAnalysis {

    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<WikipediaEditEvent> edits = env.addSource(new WikipediaEditsSource());

        KeyedStream<WikipediaEditEvent, String> keyedEdits = edits
                .keyBy(new KeySelector<WikipediaEditEvent, String>() {
                    @Override
                    public String getKey(WikipediaEditEvent event) {
                        return event.getUser();
                    }
                });

        DataStream<Tuple2<String, Long>> result = keyedEdits
                .timeWindow(Time.seconds(5))
                .aggregate(new AggregateFunction<WikipediaEditEvent, Tuple2<String, Long>, Tuple2<String, Long>>() {
                    @Override
                    public Tuple2<String, Long> createAccumulator() {
                        return new Tuple2<>("", 0L);
                    }

                    @Override
                    public Tuple2<String, Long> add(WikipediaEditEvent value, Tuple2<String, Long> accumulator) {
                        accumulator.f0 = value.getUser();
                        accumulator.f1  = value.getByteDiff();
                        return accumulator;
                    }

                    @Override
                    public Tuple2<String, Long> getResult(Tuple2<String, Long> accumulator) {
                        return accumulator;
                    }

                    @Override
                    public Tuple2<String, Long> merge(Tuple2<String, Long> a, Tuple2<String, Long> b) {
                        return new Tuple2<>(a.f0, a.f1   b.f1);
                    }
                });

        result.print();

        env.execute("flink stream job. ");
    }
}

运行 Flink 程序

可以使用 IDEA Run 或命令行上运行 Maven 命令,如下所示:

$ cd ${project_root}

# 构建项目
$ mvn clean package

# 执行主类
$ mvn exec:java -Dexec.mainClass=com.phlicode.wikiedits.WikipediaAnalysis

进入项目根目录下,执行 mvn 命令。

输出应该类似于:

1> (Richthes,2)
3> (WP 1.0 bot,8812)
4> (CaroleHenson,-30)
2> (Renerpho,201)
4> (Keenaz28,2)
3> (PiotruśW,-100)
1> (00:1700:C271:1100:9DF1:5E97:E734:6250,0)
3> (Toughpigs,1858)

来源: 海韵学社

作者: Bigo Lv

本文章著作权归作者所有,任何形式的转载都请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值