每一个成功人士的背后,必定曾经做出过勇敢而又孤独的决定。
放弃不难,但坚持很酷~
今天将自己的程序部署到生产环境中,发现执行 hdfs 相关操作时报错了。原来是测试环境是 nameNode 单节点,生产环境上是 nameNode HA 。
自己写的 hdfs 连接不适配 nameNode HA 。就很烦躁,还得增加工作量来改代码。
以前的代码如下图所示:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.6.0-cdh5.11.0</version>
</dependency>
private static Configuration conf = new Configuration();
private static FileSystem fs;
/**
* 初始化 HDFS transportClient 连接
*/
public static void initConn() {
// 获取配置
try {
fs = FileSystem.get(URI.create("hdfs://cdh-master-1:8020"), conf, "hdfs");
} catch (Exception e) {
log.error("HDFS Client Configuration Initialization exception: ", e);
}
}
就这么简单,但如果环境是 nameNode HA 状况的话,当 nameNode 切换后,这种实现方式就可能会报错,那还得改代码。
基于以上代码,我又适配了 nameNode HA 状态的写法:
private static Configuration conf = new Configuration();
private static FileSystem fs;
/**
* 初始化 HDFS transportClient 连接
*/
public static void initConn() {
// 获取配置
conf.set("fs.defaultFS", "hdfs://nameservice1");
conf.set("dfs.nameservices", "nameservice1");
conf.set("dfs.ha.namenodes.nameservice1", "namenode6,namenode26");
conf.set("dfs.namenode.rpc-address.nameservice1.namenode6", "cdh-master-1:8020");
conf.set("dfs.namenode.rpc-address.nameservice1.namenode26", "cdh-master-2:8020");
conf.set("dfs.client.failover.proxy.provider.nameservice1",
"org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");
try {
fs = FileSystem.get(URI.create("hdfs://nameservice1"), conf, "hdfs");
} catch (Exception e) {
log.error("HDFS Client Configuration Initialization exception: ", e);
}
}
这样实现起来倒也不难,但也仅仅是适配于 nameNode HA 状态的写法。我们先来分析一下为什么要加这些配置。
这种方式如果用于 单nameNode 环境的话,也不行,也不适配。
那如何让它一步到位呢?
让项目直接加载 hdfs 相关配置文件就好啦。由于上面涉及到的配置在 hdfs-site.xml 和 core-site.xml 文件中,所以要加载这两个文件。然后代码如下:
private static Configuration conf = new Configuration();
private static FileSystem fs;
/**
* 初始化 HDFS transportClient 连接
*/
public static void initConn() {
// 获取配置
conf.addResource(new Path("hdfs-site.xml"));
conf.addResource(new Path("core-site.xml"));
try {
fs = FileSystem.get(conf);
} catch (Exception e) {
log.error("HDFS Client Configuration Initialization exception: ", e);
}
}
hdfs-site.xml 和 core-site.xml 文件可以通过 cdh-manager 页面来下载获取:
强烈建议用加载 hdfs 配置文件的方式,来实现对 HDFS 客户端的操作。如果还有用前一种 conf.set() 写法来获取 hdfs 客户端的话,建议赶紧改成 加载 hdfs 配置文件的方式,好用方便,适配性强