Hadoop(二)HDFS体系结构与操作方式(命令行与JavaAPI)


Hadoop安装好启动后,通过JPS命令可以查看到底启动了哪些守护进程。
在这里插入图片描述

HDFS体系结构

首先我们要知道Hadoop有两个核心,HDFS的体系结构由三部分组成

  • HDFS(Hadoop Distributed System)分布式文件系统,主要负责Hadoop上的文件存储
  • MapReduce 是一个分布式计算框架,核心理念是将任务切分处理,再聚合归纳

NameNode (主节点)

  1. 主要职责:
    管理数据块的元信息和操作日志
    NameNode负责管理HDFS上文件的元信息,包括文件基本信息、数据块信息、数据冗余信息。
    NameNode会负责记录HDFS的操作日志。

    负责接收客户端命令,包括上传、下载等操作
    HDFS的操作命令都是先发送到NameNode,由NameNode进行查询分析后,将任务需要的元信息返回到客户端,客户端根据返回的元信息再去指定的DataNode进行数据操作。

    负责监听数据节点是否正常工作,并保证数据的健康状态
    NameNode会定时监听DataNode的心跳信息,NameNode会根据反馈的Block信息来确定数据块的备份情况。假如一定时间后没有监听到某个DataNode的心跳信息,会判定该DataNode已宕机。NameNode会根据数据块元信息去进行数据的备份,保证数据块的冗余度。

  2. HDFS操作日志 :edits文件
    日志存放地址:hadoop配置的目录/dfs/name/current,日志格式为 edits*,最新日志为:edits_inprogress*
    日志格式为二进制文件,可以用HDFS自带的转化工具转化成可读格式:
    hdfs oev -i edits_inprogress_0000000000000000005 -o ~/a.xml

  3. HDFS元信息:fsimage文件
    存放地址与日志存放地址相同,文件格式为:fsimage* 也是二进制文件,查看方式为
    hdfs oiv -i fsimage_0000000000000000004 -o ~/test.txt
    hdfs oiv -i fsimage_0000000000000000004 -o ~/test.xml -p XML

DateNode(从节点)

  • 主要职责:
    保存数据块
    1.X的版本 数据块默认大小为64M, 2.X的版本 默认大小为128M
    保存位置可通过 find . -name blk* 找到

      **定时反馈Block信息给NameNode**
    

SecondaryNameNode

主要职责为:
将日志与元信息合并,合并可分为下面几步:

  1. 将所有的日志文件和最新的元信息加载到本地内存中
  2. 将日志文件和元信息合并成一个新的.check文件,与此同时产生的新日志保存的edits_inprogress中
  3. 将.check文件上传到NameNode下,并重命名成元信息格式,将合并时产生的日志保存成正常日志格式

合并发生的时机:当HDFS触发检查点的时候,检查点触发有两种情况
1. 时间:默认为60分钟触发一次,配置参数:fs.check.period
2. 大小:日志文件大小>64M,配置参数:fs.check.size

HDFS命令行操作

如果以后忘记了可以使用hdfs dfs 回车查看到所有命令
在这里插入图片描述

常用操作命令

命令语法:hdfs dfs ,其实有很多命令和Linux的命令相同如mkdir、ls、rm等,不同的如下:

命令说明举例
-ls -R (-lsr)列出hdfs下的所有目录和文件hdfs dfs -ls -r / 将会列出 / 目录下的所有文件
-put上传文件或从键盘输入到hdfs中hdfs dfs -put aaa.txt / 将本地aaa.txt文件上传到HDFS的/ 目录下 hdfs dfs -put - /bbb.text 将从键 盘输入内容到/bbb.text
-moveFromLocal上传文件到hdfs 并删除本地文件hdfs dfs -moveFromLocal aaa.txt / 本地文件会被删除
-get与put命令相反,从hdfs下载数据到本地hdfs dfs -get /aaa.txt /root/test 下载到test目录下
-getmerge将一个目录下的文件内容合并后下载,如果文件存在则会覆盖hdfs dfs -getmerge /data/input /root/merge.txt 将/data/input下的文件合并到本地/root/merge.txt文件中
-count统计一个目录下的文件信息hdfs dfs -count / 会显示 / 下面的目录个数 文件个数 文件大小 输入路径
-balancer该命令重新在DataNode中均匀分布数据块,以防止某些DataNode保存数据过多,访问压力过大hdfs dfs -balancer

管理命令

管理命令语法为:hdfs dfsadmin

命令说明举例
-report展示HDFS的基本情况,和用浏览器看到的信息相同hdfs dfsadmin -report
-safemode操作HDFS的安全模式,可查看,进入,离开hdfs dfsadmin -safemode enter,leave ,get ,wait

JavaAPI操作HDFS

Jar包准备

从安装Hadoop上下载开发JavaAPI需要的Jar包,一共需要这四个路径下的jar
$HADOOP_HOME/share/hadoop/common/.jar
$HADOOP_HOME/share/hadoop/common/lib/
.jar
$HADOOP_HOME/share/hadoop/hdfs/.jar
$HADOOP_HOME/share/hadoop/hdfs/lib/
.jar

