點擊上方藍色“大數據實戰演練”,選擇“設爲星標”或“置頂”
回覆“資源”領取獨家整理的學習資料!
每一個成功人士的背後,必定曾經做出過勇敢而又孤獨的決定。
放棄不難,但堅持很酷~
一、前言
今天將自己的程序部署到生產環境中,發現執行 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 配置文件的方式,好用方便,適配性強。
往期推薦
掃一掃,我們的故事就開始了。
如果這篇文章對你有所啓發,點贊、轉發都是一種支持!
另外公衆號改變了推送規則,大家看文章不要忘記點擊最下方的在看,點贊按鈕,這樣微信自動識別爲常看公衆號,否則很可能推送的文章可能淹沒在別的文章找不到,謝謝大家
讓我知道你在看
本文分享自微信公衆號 - 大數據實戰演練(gh_f942bfc92d26)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。