HFDS的搭建和基本使用

一、概述

  • 简介:
    • 源自Google的GFS论文的巨大分布式文件系统
  • 特点:
    1. 扩展性
    2. 容错性
    3. 海量数据存储
  • 优缺点:
    • 优点:
      1. 数据冗余, 硬件容错
      2. 处理流式(一次写入多次读取)的数据访问
      3. 适合存储大文件
      4. 构建在廉价机器上
    • 缺点:
      1. 不满足低延迟的数据访问
      2. 不适合小文件的存储
  • 存储:
    • 将文件切分成指定大小的数据块并以多副本的存储在多个机器上
    • 数据的切分,多副本,容错等操作对用户透明
      NameNode (Filename, numReplicas, block-ids)

二、架构

  • 简介:
    1. 一个Master(NameNode/NN)带N个Slaves(DataNode/DN)
    2. 一个文件会被拆分成多个Block, 默认blocksize:128M

2.1 NameNode

  1. 负责客户端请求的响应
  2. 负责元数据(文件的名称、副本系数、Block存放的DN)的管理

2.2 DataNode

  1. 存储用户的文件对应的数据块(Block)
  2. 要定期向NN发送心跳信息, 汇报本身及所有的block信息, 健康状况

2.3 副本机制

2.3.1 副本存放策略

2.3 HDFS文件读写流程

三、环境搭建

3.1 伪分布式

  1. jdk和ssh安装
  2. 免密登录配置:
    ssh-keygen -t rsa
    cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
    ssh localhost
  3. 下载解压
    tar -zxvf hadoop-x.x.x-cdhx.x.x -C ~/app
  4. 配置文件修改: hadoop_home/etc/hadoop
    • hadoop-env.sh配置: JAVA_HOME=/usr/lib/jvm/java-x.x
    • core-site.xml配置: 默认目录位于/tmp, 重启后会丢失
      <configuration>
      <property>
          <name>fs.defaultFS</name>
          <!-- 外网访问改成ip -->
          <value>hdfs://localhost:8020</value>
      </property>
      <property>
          <name>hadoop.tmp.dir</name>
          <value>/home/hadoop/app/tmp</value>
      </property>
      </configuration>
    • hdfs-site.xml配置:
      <configuration>
      <property>
          <name>dfs.replication</name>
          <value>1</value>
      </property>
      </configuration>
    • slavs配置(伪分布式不需要配置)
  5. 启动
    # 格式化文件系统, 仅第一次执行, 使用hdfs代替hadoop(depressed))
    ./bin/hdfs namenode -format
    # 启动NameNode, DataNode
    ./sbin/start-dfs.sh
    # 进程验证 DataNode SecondaryNameNode NameNode
    jps
    # 网页方式验证
    curl http://localhost:50070/
    # 防火墙添加规则
    # vim /etc/sysconfig/iptables
    -A INPUT -p tcp -m tcp --dport 50070 -j ACCEPT
  6. 停止: ./sbin/stop-dfs.sh

四、HDFS Shell操作

  • 配置hadoop/bin的环境变量
    # vi ~/.bashrc
    export HADOOP_HOME=/opt/apache/hadoop/hadoop-2.6.0-cdh5.7.0
    export PATH=$HADOOP_HOME/bin:$PATH
    # 使生效 
    source ~/.bashrc
  • 查看命令参数: hadoop fs

4.1 常用操作

  1. ls:
    # 查看根目录
    hadoop fs -ls /
    # 递归查看
    hadoop fs -ls -R /
  2. mkdir
    # 根目录创建test目录
    hadoop fs -mkdir /test
    # 递归创建目录
    hadoop fs -mkdir -p /test/a
  3. put: 将本地文件传到hdfs
    # 将hello.txt传到hdfs根目录
    hadoop fs -put hello.txt /
  4. get
    # 将hdfs中的/test/a/h.txt拷贝到本地
    hadoop fs -get /test/a/h.txt
  5. rm: 删除文件
    # 删除文件
    hadoop fs -rm /hello.txt
    # 递归删除
    hadoop fs -rm -R /test
  6. cat: 查看文件内容
    hadoop fs -cat /hello.txt
    # 也可以使用-text
    hadoop fs -text /hello.txt
  7. copyFromLocal: 从本地拷贝到hdfs
    # 将本地hello.txt文件拷贝到hdfs的/test/a目录下, 文件名为h.txt
    fs -copyFromLocal hello.txt /test/a/h.txt

