9.5. 与Hadoop集成#

Flink可以和Hadoop生态圈的组件紧密结合,比如9.1节中提到,Flink可以使用YARN作为资源调度器,或者读取HDFS、HBase中的数据。在使用Hadoop前,我们需要确认已经安装了Hadoop,并配置了环境变量HADOOP_CONF_DIR,如下环境变量配置是Hadoop安装过程所必需的。

HADOOP_CONF_DIR=/path/to/etc/hadoop

此外,Flink与Hadoop集成时,需要将Hadoop的依赖包添加到Flink中,或者说让Flink能够获取到Hadoop类。比如,使用bin/yarn-session.sh启动一个Flink YARN Session时,如果没有设置Hadoop依赖,将会出现下面的报错。

java.lang.ClassNotFoundException: org.apache.hadoop.yarn.exceptions.YarnException

这是因为Flink源码中引用了Hadoop YARN的代码,但是在Flink官网提供的Flink下载包中,新版本的Flink已经不提供Hadoop集成,或者说,Hadoop相关依赖包不会放入Flink包中。Flink将Hadoop剔除的主要原因是Hadoop发布和构建的时间过长,不利于Flink的迭代。Flink鼓励用户自己根据需要引入Hadoop依赖包,具体有如下两种方式。

  1. 在环境变量中添加Hadoop Classpath,Flink从Hadoop Classpath中读取所需依赖包。

  2. 将所需的Hadoop 依赖包添加到Flink主目录下的lib目录中。

9.5.1 添加Hadoop Classpath#

Flink使用环境变量$HADOOP_CLASSPATH来存储Hadoop相关依赖包的路径,或者说,$HADOOP_CLASSPATH中的路径会添加到-classpath参数中。很多Hadoop发行版以及一些云环境默认情况下并不会设置这个变量,因此,执行Hadoop的各节点应该在其环境变量中设置$HADOOP_CLASSPATH

export HADOOP_CLASSPATH=`hadoop classpath`

上面的命令中,hadoop是Hadoop提供的二进制命令工具,使用前必须保证hadoop命令添加到了环境变量$PATH中,classpathhadoop命令的一个参数选项。hadoop classpath可以返回Hadoop所有相关的依赖包,将这些路径输出。如果在一台安装了Hadoop的节点上执行hadoop classpath,下面是部分返回结果。

/path/to/hadoop/etc/hadoop:/path/to/hadoop/share/hadoop/common/lib/*:/path/to/hadoop/share/hadoop/yarn/lib/*:...

Flink启动时,会从$HADOOP_CLASSPATH中寻找所需依赖包。这些依赖包来自节点所安装的Hadoop,也就是说Flink可以和已经安装的Hadoop紧密结合起来。但Hadoop的依赖错综复杂,Flink所需要的依赖和Hadoop提供的依赖有可能发生冲突。 该方式只需要设置$HADOOP_CLASSPATH,简单快捷,缺点是有依赖冲突的风险。

9.5.2 将Hadoop依赖包添加到lib目录中#

Flink主目录下有一个lib目录,专门存放各类第三方的依赖包。Flink程序启动时,会将lib目录加载到Classpath中。我们可以将所需的Hadoop 依赖包添加到lib目录中。具体有两种获取Hadoop 依赖包的方式:一种是从Flink官网下载预打包的Hadoop依赖包,一种是从源码编译。

Flink社区帮忙编译生成了常用Hadoop版本的Flink依赖包,比如Hadoop 2.8.3、Hadoop 2.7.5等,使用这些Hadoop版本的用户可以直接下载这些依赖包,并放置到lib目录中。例如,Hadoop 2.8.3的用户可以下载flink-shaded-Hadoop-2-uber-2.8.3-10.0.jar,将这个依赖包添加到Flink主目录下的lib目录中。

如果用户使用的Hadoop版本比较特殊,不在下载列表里,比如是Cloudera等厂商发行的Hadoop,用户需要自己下载flink-shaded工程源码,基于源码和自己的Hadoop版本自行编译生成依赖包。编译命令如下。

$ mvn clean install -Dhadoop.version=2.6.1

上面的命令编译了针对Hadoop 2.6.1的flink-shaded工程。编译完成后,将名为flink-shaded-hadoop-2-uber的依赖包添加到Flink主目录的lib目录中。 该方式没有依赖冲突的风险,但源码编译需要用户对Maven和Hadoop都有一定的了解。

9.5.3 本地调试#

9.5.1小节和9.5.2小节介绍的是针对Flink集群的Hadoop依赖设置方式,如果我们仅想在本地的IntelliJ IDEA里调试Flink Hadoop相关的程序,我们可以将下面的Maven依赖添加到pom.xml中。

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.8.3</version>
    <scope>provided</scope>
</dependency>