Hadoop 学习 第二章 HDFS

第1章 HDFS概述

1.1 HDFS产出背景及定义

在这里插入图片描述

1.2 HDFS优缺点

在这里插入图片描述
在这里插入图片描述
对于小文件 不适合存储 无论是几个G 还是几兆 在namenode都要占据15个字节的容量。

1.3 HDFS组成架构

在这里插入图片描述
在这里插入图片描述
默认切成128兆

1.4 HDFS文件块大小(面试重点)

在这里插入图片描述
块的大小跟磁盘的传输速率有关,机械硬盘 传输速率慢一些,一般128M, 固态传输快,块256M。
在这里插入图片描述
在这里插入图片描述

第2章 HDFS的Shell操作(开发重点)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1 常用命令实操

(0)启动Hadoop集群(方便后续的测试)

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

(1)-help:输出这个命令参数

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -help rm

(2)-ls: 显示目录信息

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -ls /

(3)-mkdir:在HDFS上创建目录

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir -p /sanguo/shuguo

(4)-moveFromLocal:从本地剪切粘贴到HDFS

[atguigu@hadoop102 hadoop-2.7.2]$ touch kongming.txt
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs  -moveFromLocal  ./kongming.txt  /sanguo/shuguo

(5)-appendToFile:追加一个文件到已经存在的文件末尾

[atguigu@hadoop102 hadoop-2.7.2]$ touch liubei.txt
[atguigu@hadoop102 hadoop-2.7.2]$ vi liubei.txt
输入
san gu mao lu
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -appendToFile liubei.txt /sanguo/shuguo/kongming.txt

(6)-cat:显示文件内容

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cat /sanguo/shuguo/kongming.txt

(7)-chgrp 、-chmod、-chown:Linux文件系统中的用法一样,修改文件所属权限

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs  -chmod  666  /sanguo/shuguo/kongming.txt
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs  -chown  atguigu:atguigu   /sanguo/shuguo/kongming.txt

(8)-copyFromLocal:从本地文件系统中拷贝文件到HDFS路径去

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -copyFromLocal README.txt /

(9)-copyToLocal:从HDFS拷贝到本地

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -copyToLocal /sanguo/shuguo/kongming.txt ./

(10)-cp :从HDFS的一个路径拷贝到HDFS的另一个路径

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cp /sanguo/shuguo/kongming.txt /zhuge.txt

(11)-mv:在HDFS目录中移动文件

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mv /zhuge.txt /sanguo/shuguo/

(12)-get:等同于copyToLocal,就是从HDFS下载文件到本地

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -get /sanguo/shuguo/kongming.txt ./

