Java大数据之路--HDFS详解(5)--执行流程及API操作

HDFS(分布式文件存储系统)--执行流程及API操作

目录

HDFS(分布式文件存储系统)--执行流程及API操作

流程

一、读取流程/下载

二、写入流程/上传

三、删除流程

API操作

一、准备步骤

二、API操作


流程

一、读取流程/下载

  1. 客户端发起RPC请求到NameNode
  2. NameNode在接收到请求之后会进行校验:
    1. 校验指定路径是否存在
    2. 校验文件是否有存在
  3. 如果文件存在,NameNode就会读取元数据,同时给客户端一个信号
  4. 客户端就会向NameNode要第一个Block的地址
  5. NameNode在收到请求之后会读取元数据,然后将第一个Block的地址放入队列中给客户端
  6. 默认一个Block是三个地址(3副本),客户端收到队列之后选择一个较的节点来读取第一个Blcok,读取完成之后,会对这个Block进行checksum的验证;如果校验失败,客户端给NameNode一个信号,然后重新选取地址重新读取;如果校验成功,客户端就会向NameNode要第二个Block的地址,重复4,5,6三个过程。
  7. 客户端读取完所有的Block之后,会给NameNode一个结束信号,NameNode在收到信号之后会关闭文件

二、写入流程/上传

  1. 客户端发起RPC请求到NameNode
  2. NameNode在接收到请求之后会进行校验:
    1. 校验指定路径是否存在
    2. 校验写入路径是否有权限
    3. 校验指定路径中是否有同名文件
  3. 如果校验失败,则抛出异常,如果校验成功,记录元数据,NameNode会给客户端一个信号。
  4. 客户端在收到信号之后会向NameNode要第一个Block的存储位置。
  5. NameNode在收到请求之后,会等待DataNode的心跳,选取DataNode的地址放入队列中返回给客户端。默认情况下,NameNode会选择3个地址。
  6. 客户端收到队列中的3个地址,从这些地址中选择一个较近(网络拓扑距离)的节点写入第一个Block的第一个副本。
  7. 第一个副本所在的节点会通过pipeline(管道,实际就是NIO中的Channel)将第二个副本写到其他节点上,第二个副本所在节点在写到第三个副本。
  8. 写完之后,第三个副本所在的节点会给第二个副本所在的节点返回ack,第二个副本所在的节点收到ack之后会给第一个副本所在的节点返回ack,第一个副本所在的节点在给客户端返回ack
  9. 写完第一个Block之后,客户端会和NameNode要第二个Block的存储位置,然后重复5,6,7,8过程。
  10. 当写完所有的Block之后,客户端会给NameNode一个结束信号,NameNode就会关闭文件/关流,关流之后,这个文件就不可修改。

三、删除流程

  1. 客户端发起的RPC请求到NameNode。

  2. NameNode在收到请求之后,会将这个请求记录到edits文件中,然后更新内存中的元数据,内存更新成功之后客户端会返回一个ack信号,此时这个文件对应的Block依然存储在DataNode

  3. 在NameNode收到DataNode的心跳的时候,NameNode就会检查Block信息,会给DataNode进行心跳响应,要求删除对应的Block。DataNode在收到心跳响应之后才会真正删除Block

API操作

吞吐量-----单位时间内节点或者集群读写的数据总量 1s读写100M --- 100M/s

高并发不一定是高吞吐的,但是高吞吐一般是高并发的

一、准备步骤

  1. 需要导入HDFS的依赖的jar包:

hadoop-2.7.1\share\hadoop\common\*.jar

hadoop-2.7.1\share\hadoop\common\lib\*.jar

hadoop-2.7.1\share\hadoop\hdfs\*.jar

hadoop-2.7.1\share\hadoop\hdfs\lib\*.jar

二、API操作

读取文件

@Test

public void testConnectNamenode() throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.21:9000"), conf);

    InputStream in=fs.open(new Path("/park/1.txt"));

    OutputStream out=new FileOutputStream("1.txt");

    IOUtils.copyBytes(in, out, conf);

}

 

上传文件

@Test

public void testPut() throws Exception{

    Configuration conf=new Configuration();

    conf.set("dfs.replication","1");

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.21:9000"),conf,"root");

    ByteArrayInputStream in=new ByteArrayInputStream("hello hdfs".getBytes());

    OutputStream out=fs.create(new Path("/park/2.txt"));

    IOUtils.copyBytes(in, out, conf);

}

 

删除文件

@Test

public void testDelete()throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.21:9000"),conf,"root");

    //true表示无论目录是否为空,都删除掉。可以删除指定的文件

    fs.delete(new Path("/park01"),true);

    //false表示只能删除不为空的目录。

    fs.delete(new Path("/park01"),false);

    fs.close();

}

 

在hdfs上创建文件夹

@Test

public void testMkdir()throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.21:9000"),conf,"root");

    fs.mkdirs(new Path("/park02"));

}

 

查询hdfs指定目录下的文件

@Test

public void testLs()throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.21:9000"),conf,"root");

    FileStatus[] ls=fs.listStatus(new Path("/"));

    for(FileStatus status:ls){

        System.out.println(status);

    }

}

 

递归查看指定目录下的文件

@Test

public void testLs()throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.214:9000"),conf,"root");

    RemoteIterator<LocatedFileStatus> rt=fs.listFiles(new Path("/"), true);

    while(rt.hasNext()){

        System.out.println(rt.next());

    }

}

 

重命名

@Test

public void testCreateNewFile() throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.176:9000"),conf,"root");

    fs.rename(new Path("/park"), new Path("/park01"));

}

 

获取文件的块信息

@Test

public void testCopyFromLoaclFileSystem() throws Exception{

    Configuration conf=new Configuration();

    FileSystem fs=FileSystem.get(new URI("hdfs://192.168.234.176:9000"),conf,"root");

    BlockLocation[] data=fs.getFileBlockLocations(new Path("/park01/1.txt"),0,Integer.MaxValue);

    for(BlockLocation bl:data){

        System.out.println(bl);

    }

}

还能用插件对hdfs来进行操作

猜你喜欢

转载自blog.csdn.net/a34651714/article/details/102821803