(hadoop-flink)=
# 与Hadoop集成

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

```bash
HADOOP_CONF_DIR=/path/to/etc/hadoop
```

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

```java
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`。

```bash
export HADOOP_CLASSPATH=`hadoop classpath`
```

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

```plaintext
/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版本自行编译生成依赖包。编译命令如下。

```bash
$ 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`中。

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