4、hdfs api使用

weixin_33866037發表於2018-07-23

一、hadoop開發環境準備

1、user library:
  把%HADOOP_HOME%\share\hadoop目錄下的common,hdfs,mapreduce,tools,yarn目錄下和各自的lib目錄下的jar包copy到一個hadoop-lib下面,作為user library。在build path中新增hadoop2.6.5的lib包,包含121個jar包。

2、安裝hadoop eclipse外掛
2.1、複製hadoop-eclipse-plugin-2.6.0.jar到eclipse的plugins資料夾下,啟動eclipse。
2.2、發現在window-preference裡有Hadoop Map/Deduce選項,配置hadoop的安裝目錄
2.3、window--perspective--open perspective--Map/Reduce
2.4、在Map/Reduce裡新建一個location,取消勾選User M/R Master host,設定host為node01,Port為8020
2.5、在Map/Reduce檢視下,左側會出現DFS Locations下可以管理hdfs目錄。

3、本地開發環境搭建
3.1、複製叢集中的配置檔案core-site.xml,hdfs-site.xml到eclipse的conf目錄下
3.2、把conf目錄設定到build path中,因為專案中需要讀取配置檔案,獲知NameNode在哪個節點上。

二、測試操作hdfs

1、建立連線
2、關閉連線
3、在叢集上建立目錄
4、上傳本地檔案到叢集的指定目錄

public class TestHDFS {
    Configuration conf = null;
    FileSystem fs = null;
    
    // 建立連線
    @Before
    public void conn() throws IOException {
        conf = new Configuration(true);
        fs = FileSystem.get(conf);
    }
    
    // 關閉連線
    @After
    public void close() throws IOException {
        fs.close();
    }
    
    // 如果/data存在,就刪除,然後建立
    @Test
    public void mkdir() throws Exception {
        Path path = new Path("/data/");
        if(fs.exists(path)) {
            fs.delete(path, true);
        }
        fs.mkdirs(path);
    }
    
    // 上傳一個本地檔案,重新命名為test.txt
    @Test
    public void upload() throws Exception {
        InputStream inputStream = new BufferedInputStream(new FileInputStream(new File("D:\\abc.txt")));
        Path path = new Path("/data/test.txt");
        OutputStream outputStream = fs.create(path);
        IOUtils.copyBytes(inputStream, outputStream, conf, true);
    }
}

5、檢視hdfs上block塊的資訊
5.1、生成一個100000行的檔案
for i in seq 100000 ;do echo "hello wxx $i">> test.txt ; done
5.2、上傳到hdfs,並指定一個block大小為1M,預設root使用者會上傳到/user/root目錄下。
hdfs dfs -D dfs.blocksize=1048576 -put test.txt
5.3、檢視列印結果
hdfs會暴露塊的位置資訊,從管理頁面(http://node01:50070)能看出,該檔案第一個塊在node02,node03上。第二個塊在node02,node04上。表明如果計算第一個塊可以在node02和node03上同時進行。

    @Test
    public void blks() throws Exception {
        Path p = new Path("/user/root/test.txt");
        FileStatus file = fs.getFileStatus(p);
        // 獲取檔案block塊資訊
        BlockLocation[] blks = fs.getFileBlockLocations(file, 0, file.getLen());
        for(BlockLocation blk : blks) {
            System.out.println(blk);
        }
        // 讀取檔案內容
        FSDataInputStream in = fs.open(p);
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        // 直接跳轉到第二個塊的開頭
        in.seek(1048576);
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
    }

6、總結hdfs對上層計算的支援
6.1、把計算移動到資料身邊,支援平行計算。
6.2、seek(): 計算移動到節點旁邊,對資料發起本地化讀取。

相關文章