五、Java API操作HDFS

  • 默认副本系数为3

5.1 步骤

  1. 添加依赖
    <properties>
    <cdh.version>2.6.0-cdh5.7.0</cdh.version>
    </properties>
    <repositories>
    <repository>
        <id>cloudera</id>
        <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
    </repository>
    </repositories>
    <dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>${cdh.version}</version>
    </dependency>
  2. 创建连接
    // 该路径为core-site.xml中配置
    public static final String HADOOP_PATH = "hdfs://192.168.33.12:8020";
    FileSystem fileSystem = null;
    Configuration configuration = null;
    configuration = new Configuration();
    // 指定用户为hadoop
    fileSystem = FileSystem.get(new URI(HADOOP_PATH), configuration, "hadoop");
    // 创建文件夹
    fileSystem.mkdirs(new Path("/hdfsapi/test"));
    //创建文件并写入内容
    FSDataOutputStream outputStream = fileSystem.create(new Path("/hdfsapi/test/a.txt"));
    outputStream.write("hello hdfs".getBytes());
    outputStream.flush();
    outputStream.close();
    //将内容输出到控制台
    FSDataInputStream inputStream = fileSystem.open(new Path("/hdfsapi/test/a.txt"));
    IOUtils.copyBytes(inputStream, System.out, 1024);   // IOUtils为hadoop.io包
    inputStream.close();
    // 重命名
    Path srcPath = new Path("/hdfsapi/test/a.txt");
    Path dstPath = new Path("/hdfsapi/test/b.txt");
    boolean rename = fileSystem.rename(srcPath, dstPath);
    System.out.println(rename);
    // 本地文件上传到hdfs
    Path localPath = new Path("E:\\WorkSpace\\data\\test.txt");
    Path hdfsPath = new Path("/hdfsapi/test");
    fileSystem.copyFromLocalFile(localPath, hdfsPath);
    //带进度的大文件上传
    InputStream inputStream = new BufferedInputStream(
        new FileInputStream(new File("E:\\WorkSpace\\Web\\bigFile"))
    );
    FSDataOutputStream fsDataOutputStream = fileSystem.create(new Path("/hdfsapi/test"), new Progressable() {
    @Override
    public void progress() {
        System.out.println(".");
    }
    });
    IOUtils.copyBytes(inputStream, fsDataOutputStream, 4096);
    // 下载文件
    Path localPath = new Path("E:\\WorkSpace\\b.txt");
    Path hdfsPath = new Path("/hdfsapi/test/b.txt");
    fileSystem.copyToLocalFile(hdfsPath, localPath);
    // 列出文件信息
    FileStatus[] listStatus = fileSystem.listStatus(new Path("/hdfsapi/test"));
    for (FileStatus status : listStatus) {
    String file = status.isDirectory() ? "文件夹" : "文件";
    short replication = status.getReplication();    //副本
    long len = status.getLen(); // 文件大小
    String path = status.getPath().toString();
    System.out.println(file + "\t" + replication + "\t" + len + "\t" + path);
    }
    //删除文件
    fileSystem.delete(new Path("/hdfsapi/test/a.txt"), true);

六、HDFS文件读写流程

6.1 存储数据

  • client(divide into blocks)->NameNode->DataNode

6.2 读取数据

  • client从NameNode获取元数据信息
  • client从DataNode请求数据

七、参考

标签: none

已有 2 条评论

  1. 期待能整理出更详细的写入流程~~

    1. 因工作中需要从零搭建大数据平台, 所以这篇是个quick start

添加新评论