測試代碼
@Before
public void init() throws Exception {
conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://leader:9000");
conf.set("dfs.replication", "3");
fs = FileSystem.get(new URI("hdfs://leader:9000"), conf, "root");
}
@Test
public void testUpload() throws Exception {
fs.copyFromLocalFile(new Path("D:/111.txt"), new Path("/111.txt"));
fs.close();
}
原因一 本地環境問題
本地上傳需要本地環境,在Windows 下搭建對應的開發環境
- 在windows的某個目錄下解壓一個hadoop的安裝包
- 將安裝包下的lib和bin目錄用對應windows版本平臺編譯的本地庫替換
- 在window系統中配置HADOOP_HOME指向你解壓的安裝包
- 在windows系統的path變量中加入hadoop的bin目錄
- 重啓編譯器(編譯器啓動是會讀取啓動時的狀態)
原因二 多次 format 導致ID 不一致
- 停止集羣(切換到/sbin目錄下)
$./stop-all.sh
- 刪除在hdfs中配置的data目錄(即在core-site.xml中配置的hadoop.tmp.dir對應文件件)下面的所有數據;
$ rm -rf /home/hadoop/hdpdata/*
- 重新格式化namenode(切換到hadoop目錄下的bin目錄下)
hadoop namenode -format
- 重新啓動hadoop集羣
start-all.sh
在使用hadoop dfsadmin -report查看使用情況,結果如下圖所示:
原因三 無法連接公網的DataNode
- 問題描述
如果不是在本地虛擬機操作,在shell終端可以正常進行文件操作,但是在java客戶端,只能操作目錄,但是無法進行文件操作
- 問題原因
NameNode節點存放的是文件目錄,也就是文件夾、文件名稱,本地可以通過公網訪問NameNode,所以可以進行文件夾的創建,當上傳文件需要寫入數據到DataNode時,NameNode 和DataNode 是通過局域網進行通信,NameNode返回地址爲 DataNode 的私有 IP,本地無法訪問。
- 解決方案
返回的IP地址爲主機名,通過主機名host 文件進行映射
1:因爲本地配置會覆蓋服務器配置,所以直接在java客戶端修改,添加如下代碼
conf.set("dfs.client.use.datanode.hostname", "true");
或者在本地hdfs添加如下配置
2:配置本機的hosts文件 (文件目錄 C:\Windows\System32\drivers\etc)
- 最終代碼
@Before
public void init() throws Exception {
conf = new Configuration();
conf.set("dfs.client.use.datanode.hostname", "true");
conf.set("fs.defaultFS", "hdfs://leader:9000");
conf.set("dfs.replication", "1");
fs = FileSystem.get(new URI("hdfs://leader:9000"), conf, "root"); // 最後一個參數爲用戶名
}
@Test
public void testUpload() throws Exception {
fs.copyFromLocalFile(new Path("D:/111.txt"), new Path("/111.txt"));
fs.close();
}