DataStream API教程

在本指南中,我们将从头开始,从设置Flink项目到在Flink集群上运行流分析程序。

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

设置Maven项目

我们将使用Flink Maven Archetype来创建我们的项目结构,运行命令如下:

$ mvn archetype:generate \
    -DarchetypeGroupId=org.apache.flink \
    -DarchetypeArtifactId=flink-quickstart-java \
    -DarchetypeCatalog=https://repository.apache.org/content/repositories/snapshots/ \
    -DarchetypeVersion=1.7-SNAPSHOT \
    -DgroupId=wiki-edits \
    -DartifactId=wiki-edits \
    -Dversion=0.1 \
    -Dpackage=wikiedits \
    -DinteractiveMode=false

可以编辑groupId,artifactId而package如果你喜欢。使用上面的参数,Maven将创建一个如下所示的项目结构:

$ tree wiki-edits
wiki-edits/
├── pom.xml
└── src
    └── main
        ├── java
        │   └── wikiedits
        │       ├── BatchJob.java
        │       ├── SocketTextStreamWordCount.java
        │       ├── StreamingJob.java
        │       └── WordCount.java
        └── resources
            └── log4j.properties

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

$ rm wiki-edits/src/main/java/wikiedits/*.java

作为最后一步,我们需要将Flink Wikipedia连接器添加为依赖关系,以便我们可以在我们的程序中使用它。编辑它的dependencies部分pom.xml,使它看起来像这样:

<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_2.11</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients_2.11</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-connector-wikiedits_2.11</artifactId>
        <version>${flink.version}</version>
    </dependency>
</dependencies>


注意flink-connector-wikiedits_2.11添加的依赖项。

编写Flink程序

这是编码时间。启动您喜欢的IDE并导入Maven项目或打开文本编辑器并创建文件src/main/java/wikiedits/WikipediaAnalysis.java:

package wikiedits;

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

Flink程序的第一步是创建一个StreamExecutionEnvironment (或者ExecutionEnvironment如果您正在编写批处理作业)。这可用于设置执行参数并创建从外部系统读取的源。所以让我们继续把它添加到main方法:

StreamExecutionEnvironment see = StreamExecutionEnvironment.getExecutionEnvironment();

接下来,我们将创建一个从Wikipedia IRC日志中读取的源:

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

这创建了一个我们可以进一步处理DataStream的WikipediaEditEvent数据元。出于本示例的目的,我们感兴趣的是确定每个用户在特定时间窗口中添加或删除的字节数,比如说五秒。为此,我们首先必须指定我们要在用户名上键入流,也就是说此流上的 算子操作应考虑用户名。在我们的例子中,窗口中编辑的字节的总和应该是每个唯一的用户。对于键入流,我们必须提供一个KeySelector,如下所示:

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

这为我们提供了一个WikipediaEditEvent具有StringKeys的用户名。我们现在可以指定我们希望在此流上加上窗口,并根据这些窗口中的数据元计算结果。窗口指定要在其上执行计算的Stream片。在无限的数据元流上计算聚合时需要Windows。在我们的例子中,我们将说我们想要每五秒聚合一次编辑的字节总和:

DataStream<Tuple2<String, Long>> result = keyedEdits
    .timeWindow(Time.seconds(5))
    .fold(new Tuple2<>("", 0L), new FoldFunction<WikipediaEditEvent, Tuple2<String, Long>>() {
        @Override
        public Tuple2<String, Long> fold(Tuple2<String, Long> acc, WikipediaEditEvent event) {
            acc.f0 = event.getUser();
            acc.f1 += event.getByteDiff();
            return acc;
        }
    });

第一个调用,.timeWindow()指定我们想要有五秒钟的翻滚(非重叠)窗口。第二个调用为每个唯一键指定每个窗口切片的折叠变换。在我们的例子中,我们从一个初始值开始,("", 0L)并在其中为用户添加该时间窗口中每个编辑的字节差异。生成的Stream现在包含Tuple2<String, Long>每五秒钟发出一次的用户。

剩下要做的就是将流打印到控制台并开始执行:

result.print();
see.execute();

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

到目前为止完整的代码是这样的:

package wikiedits;

import org.apache.flink.api.common.functions.FoldFunction;
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 see = StreamExecutionEnvironment.getExecutionEnvironment();

    DataStream<WikipediaEditEvent> edits = see.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))
      .fold(new Tuple2<>("", 0L), new FoldFunction<WikipediaEditEvent, Tuple2<String, Long>>() {
        @Override
        public Tuple2<String, Long> fold(Tuple2<String, Long> acc, WikipediaEditEvent event) {
          acc.f0 = event.getUser();
          acc.f1 += event.getByteDiff();
          return acc;
        }
      });
    result.print();
    see.execute();
  }
}

您可以使用Maven在IDE或命令行上运行此示例:

$ mvn clean package
$ mvn exec:java -Dexec.mainClass=wikiedits.WikipediaAnalysis

第一个命令构建我们的项目,第二个命令执行我们的主类。输出应该类似于:

1> (Fenix down,114)
6> (AnomieBOT,155)
8> (BD2412bot,-3690)
7> (IgnorantArmies,49)
3> (Ckh3111,69)
5> (Slade360,0)
7> (Narutolovehinata5,2195)
6> (Vuyisa2001,79)
4> (Ms Sarah Welch,269)
4> (KasparBot,-245)

每行前面的数字告诉您输出生成的打印接收器的哪个并行实例。

这应该让您开始编写自己的Flink程序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值