大數據系列(5)——hdfs的學習

1. hdfs(分佈式文件系統)

1.1 分佈式文件系統

數據集的大小超過一臺獨立的計算機的存儲能力時,就要經過網絡中的多個機器來存儲數據集,把管理網絡中多臺計算機組成的文件系統,稱爲分佈式文件系統java

1.2 hdfs的特色

  • 分佈式node

    • 數據量愈來愈多,在一個操做系統管轄的範圍存不下了,那麼就分配到更多的操做系統管理的磁盤中,可是不方便管理和維護,所以迫切須要一種系統來管理多臺機器上的文件,這就是分佈式文件管理系統 ,
  • 高可用shell

    • 副本機制
  • 通透性apache

    • 其實是經過網絡來訪問文件的動做,由程序與用戶看來,就像是訪問本地的磁盤通常

1.3 hdfs的體系架構

  • namenode瀏覽器

    • 名稱節點
    • 文件系統的管理節點
    • 維護着整個文件系統的文件目錄樹
    • 接收用戶的請求
  • datanode安全

    • 數據節點
    • 存儲block(一個block在hadoop1.x的版本中64mb,在hadoop2.x的版本中是128mb)

1.4 hdfs的設計

  • 流式數據的訪問服務器

    • 一次寫入屢次讀取
  • 商用硬件網絡

    • hadoop不須要運行在昂貴的商業機器上(ibm的小型機等),只須要普通的機器便可
  • 低時間延時的數據訪問架構

    • 要求幾十毫秒獲取響應結果的應用數據不能使用hdfs來存儲
    • 雖然hdfs不能解決低延遲的訪問,可是基於hdfs的hbase能解決延遲問題
  • 大量的小文件分佈式

    • 每一個文件在namenode中,存儲文件目錄信息,block信息,約佔150byte
    • hdfs不適合存儲小文件
  • 多用戶寫入,任意修改文件

    • 存儲在hdfs中的文件只能有一個寫入者(writer)
    • 只能在文件末尾追加數據,不能在任意位置修改文件

1.4 block的大小規劃

  • block: 數據塊

    • 大數據集存儲的基本單位
    • block在hadoop1.x的版本中64mb,在hadoop2.x的版本中是128mb
    • 爲何會有以上的設計

      • 硬盤有個尋址時間(10ms)
      • 尋址時間佔傳輸時間的1%
      • 硬盤的讀取速率通常爲100mb/s

1.5 secondary namenode

  • 合併edits與fsimage
  • 合併的時機

    • 3600s
    • 64mb

2. hdfs的操做

2.1 圖形化操做

2.2 shell操做

2.3 API操做

3. hdfs的操做(圖形界面)

3.1 hdfs的啓動流程

  1. 進入安全模式
  2. 加載fsimage
  3. 加載edits
  4. 保存檢查點(融合fsimage和edits文件,生成新的fsimage)
  5. 退出安全模式

3.2 經過瀏覽器訪問

http://namenode:50070

4. hdfs的操做(shell操做)

  • hdfs dfs
  • hadoop fs

5. hdfs的操做(API操做)

5.1 依賴POM

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.6.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.6.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs</artifactId>
    <version>2.6.4</version>
</dependency>

5.2 hdfs讀寫文件

import org.apache.commons.compress.utils.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.Test;
public class HdfsTest {
    /**
     * 寫文件操做
     */
    @Test
    public void testWriteFile() throws Exception {
        //建立配置對象
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://uplooking01:8020");
        //建立文件系統對象
        FileSystem fs = FileSystem.get(conf);
        Path path = new Path("/test002.txt");
        FSDataOutputStream fsDataOutputStream = fs.create(path, true);
        fsDataOutputStream.write("hello".getBytes());
        fsDataOutputStream.flush();
        fsDataOutputStream.close();
    }

    /**
     * 讀文件操做
     */
    @Test
    public void testReadFile() throws Exception {
        //建立配置對象
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://uplooking01:8020");
        //建立文件系統對象
        FileSystem fs = FileSystem.get(conf);
        Path path = new Path("/test002.txt");
        FSDataInputStream fsDataInputStream = fs.open(path);
        IOUtils.copy(fsDataInputStream, System.out);
    }


    /**
     * 上傳文件操做
     */
    @Test
    public void testuploadFile() throws Exception {
        //建立配置對象
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://uplooking01:8020");
        //建立文件系統對象
        FileSystem fs = FileSystem.get(conf);
        Path fromPath = new Path("file:///f:/test01.txt");
        Path toPath = new Path("/test01.txt");
        fs.copyFromLocalFile(false, fromPath, toPath);
    }

    /**
     * 下載文件操做
     */
    @Test
    public void testdownloadFile() throws Exception {
        //建立配置對象
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://uplooking01:8020");
        //建立文件系統對象
        FileSystem fs = FileSystem.get(conf);
        Path fromPath = new Path("/test01.txt");
        Path toPath = new Path("file:///f:/test01.txt");
        fs.copyToLocalFile(false, fromPath, toPath);
    }


