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 自定義服務啓動成功後,依舊顯示停止狀態的解決方案


掃一掃,我們的故事就開始了。

如果這篇文章對你有所啓發,點贊、轉發都是一種支持!

另外公衆號改變了推送規則,大家看文章不要忘記點擊最下方的在看,點贊按鈕,這樣微信自動識別爲常看公衆號,否則很可能推送的文章可能淹沒在別的文章找不到,謝謝大家

讓我知道你在看

本文分享自微信公衆號 - 大數據實戰演練(gh_f942bfc92d26)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章