day36-s-hadoop-hdfs

day36-s-hadoop-hdfs

hadoop-hdfs

练习:输出文件和目录

package com.liuchao.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.net.URI;

public class Test01 {
    private FileSystem fs; // hdfs 文件系统对象
    private URI uri; // 统一资源标识符
    private Configuration conf; // hdfs 的配置文件对象
    private String user; // 用户
    // 获取连接
    @Before
    public void getConnect() {
        try {
            uri = new URI("hdfs://192.168.31.51:8020");
            conf = new Configuration();
            user = "atguigu";
            fs = FileSystem.get(uri, conf, user);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    // 关闭连接
    @After
    public void close() {
        if (fs != null) {
            try {
                fs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // 输出文件和文件夹
    // file:
    // directory:
    @Test
    public void printFileList() throws Exception {
       String dstPath="/";
       listAllFileAndDirectory(dstPath,fs);
    }

    public void listAllFileAndDirectory(String path, FileSystem fs) throws IOException {
        // 获取指定目录下的文件和文件夹
        FileStatus[] listStatus = fs.listStatus(new Path(path));
        // 迭代listStatus 是文件或数组
        for (FileStatus status : listStatus) {
            if(status.isFile()){
                // 是文件
                System.out.println("file: "+status.getPath().toString());
            }else{
                // 是目录
                String directory=status.getPath().toString();
                System.out.println("directory: "+directory);
                listAllFileAndDirectory(directory,fs);
            }
        }
    }
}

HDFS的数据流

HDFS写数据流程

  • 剖析文件写入

1. 客户端通过Distributed FileSystem 模块向NameNodw请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在
2. NameNode返回是否可以上传
3. 客户端请求第一个 Block上传到哪几个DataNode服务器上
4. NameNode 返回3个DataNode节点,分别为dn1、dn2、dn3
5、客户端通过FSDataOutputStream模块请求dn1 上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成
6、dn1、dn2、dn3逐级应答客户端
7、客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答
8. 当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器(重复执行3-7步)

网络拓扑-节点距离计算

机架感知(副本存储节点的选择)

HDFS的读数据流程

NameNode和SecondaryNameNode的工作机制

NameNode

1. NameNode元数据信息维护到哪里?内存?磁盘?
内存和磁盘都有。
	如果考虑数据的可靠性(数据不能随便就丢了),需要将元数据维护到磁盘。带来的问题是对磁盘的数据修改效率低。
	如果考虑数据访问和修改的效率,需要将元数据维护到内存中。带来的问题是数据不可靠。
	综合考虑:磁盘+内存,
2·磁盘 或 内存带来的问题?
如何保证内内存和磁盘数据的同步?
	改内存的时候,会去该磁盘

方案:在内存中维护元数据,且在磁盘中通过fsimage(镜像文件)来维护元数据,并且通过edits(编辑日志),文件记录对数据的修改操作,记录的方式为文件末尾追加操作。

3. edits文件中记录的操作越来越多怎么办?
	定时的将 fsImage文件和editis文件进行合并

4. 谁来做合并的是?
	通过SecondaryNameNode来帮助NameNode完成合并的事
	过程:当满足要合并的条件后以后,SecondaryNameNode会将NameNode中fsimage和当前正在使用的edits文件拉去过来,将fsimage和edits在SecondaryNameNode的内存中进行合并,合并完成生成一个新的fsImage文件,再将新的fsimage文件推送给NameNode替换NameNode的Fsimage文件。

其他

hdfs的路径问题:

路径问题:
	fs.copyFromLocalFile() 从本地复制文件到hdfs
hdfs路径:new Path("/input/abc.txt")
	"/input/abc.txt"不是完整的路径,完整的路径:hdfs://node1:8020/input/abc.txt

Linux网络问题:

前提:网络配置都正确,但是网路服务启动失败,导致xshell等连接失败
可能的原因是因为:NetworkManager服务冲突。因此将NetworkManager服务关掉并禁用。

通道正常运行,数据写入时,怎么保证数据在每台机器上的数据一致

ack 应答
如果 a 与 b 进行通信,怎么保证b接受到了a的信息?
	b 返回给 a 一个应答
posted @ 2022-04-24 09:00  黎白昼  阅读(21)  评论(0)    收藏  举报