    /**
     * 下載文件操做
     */
    @Test
    public void testOtherFile() throws Exception {
        //建立配置對象
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://uplooking01:8020");
        //建立文件系統對象
        FileSystem fs = FileSystem.get(conf);
//        BlockLocation[] blockLocations = fs.getFileBlockLocations(new Path("/test01.txt"), 0, 134217730);
//        System.out.println(blockLocations);
        FileStatus[] listStatus = fs.listStatus(new Path("/test01.txt"));
        System.out.println(listStatus);
    }
}

3. hdfs的高級操做

回滾edits: hdfs dfsadmin -rollEdits

進入安全模式: hdfs dfsadmin -safemode | enter | leave| get| wait

融合edits和fsimage: hdfs dfsadmin -saveNamespace:

查看fsimage: hdfs oiv -i -o -p

查看edits: hdfs oev -i -o -p

4. hdfs中的配額管理

  • 目錄配額

    • 設置目錄配額

      • hdfs dfsadmin -setQuota n dir
      • n:指的是目錄配額的個數,若是個數爲1,則不能存聽任何文件,若是爲2則只能放一個文件,以此類推.
    • 清除目錄配額

      • hdfs dfsadmin -clrQuota dir
  • 空間配額

    • 設置空間配額

      • hdfs dfsadmin -setSpaceQuota n dir

        • n:指空間的大小
    • 清除空間配額

      • hdfs dfsadmin -clrSpaceQuota dir

5. 獲取配置

hdfs getconf -confKey keyname

6. hadoop中的RPC

  • RPC(Remote Procedure Call)——遠程過程調用協議
  • 它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議
  • 設計目的:

    • 調用遠程的方法和調用本地方法同樣方便

6.1 編寫RPC服務端

定義協議

/**
 * 定義協議
 */
public interface IHelloService extends VersionedProtocol {
    public long versionID = 123456798L;//定義協議的版本
    public String sayHello(String name);//協議的具體條目
}

定義RPC的服務器實例類

/**
 * 實例類,實現了協議的類
 */
public class HelloServiceImpl implements IHelloService {
    @Override
    public String sayHello(String name) {
        System.out.println("==================" + name + "==================");
        return "hello" + name;
    }

    @Override
    public long getProtocolVersion(String protocol, long clientVersion) throws IOException {
        return versionID;
    }

    @Override
    public ProtocolSignature getProtocolSignature(String protocol, long clientVersion, int clientMethodsHash) throws IOException {
        return new ProtocolSignature();
    }
}

定義RPC程序的啓動程序

public class MyRpcServer {
    public static void main(String[] args) throws IOException {
        Configuration conf = new Configuration();
        RPC.Server server = new RPC.Builder(conf)
            .setBindAddress("172.16.4.3")//配置主機
            .setPort(8899)//配置端口
            .setProtocol(IHelloService.class)//配置協議
            .setInstance(new HelloServiceImpl())//配置實例,能夠配置多個
            .build();
        server.start();
        System.out.println("RPC服務器啓動成功....");
    }
}

6.2 編寫RPC客戶端

定義協議

/**
 * 定義協議
 */
public interface IHelloService extends VersionedProtocol {
    public long versionID = 123456798L;//定義協議的版本
    public String sayHello(String name);//協議的具體條目
}

定義客戶端啓動程序

Configuration conf = new Configuration();
ProtocolProxy<IHelloService> proxy = RPC.getProtocolProxy(IHelloService.class, IHelloService.versionID, new InetSocketAddress("172.16.4.3", 8899), conf);
IHelloService helloService = proxy.getProxy();
String ret = helloService.sayHello("xiaoming");
System.out.println(ret);

7. 獨立啓動namenode datanode

hadoop-daemon.sh start namenode

hadoop-daemon.sh start datanode

hadoop-daemon.sh start secondarynamenode

yarn-daemon.sh start resourcemanager

yarn-daemon.sh start nodemanager

8. 節點的服役和退役

  • 動態的添加節點,不須要中止整個集羣
  • hdfs中維護着一個白名單和一個黑名單

8.1 節點服役

==在namenode中操做==

hdfs-site.xm

<!-- 白名單-->
<property>
    <name>dfs.hosts</name>
    <value>/opt/hadoop/etc/hadoop/dfs.include</value>
</property>

建立白名單文件

/opt/hadoop/etc/hadoop/dfs.include

​ uplooking03

​ uplooking04

​ uplooking05

​ uplooking06

刷新節點:

hdfs dfsadmin -refreshNodes

8.1 節點退役

  • 從白名單移除
  • 添加到黑名單
  • 刷新節點
  • 從黑名單移除
  • 中止datanode進程
相關文章
相關標籤/搜索