(13)-getmerge:合并下载多个文件,比如HDFS的目录 /user/atguigu/test下有多个文件:log.1, log.2,log.3,…

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -getmerge /user/atguigu/test/* ./zaiyiqi.txt

(14)-put:等同于copyFromLocal

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -put ./zaiyiqi.txt /user/atguigu/test/

(15)-tail:显示一个文件的末尾

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -tail /sanguo/shuguo/kongming.txt

(16)-rm:删除文件或文件夹

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -rm /user/atguigu/test/jinlian2.txt

(17)-rmdir:删除空目录

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir /test
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -rmdir /test

(18)-du统计文件夹的大小信息

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -du -s -h /user/atguigu/test
2.7 K  /user/atguigu/test

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -du  -h /user/atguigu/test
1.3 K  /user/atguigu/test/README.txt
15     /user/atguigu/test/jinlian.txt
1.4 K  /user/atguigu/test/zaiyiqi.txt

(19)-setrep:设置HDFS中文件的副本数量

[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -setrep 10 /sanguo/shuguo/kongming.txt

在这里插入图片描述
这里设置的副本数只是记录在NameNode的元数据中,是否真的会有这么多副本,还得看DataNode的数量。因为目前只有3台设备,最多也就3个副本,只有节点数的增加到10台时,副本数才能达到10。

第3章 HDFS客户端操作(开发重点)

3.1 HDFS客户端环境准备

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.创建一个Maven工程HdfsClientDemo

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.导入相应的依赖坐标+日志添加

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.8.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-common</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-client</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-hdfs</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>jdk.tools</groupId>
			<artifactId>jdk.tools</artifactId>
			<version>1.8</version>
			<scope>system</scope>
			<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
		</dependency>
</dependencies>

在这里插入图片描述

然后保存

6.创建包名:com.atguigu.hdfs
在这里插入图片描述
创建包:
在这里插入图片描述
7.创建HdfsClient类
在这里插入图片描述
需要在项目的src/main/resources目录下,新建一个文件,命名为“log4j.properties”,在文件中填入:

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

在这里插入图片描述
在这里插入图片描述

package com.BW.hdfs;


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

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;



public class HDFSClient {
	public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
		
		Configuration conf =new Configuration();
		//FileSystem fs =FileSystem.get(conf));
		FileSystem fs=FileSystem.get(new URI("hdfs://192.168.186.102:9000"), conf, "BW");
		fs.mkdirs(new Path("/0529/dashen/"));
		
		fs.close();
		System.out.print("over");
		
		
	}

}

成功:!!!
在这里插入图片描述
注意:第一次尝试总是报一个JDK包无法找到的错误,要修改jdk1.8版本,并且还要检查JAVA_HOME的环境变量才行。
Maven相关设置请看Maven视频教程。
然后还要在eclipse修改jdk1.8版本
最后还要检查JAVA_HOME的环境变量。
在这里插入图片描述

3.2 HDFS的API操作

3.2.1 HDFS文件上传(测试参数优先级)

1.编写源代码

@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {

		// 1 获取文件系统
		Configuration configuration = new Configuration();
		configuration.set("dfs.replication", "2");
		FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");

		// 2 上传文件
		fs.copyFromLocalFile(new Path("e:/banzhang.txt"), new Path("/banzhang.txt"));

		// 3 关闭资源
		fs.close();

		System.out.println("over");
}

在这里插入图片描述
2.将hdfs-site.xml拷贝到项目的根目录下

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
	<property>
		<name>dfs.replication</name>
        <value>1</value>
	</property>
</configuration>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.2.2 HDFS文件下载

 @Test
public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{

		// 1 获取文件系统
		Configuration configuration = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
		
		// 2 执行下载操作
		// boolean delSrc 指是否将原文件删除
		// Path src 指要下载的文件路径
		// Path dst 指将文件下载到的路径
		// boolean useRawLocalFileSystem 是否开启文件校验
		fs.copyToLocalFile(false, new Path("/banzhang.txt"), new Path("e:/banhua.txt"), true);
		
		// 3 关闭资源
		fs.close();
}

在这里插入图片描述

3.2.3 HDFS文件夹删除

在这里插入图片描述

@Test
public void testDelete() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://192.168.186.102:9000"), configuration, "atguigu");
		
	// 2 执行删除
	fs.delete(new Path("/0508/"), true);
		
	// 3 关闭资源
	fs.close();
}

3.2.4 HDFS文件名更改

在这里插入图片描述

@Test
public void testRename() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu"); 
		
	// 2 修改文件名称
	fs.rename(new Path("/banzhang.txt"), new Path("/banhua.txt"));
		
	// 3 关闭资源
	fs.close();
}

3.2.5 HDFS文件详情查看

查看文件名称、权限、长度、块信息

@Test
public void testListFiles() throws IOException, InterruptedException, URISyntaxException{

	// 1获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu"); 
		
	// 2 获取文件详情
	RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
		
	while(listFiles.hasNext()){
		LocatedFileStatus status = listFiles.next();
			
		// 输出详情
		// 文件名称
		System.out.println(status.getPath().getName());
		// 长度
		System.out.println(status.getLen());
		// 权限
		System.out.println(status.getPermission());
		// 分组
		System.out.println(status.getGroup());
			
		// 获取存储的块信息
		BlockLocation[] blockLocations = status.getBlockLocations();
			
		for (BlockLocation blockLocation : blockLocations) {
				
			// 获取块存储的主机节点
			String[] hosts = blockLocation.getHosts();
				
			for (String host : hosts) {
				System.out.println(host);
			}
		}
			
		System.out.println("-----------班长的分割线----------");
	}

// 3 关闭资源
fs.close();
}

3.2.6 HDFS文件和文件夹判断

在这里插入图片描述

@Test
public void testListStatus() throws IOException, InterruptedException, URISyntaxException{
		
	// 1 获取文件配置信息
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
		
	// 2 判断是文件还是文件夹
	FileStatus[] listStatus = fs.listStatus(new Path("/"));
		
	for (FileStatus fileStatus : listStatus) {
		
		// 如果是文件
		if (fileStatus.isFile()) {
				System.out.println("f:"+fileStatus.getPath().getName());
			}else {
				System.out.println("d:"+fileStatus.getPath().getName());
			}
		}
		
	// 3 关闭资源
	fs.close();
}

3.3 HDFS的I/O流操作

有一个输入流和一个输出流,输入流是从外部读取文件,比如从数据库读取。输出流是写入到HDFS中。
fs管的是输出流。
需求:把本地e盘上的banhua.txt文件上传到HDFS根目录
在这里插入图片描述

3.3.1 HDFS文件上传

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

@Test
public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException {

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");

	// 2 创建输入流
	FileInputStream fis = new FileInputStream(new File("e:/banhua.txt"));

	// 3 获取输出流
	FSDataOutputStream fos = fs.create(new Path("/banhua.txt"));

	// 4 流对拷
	IOUtils.copyBytes(fis, fos, configuration);

	// 5 关闭资源
	IOUtils.closeStream(fos);
	IOUtils.closeStream(fis);
    fs.close();
}

3.3.2 HDFS文件下载

1.需求:从HDFS上下载banhua.txt文件到本地e盘上
// 文件下载

@Test
public void getFileFromHDFS() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
		
	// 2 获取输入流
	FSDataInputStream fis = fs.open(new Path("/banhua.txt"));
		
	// 3 获取输出流
	FileOutputStream fos = new FileOutputStream(new File("e:/banhua.txt"));
		
	// 4 流的对拷
	IOUtils.copyBytes(fis, fos, configuration);
		
	// 5 关闭资源
	IOUtils.closeStream(fos);
	IOUtils.closeStream(fis);
	fs.close();
}

3.3.3 定位文件读取

1.需求:分块读取HDFS上的大文件,比如根目录下的/hadoop-2.7.2.tar.gz
(1)下载第一块

@Test
public void readFileSeek1() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
		
	// 2 获取输入流
	FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));
		
	// 3 创建输出流
	FileOutputStream fos = new FileOutputStream(new File("e:/hadoop-2.7.2.tar.gz.part1"));
		
	// 4 流的拷贝
	byte[] buf = new byte[1024];
		
	for(int i =0 ; i < 1024 * 128; i++){
		fis.read(buf);
		fos.write(buf);
	}
		
	// 5关闭资源
	IOUtils.closeStream(fis);
	IOUtils.closeStream(fos);
fs.close();
}

(2)下载第二块

@Test
public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{

	// 1 获取文件系统
	Configuration configuration = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9000"), configuration, "atguigu");
		
	// 2 打开输入流
	FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));
		
	// 3 定位输入数据位置
	fis.seek(1024*1024*128);
		
	// 4 创建输出流
	FileOutputStream fos = new FileOutputStream(new File("e:/hadoop-2.7.2.tar.gz.part2"));
		
	// 5 流的对拷
	IOUtils.copyBytes(fis, fos, configuration);
		
	// 6 关闭资源
	IOUtils.closeStream(fis);
	IOUtils.closeStream(fos);
}

在这里插入图片描述

第4章 HDFS的数据流(面试重点)

4.1 HDFS写数据流程

4.1.1 剖析文件写入

在这里插入图片描述
1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,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步)

如何判断上传到哪个节点?:

第一:跟节点的距离 离谁最近,优先传到那里。
第二:根据负载情况。

7:实际就是IO流操作,先将packet传到内存 然后将packet序列化到本地,然后传下一个节点,然后都写完了,会一一返回应答(都写完了),然后立刻将内存中的数据都清除掉。

4.1.2 网络拓扑-节点距离计算

在HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接收数据。那么这个最近距离怎么计算呢?
节点距离:两个节点到达最近的共同祖先的距离总和。
在这里插入图片描述
彩色的方块可以看做交换机,黄色的是各机架的共同祖先,橘色的两个集群的共同祖先。

例如,假设有数据中心d1机架r1中的节点n1。该节点可以表示为/d1/r1/n1。利用这种标记,这里给出四种距离描述,如图3-9所示。
大家算一算每两个节点之间的距离,如图3-10所示。
在这里插入图片描述

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

在这里插入图片描述
2. Hadoop2.7.2副本节点选择

在这里插入图片描述

4.2 HDFS读数据流程(面试重点)

在这里插入图片描述

1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。

2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。

3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。

4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

第5章 NameNode和SecondaryNameNode(面试开发重点)

5.1 NN和2NN工作机制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:namenode内存是128G,secondarynamenode也是128G 所以一般不放到一个节点上,如果都放在一个节点上,每个分64G 性能会降低。
磁盘的内容加编辑日志的内容合并就是内存中的内容。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
namenode 中的元数据存放位置。此外还有secondarynamenode:

5.2 Fsimage和Edits解析

在这里插入图片描述

2. oiv查看Fsimage文件

(1)查看oiv和oev命令

[atguigu@hadoop102 current]$ hdfs
oiv            apply the offline fsimage viewer to an fsimage
oev            apply the offline edits viewer to an edits file

(2)基本语法

hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径

(3)案例实操

[atguigu@hadoop102 current]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current

[atguigu@hadoop102 current]$ hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-2.7.2/fsimage.xml

[atguigu@hadoop102 current]$ cat /opt/module/hadoop-2.7.2/fsimage.xml

将显示的xml文件内容拷贝到Eclipse中创建的xml文件中,并格式化。部分显示结果如下。

<inode>
	<id>16386</id>
	<type>DIRECTORY</type>
	<name>user</name>
	<mtime>1512722284477</mtime>
	<permission>atguigu:supergroup:rwxr-xr-x</permission>
	<nsquota>-1</nsquota>
	<dsquota>-1</dsquota>
</inode>
<inode>
	<id>16387</id>
	<type>DIRECTORY</type>
	<name>atguigu</name>
	<mtime>1512790549080</mtime>
	<permission>atguigu:supergroup:rwxr-xr-x</permission>
	<nsquota>-1</nsquota>
	<dsquota>-1</dsquota>
</inode>
<inode>
	<id>16389</id>
	<type>FILE</type>
	<name>wc.input</name>
	<replication>3</replication>
	<mtime>1512722322219</mtime>
	<atime>1512722321610</atime>
	<perferredBlockSize>134217728</perferredBlockSize>
	<permission>atguigu:supergroup:rw-r--r--</permission>
	<blocks>
		<block>
			<id>1073741825</id>
			<genstamp>1001</genstamp>
			<numBytes>59</numBytes>
		</block>
	</blocks>
</inode >

在这里插入图片描述

3. oev查看Edits文件

(1)基本语法

hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径

(2)案例实操

[atguigu@hadoop102 current]$ hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-2.7.2/edits.xml

[atguigu@hadoop102 current]$ cat /opt/module/hadoop-2.7.2/edits.xml

将显示的xml文件内容拷贝到Eclipse中创建的xml文件中,并格式化。显示结果如下。

<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
	<EDITS_VERSION>-63</EDITS_VERSION>
	<RECORD>
		<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
		<DATA>
			<TXID>129</TXID>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_ADD</OPCODE>
		<DATA>
			<TXID>130</TXID>
			<LENGTH>0</LENGTH>
			<INODEID>16407</INODEID>
			<PATH>/hello7.txt</PATH>
			<REPLICATION>2</REPLICATION>
			<MTIME>1512943607866</MTIME>
			<ATIME>1512943607866</ATIME>
			<BLOCKSIZE>134217728</BLOCKSIZE>
			<CLIENT_NAME>DFSClient_NONMAPREDUCE_-1544295051_1</CLIENT_NAME>
			<CLIENT_MACHINE>192.168.1.5</CLIENT_MACHINE>
			<OVERWRITE>true</OVERWRITE>
			<PERMISSION_STATUS>
				<USERNAME>atguigu</USERNAME>
				<GROUPNAME>supergroup</GROUPNAME>
				<MODE>420</MODE>
			</PERMISSION_STATUS>
			<RPC_CLIENTID>908eafd4-9aec-4288-96f1-e8011d181561</RPC_CLIENTID>
			<RPC_CALLID>0</RPC_CALLID>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
		<DATA>
			<TXID>131</TXID>
			<BLOCK_ID>1073741839</BLOCK_ID>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
		<DATA>
			<TXID>132</TXID>
			<GENSTAMPV2>1016</GENSTAMPV2>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_ADD_BLOCK</OPCODE>
		<DATA>
			<TXID>133</TXID>
			<PATH>/hello7.txt</PATH>
			<BLOCK>
				<BLOCK_ID>1073741839</BLOCK_ID>
				<NUM_BYTES>0</NUM_BYTES>
				<GENSTAMP>1016</GENSTAMP>
			</BLOCK>
			<RPC_CLIENTID></RPC_CLIENTID>
			<RPC_CALLID>-2</RPC_CALLID>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_CLOSE</OPCODE>
		<DATA>
			<TXID>134</TXID>
			<LENGTH>0</LENGTH>
			<INODEID>0</INODEID>
			<PATH>/hello7.txt</PATH>
			<REPLICATION>2</REPLICATION>
			<MTIME>1512943608761</MTIME>
			<ATIME>1512943607866</ATIME>
			<BLOCKSIZE>134217728</BLOCKSIZE>
			<CLIENT_NAME></CLIENT_NAME>
			<CLIENT_MACHINE></CLIENT_MACHINE>
			<OVERWRITE>false</OVERWRITE>
			<BLOCK>
				<BLOCK_ID>1073741839</BLOCK_ID>
				<NUM_BYTES>25</NUM_BYTES>
				<GENSTAMP>1016</GENSTAMP>
			</BLOCK>
			<PERMISSION_STATUS>
				<USERNAME>atguigu</USERNAME>
				<GROUPNAME>supergroup</GROUPNAME>
				<MODE>420</MODE>
			</PERMISSION_STATUS>
		</DATA>
	</RECORD>
</EDITS >

思考:NameNode如何确定下次开机启动的时候合并哪些Edits?有一个seemtext_id

5.3 CheckPoint时间设置

(1)通常情况下,SecondaryNameNode每隔一小时执行一次。

[hdfs-default.xml]

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
</property>

(2)一分钟检查一次操作次数,3当操作次数达到1百万时,SecondaryNameNode执行一次。

<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
<description>操作动作次数</description>
</property>

<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
<description> 1分钟检查一次操作次数</description>
</property >

5.4 NameNode故障处理

在这里插入图片描述
在这里插入图片描述

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

在这里插入图片描述

[atguigu@hadoop102 dfs]$ scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/

在这里插入图片描述

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

在这里插入图片描述

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>120</value>
</property>

<property>
  <name>dfs.namenode.name.dir</name>
  <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>

在这里插入图片描述

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

在这里插入图片描述

[atguigu@hadoop102 dfs]$ scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./

[atguigu@hadoop102 namesecondary]$ rm -rf in_use.lock

[atguigu@hadoop102 dfs]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs

[atguigu@hadoop102 dfs]$ ls
data  name  namesecondary

在这里插入图片描述

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint

在这里插入图片描述

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

5.5 集群安全模式

在这里插入图片描述
在这里插入图片描述
安全模式不能向HDFS进行写操作。

5.6 NameNode多目录配置

  1. NameNode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性
  2. 具体配置如下
    (1)在hdfs-site.xml文件中增加如下内容,添加之前先删除
    在这里插入图片描述
    然后再添加:
<property>
    <name>dfs.namenode.name.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
</property>

然后再分发:
在这里插入图片描述

(2)停止集群,删除data和logs中所有数据。

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf data/ logs/
[atguigu@hadoop103 hadoop-2.7.2]$ rm -rf data/ logs/
[atguigu@hadoop104 hadoop-2.7.2]$ rm -rf data/ logs/

(3)格式化集群并启动。

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs namenode –format
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh

(4)查看结果

[atguigu@hadoop102 dfs]$ ll
总用量 12
drwx------. 3 atguigu atguigu 4096 1211 08:03 data
drwxrwxr-x. 3 atguigu atguigu 4096 1211 08:03 name1
drwxrwxr-x. 3 atguigu atguigu 4096 1211 08:03 name2

在这里插入图片描述

第6章 DataNode(面试开发重点)

6.1 DataNode工作机制

在这里插入图片描述

1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。

2)DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息。

3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。

4)集群运行中可以安全加入和退出一些机器。

6.2 数据完整性

在这里插入图片描述
在这里插入图片描述

6.3 掉线时限参数设置

在这里插入图片描述
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒。:

<property>
    <name>dfs.namenode.heartbeat.recheck-interval</name>
    <value>300000</value>
</property>
<property>
    <name>dfs.heartbeat.interval</name>
    <value>3</value>
</property>

6.4 服役新数据节点

  1. 需求
    随着公司业务的增长,数据量越来越大,原有的数据节点的容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的数据节点。
  2. 环境准备
    (1)在hadoop104主机上再克隆一台hadoop105主机
    (2)修改IP地址和主机名称
    (3)删除原来HDFS文件系统留存的文件(/opt/module/hadoop-2.7.2/data和log)
    (4)source一下配置文件
[atguigu@hadoop105 hadoop-2.7.2]$ source /etc/profile
  1. 服役新节点具体步骤
    (1)直接启动DataNode,即可关联到集群
[atguigu@hadoop105 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start datanode
[atguigu@hadoop105 hadoop-2.7.2]$ sbin/yarn-daemon.sh start nodemanager

几个需要注意的问题:

  1. 假设服役一个107新节点 在102 的/etc/hosts 里需要配置主机名和IP地址的映射。
  2. 如果下次直接启动:107还是不能群起 还要配置slaves 加上107, 同时设置107的ssh免密登录,最后用xnyc 分发下配置文件。

(2)在hadoop105上上传文件

[atguigu@hadoop105 hadoop-2.7.2]$ hadoop fs -put /opt/module/hadoop-2.7.2/LICENSE.txt /

在这里插入图片描述
105一定有 在105客户端上传,节点距离最近。

(3)如果数据不均衡,可以用命令实现集群的再平衡

[atguigu@hadoop102 sbin]$ ./start-balancer.sh
starting balancer, logging to /opt/module/hadoop-2.7.2/logs/hadoop-atguigu-balancer-hadoop102.out
Time Stamp  Iteration#  Bytes Already Moved  Bytes Left To Move  Bytes Being Moved

带来的危险:如果知道namenode 知道IP地址 按照配置起来 启动起来 就可以把数据download下来了。

6.5 退役旧数据节点

6.5.1 添加白名单

之前添加节点的方式不安全,利用白名单解决安全问题:
添加到白名单的主机节点,都允许访问NameNode,不在白名单的主机节点,都会被退出。
配置白名单的具体步骤如下:
(1)在NameNode的/opt/module/hadoop-2.7.2/etc/hadoop目录下创建dfs.hosts文件

[atguigu@hadoop102 hadoop]$ pwd
/opt/module/hadoop-2.7.2/etc/hadoop
[atguigu@hadoop102 hadoop]$ touch dfs.hosts
[atguigu@hadoop102 hadoop]$ vi dfs.hosts

添加如下主机名称(不添加hadoop105)

hadoop102
hadoop103
hadoop104

(2)在NameNode的hdfs-site.xml配置文件中增加dfs.hosts属性

<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
</property>

(3)配置文件分发

[atguigu@hadoop102 hadoop]$ xsync hdfs-site.xml

刷新之前,105还在:
在这里插入图片描述
(4)刷新NameNode

[atguigu@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes
Refresh nodes successful

在这里插入图片描述
105瞬间下线。但是之前用105上传的文件还有。
在这里插入图片描述
(5)更新ResourceManager节点

[atguigu@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes
17/06/24 14:17:11 INFO client.RMProxy: Connecting to ResourceManager at hadoop103/192.168.1.103:8033

(6)在web浏览器上查看
在这里插入图片描述

  1. 如果数据不均衡,可以用命令实现集群的再平衡
    假设退役一个节点,那么数据可能需要拷贝到另外的节点上,导致某些节点负载较大,所以需要重新平衡节点。
[atguigu@hadoop102 sbin]$ ./start-balancer.sh

starting balancer, logging to /opt/module/hadoop-2.7.2/logs/hadoop-atguigu-balancer-hadoop102.out
Time Stamp    Iteration#  Bytes Already Moved  Bytes Left To Move  Bytes Being Moved

6.5.2 黑名单退役

在黑名单上面的主机都会被强制退出。

[atguigu@hadoop102 hadoop]$ pwd
/opt/module/hadoop-2.7.2/etc/hadoop
[atguigu@hadoop102 hadoop]$ touch dfs.hosts.exclude
[atguigu@hadoop102 hadoop]$ vi dfs.hosts.exclude

首先恢复现场,将105重新启动:
在NameNode的hdfs-site.xml配置文件中**删除** dfs.hosts属性

<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
</property>

然后将配置文件分发

[atguigu@hadoop102 hadoop]$ xsync hdfs-site.xml
[atguigu@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes
Refresh nodes successful

[atguigu@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes
17/06/24 14:55:56 INFO client.RMProxy: Connecting to ResourceManager at hadoop103/192.168.1.103:8033

在这里插入图片描述
然后将105datanode启动:
在这里插入图片描述

在这里插入图片描述

成功:
在这里插入图片描述
下面开始黑名单操作:

  1. 在NameNode的/opt/module/hadoop-2.7.2/etc/hadoop目录下创建dfs.hosts.exclude文件
[atguigu@hadoop102 hadoop]$ pwd
/opt/module/hadoop-2.7.2/etc/hadoop
[atguigu@hadoop102 hadoop]$ touch dfs.hosts.exclude
[atguigu@hadoop102 hadoop]$ vi dfs.hosts.exclude

添加如下主机名称(要退役的节点)

hadoop105
  1. 在NameNode的hdfs-site.xml配置文件中增加dfs.hosts.exclude属性
<property>
<name>dfs.hosts.exclude</name>
      <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>
</property>

然后进行分发:
在这里插入图片描述

  1. 刷新NameNode、刷新ResourceManager
[atguigu@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes

Refresh nodes successful


[atguigu@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes

17/06/24 14:55:56 INFO client.RMProxy: Connecting to ResourceManager at hadoop103/192.168.1.103:8033
  1. 检查Web浏览器,退役节点的状态为decommission in progress(退役中),说明数据节点正在复制块到其他节点,如图3-17所示
    在这里插入图片描述
    之前105上传的数据传给了别的节点。
    在这里插入图片描述

  2. 等待退役节点状态为decommissioned(所有块已经复制完成),停止该节点及节点资源管理器。注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役,如图3-18所示
    在这里插入图片描述

然后手动将105的datanode和nodemanager退出:

[atguigu@hadoop105 hadoop-2.7.2]$ sbin/hadoop-daemon.sh stop datanode

stopping datanode

[atguigu@hadoop105 hadoop-2.7.2]$ sbin/yarn-daemon.sh stop nodemanager

stopping nodemanager
  1. 如果数据不均衡,可以用命令实现集群的再平衡
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-balancer.sh 

starting balancer, logging to /opt/module/hadoop-2.7.2/logs/hadoop-atguigu-balancer-hadoop102.out
Time Stamp    Iteration#  Bytes Already Moved  Bytes Left To Move  Bytes Being Moved

注意:不允许白名单和黑名单中同时出现同一个主机名称。

6.6 Datanode多目录配置

namenode中的多目录备份的数据是一模一样的,

  1. DataNode也可以配置成多个目录,每个目录存储的数据不一样。即:数据不是副本
  2. 具体配置如下

在这里插入图片描述
将以下删除:namenode 的多目录和 黑名单设置在这里插入图片描述
然后将以下添加

<property>
        <name>dfs.datanode.data.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2</value>
</property>

然后分发配置文件:
在这里插入图片描述
配置好后 退出所有的进程:
在这里插入图片描述在这里插入图片描述
然后在102 103 104上都删除数据:
在这里插入图片描述
然后格式化namenode:
在这里插入图片描述
随后开始重新启动:
在这里插入图片描述
发现多了目录:
在这里插入图片描述
随后传入一个数据:
在这里插入图片描述
发现:
data2没有数据 data1有数据:
在这里插入图片描述
在这里插入图片描述
发现不通过目录存放的数据不一样,只是多个目录,但是不会备份数据。

第7章 HDFS 2.X新特性

7.1 集群间数据拷贝

在这里插入图片描述

7.2 小文件存档

在这里插入图片描述
首先将进程都启动 dfs yarn

把/user/atguigu/input目录里面的所有文件归档成一个叫input.har的归档文件,并把归档后文件存储到/user/atguigu/output路径下。

创建三个小文件:
在这里插入图片描述
在这里插入图片描述
然后进行归档:
在这里插入图片描述
在这里插入图片描述
对外是一个整体,对内是一个个的文件,这样减少了namenode内存的压力。
har:// 算是一种har 协议 类似于hdfs://
所以要用har协议解析har文件。
在这里插入图片描述

7.3 回收站

开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。
在这里插入图片描述

2.启用回收站
修改core-site.xml,配置垃圾回收时间为1分钟。

<property>
   <name>fs.trash.interval</name>
<value>1</value>
</property>

在这里插入图片描述
3. 查看回收站
回收站在集群中的路径:/user/atguigu/.Trash/….
4. 修改访问垃圾回收站用户名称
进入垃圾回收站用户名称,默认是dr.who,修改为atguigu用户
[core-site.xml]

<property>
  <name>hadoop.http.staticuser.user</name>
  <value>atguigu</value>
</property>
  1. 通过程序删除的文件不会经过回收站,需要调用moveToTrash()才进入回收站
    Trash trash = New Trash(conf);
    trash.moveToTrash(path);
  2. 恢复回收站数据
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mv
/user/atguigu/.Trash/Current/user/atguigu/input    /user/atguigu/input
  1. 清空回收站
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -expunge

然后分发一下:
在这里插入图片描述
然后删一个文件:
在这里插入图片描述
在这里插入图片描述
然后这个文件在回收站存活的时间是1分钟 如果超过时间 则回收站删除这个文件
按照时间戳生成一个包
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值