操作权限解决

当我们通过JavaAPI 操作 HDFS上的数据时,会出现没有权限的提示,一共有如下四种方法解决

  1. 配置Hadoop的配置文件hdfs-site.xml的dfs.permissions值为false
  2. 配置操作用户为有权限的用户,程序第一行输入System.setProperty(“HADOOP_USER_NAME”,“ROOT”);
  3. 在运行程序时添加运行参数:-DHADOOP_USER_NAME=ROOT
  4. 使用hdfs dfs -chmod 777 / 修改权限

JavaAPI操作

1.在HDFS上创建目录

@Test
public void testMkdir() throws IOException {
	Configuration conf = new Configuration();
	//配置NameNode访问地址
	conf.set("fs.defaultFS", "hdfs://192.168.159.111:9000");
	
	//创建一个操作客户端
	FileSystem client = FileSystem.get(conf);
	
	client.mkdirs(new Path("/folder1"));
	
	client.close();
}

2.上传文件到HDFS

有个疑问,通过API上传的文件,即使是在伪分布环境配置了副本数为1,实际查看时副本数显示为3

@Test
	public void testUpload() throws IOException {
		Configuration conf = new Configuration();
		//配置NameNode访问地址
		conf.set("fs.defaultFS", "hdfs://192.168.159.111:9000");
		//创建一个操作客户端
		FileSystem client = FileSystem.get(conf);
		
		//创建一个输入流,本地文件
		InputStream in = new FileInputStream(new File("D:\\BaiduNetdiskDownload\\大数据\\hadoop-2.7.3.tar.gz"));
		//创建一个输出流,hdfs上的路径
		OutputStream out = client.create(new Path("/tools/a.zip"));
		IOUtils.copyBytes(in, out, 1024);
		client.close();
	}

3.从HDFS下载文件到本地

@Test
public void testDown() throws IOException {
	Configuration conf = new Configuration();
	//配置NameNode访问地址
	conf.set("fs.defaultFS", "hdfs://192.168.159.111:9000");
	//创建一个操作客户端
	FileSystem client = FileSystem.get(conf);
	
	//创建一个输入流,从hdfs读取数据
	InputStream in = client.open(new Path("/tools/a.zip"));
	//创建一个输出流,保存到本地
	OutputStream out = new FileOutputStream(new File("D:\\BaiduNetdiskDownload\\a.zip"));
	IOUtils.copyBytes(in, out, 1024);
	client.close();
}

4.查看目录以及文件信息

@Test
	public void testLook() throws IOException {
		Configuration conf = new Configuration();
		//配置NameNode访问地址
		conf.set("fs.defaultFS", "hdfs://192.168.159.111:9000");
		//创建一个操作客户端
		FileSystem client = FileSystem.get(conf);
		FileStatus[] status = client.listStatus(new Path("/tools"));
		for(FileStatus s:status) {
			System.out.println("是否目录  "+s.isDirectory());
			System.out.println("文件名: "+s.getPath().getName());
			System.out.println("路径: "+s.getPath());
			System.out.println("创建时间: "+s.getAccessTime());
			System.out.println("块大小: "+s.getBlockSize());
			System.out.println("工作组: "+s.getGroup());
			System.out.println("文件大小: "+s.getLen());
			System.out.println("修改时间: "+s.getModificationTime());
			System.out.println("所有者: "+s.getOwner());
			System.out.println("操作权限: "+s.getPermission());
			System.out.println("副本数: "+s.getReplication());
			System.out.println("============================================");
		}
		
		client.close();
	}

5.获取HDFS上某个文件的数据块信息

@Test
	public void testBlock() throws IOException {
		Configuration conf = new Configuration();
		//配置NameNode访问地址
		conf.set("fs.defaultFS", "hdfs://192.168.159.111:9000");
		//创建一个操作客户端
		FileSystem client = FileSystem.get(conf);
		//获取文件信息
		FileStatus status = client.getFileStatus(new Path("/tools/a.zip"));
		//获取数据块信息
		BlockLocation[] blocks = client.getFileBlockLocations(status, 0, status.getLen());
		for(BlockLocation block:blocks) {
			System.out.println(Arrays.toString(block.getHosts()) + "===" + Arrays.toString(block.getNames()));
		}
		client.close();
	}

6.获取HDFS的DataNode的信息

@Test
	public void testDataNode() throws IOException {
		Configuration conf = new Configuration();
		//配置NameNode访问地址
		conf.set("fs.defaultFS", "hdfs://192.168.159.111:9000");
		//创建一个操作客户端
		DistributedFileSystem client = (DistributedFileSystem) FileSystem.get(conf);
		DatanodeInfo[] infos = client.getDataNodeStats();
		for(DatanodeInfo info : infos) {
			System.out.println(info.getHostName() + "\t" + info.getName());
		}
		client.close();
	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值