Java api 远程访问 HDFS HA 通用写法总结,说实话,我之前就是前一种写法的那种人,笑哭~...

点击上方蓝色“大数据实战演练”,选择“设为星标”或“置顶”

回复“资源”领取独家整理的学习资料!

每一个成功人士的背后,必定曾经做出过勇敢而又孤独的决定。

放弃不难,但坚持很酷~

一、前言

今天将自己的程序部署到生产环境中,发现执行 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 的写法

基于以上代码,我又适配了 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 状态的写法。我们先来分析一下为什么要加这些配置。

  • fs.defaultFS:客户端连接 HDFS 时,默认的路径前缀。如果配置了 nameNode HA 的话,这里的值就为:hdfs://[nameservice id] 。

  • dfs.nameservices   命名空间的逻辑名称。

  • dfs.ha.namenodes.[nameservice id]   命名空间中所有 nameNode 的唯一标示名称。可以配置多个,使用逗号分隔。该名称可以让 dataNode 知道每个集群的所有 nameNode 。

  • dfs.namenode.rpc-address.[nameservice id].[namenode name]:HDFS Client访问HDFS,就是通过 RPC 实现的,代表每个 nameNode 监听的 RPC 地址。

  • dfs.client.failover.proxy.provider.[nameservice id]:配置 HDFS 客户端连接到 Active NameNode 的一个 java 类。

这种方式如果用于 单nameNode 环境的话,也不行,也不适配。

三、通过加载 hdfs 配置文件,适配单/双 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 配置文件的方式,好用方便,适配性强

欢迎大家留言讨论

???? ???? ????

往期推荐

HDFS ACL权限设置

HDFS NFS Gateway配置使用说明

终于!Ambari 自定义服务集成系列视频来了!!!

都快2020年了,ambari自定义服务集成,你还没掌握吗?文末有福利

Ambari 自定义服务启动成功后,依旧显示停止状态的解决方案

扫一扫,我们的故事就开始了。

如果这篇文章对你有所启发,点赞、转发都是一种支持!

另外公众号改变了推送规则,大家看文章不要忘记点击最下方的在看,点赞按钮,这样微信自动识别为常看公众号,否则很可能推送的文章可能淹没在别的文章找不到,谢谢大家

让我知道你在看

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

create17

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值