1、HDFS的体系架构
2、NameNode的职责
3、DataNode的职责
4、SecondaryNameNode的职责
5、Yarn的体系架构和任务调度过程
6、Yan的资源分配方式
7、HBase的体系架构简介
8、操作HDFS
8.1、Web Console网页工具
(1)NameNode:端口50070
(2)SecondaryNameNode:端口50090
8.2、命令行
- 普通的操作命令:hdfs dfs ******
-mkdir 在HDFS中创建目录,如果父目录不存在,使用-p参数先创建父目录
hdfs dfs -mkdir /aaa
-ls 查询HDFS的某个目录
-ls -R 查询HDFS的某个目录,包含子目录
- 管理的命令:hdfs dfsadmin ******
8.3、Java API
包含的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
8.3.1使用JavaAPI创建HDFS目录
创建工程hdfsDemo,在工程根目录下创建lib目录,将上面的jar包导入拷贝到lib文件夹下,工程目录截图如下:
将lib加入到工程中,创建类DemoMkdir,代码如下:
package com.muze;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.junit.Test;
/**
* @author muze
* @version 1.0
* @date 2022/6/18 10:07
*/
public class DemoMkdir {
@Test
public void test1() throws Exception{
//指定NameNode地址
Configuration conf = new Configuration();
//注意改为你自己的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
//创建一个HDFS的客户端 DistributedFileSystem
FileSystem client = FileSystem.get(conf);
//创建目录
client.mkdirs(new Path("/folder1"));
//关闭客户端
client.close();
}
}
执行test方法,如果报如下错误:
Permission denied:user =***,access=WRITE,INODE="/folder1:root:supergroup:drwxr-xr-x",解决方案如下:
1、设置执行的用户是root用户,环境变量 HADOOP_USER_NAME 2、可以使用java的-D参数来设置环境变量 HADOOP_USER_NAME 3、使用命令chmod改变目录的权限 hdfs -chmod 777 /folder2 4、修改参数配置 /usr/local/hadoop-2.7.3/etc/hadoop 路径下hdfs-site.xml,增加如下内容 <property> <name>dfs.permissions</name> <value>fales</value> </property>
代码如下:
@Test
public void test2() throws Exception{
System.setProperty("HADOOP_USER_NAME","root");
//指定NameNode地址
Configuration conf = new Configuration();
//注意改为自己的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
//创建一个HDFS的客户端 DistributedFileSystem
FileSystem client = FileSystem.get(conf);
//创建目录
client.mkdirs(new Path("/folder1"));
//关闭客户端
client.close();
}
注意:可能汇报如下错误 :
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.SafeModeException): Cannot create file/folder1/b.tar.gz. Name node is in safe mode.
解决办法:
这是因为在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束。安全模式主要是为了系统启动的时候检查各个DataNode上数据块的有效性,同时根据策略必要的复制或者删除部分数据块。运行期通过命令也可以进入安全模式。在实践过程中,系统启动的时候去修改和删除文件也会有安全模式不允许修改的出错提示,只需要等待一会儿即可。
也可以通过如下命令手动离开安全模式:
bin/hadoop dfsadmin -safemode leave
//在bin下执行
//若配置环境变量,使用以下命令
hadoop dfsadmin -safemode leave
用户可以通过dfsadmin -safemode value 来操作安全模式,参数value的说明如下:
enter - 进入安全模式
leave - 强制NameNode离开安全模式
get - 返回安全模式是否开启的信息
wait - 等待,一直到安全模式结束。
8.3.2、使用JavaAPI上传和下载数据
- 使用javaAPI上传数据
代码如下:
@Test
public void test1() throws Exception {
System.setProperty("HADOOP_USER_NAME","root");
//构造一个输入流,代表要上传的数据
InputStream input = new FileInputStream("D:\\demo\\hadoop-2.7.3.tar.gz");
//指定NameNode地址
Configuration conf = new Configuration();
//注意ip改为自己服务器的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
//创建HDFS客户端
FileSystem client = FileSystem.get(conf);
//构造一个输出流,只想HDFS
OutputStream output = client.create(new Path("/folder1/a.tar.gz"));
//缓冲区
byte[] buffer = new byte[1024];
//长度
int len = 0;
while ((len = input.read(buffer)) > 0){
//写到输出流
output.write(buffer,0,len);
}
output.flush();
output.close();
input.close();
}
- 使用hadoop封装好的工具类使用javaAPI上传数据,代码如下:
@Test
public void test2() throws Exception {
System.setProperty("HADOOP_USER_NAME","root");
//构造一个输入流,代表要上传的数据
InputStream input = new FileInputStream("D:\\demo\\hadoop-2.7.3.tar.gz");
//指定NameNode地址
Configuration conf = new Configuration();
//ip改为自己的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
//创建HDFS客户端
FileSystem client = FileSystem.get(conf);
//构造一个输出流,只想HDFS
OutputStream output = client.create(new Path("/folder1/b.tar.gz"));
//利用hadoop.io工具类封装好的工具类进行上传数据
IOUtils.copyBytes(input,output,1024);
}
- 使用javaAPI下载数据
代码如下:
@Test
public void test1 () throws Exception{
OutputStream output = new FileOutputStream("D:\\demo\\x.tar.gz");
System.setProperty("HADOOP_USER_NAME","root");
//指定NameNode地址
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://152.136.208.154:9000");
//创建HDFS客户端
FileSystem client = FileSystem.get(conf);
//得到一个输入流
InputStream input = client.open(new Path("/folder2/c.tar.gz"));
//构造一个缓冲区
byte[] buffer = new byte[1024];
int len = 0;
while((len = input.read(buffer)) > 0 ){
output.write(buffer,0,len);
}
output.flush();
output.close();
input.close();
}
- 使用hadoop封装好的工具类使用javaAPI下载数据,代码如下:
@Test
public void test2 () throws Exception{
OutputStream output = new FileOutputStream("D:\\demo\\y.tar.gz");
System.setProperty("HADOOP_USER_NAME","root");
//指定NameNode地址
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://152.136.208.154:9000");
//创建HDFS客户端
FileSystem client = FileSystem.get(conf);
//得到一个输入流
InputStream input = client.open(new Path("/folder2/c.tar.gz"));
//使用工具类简化程序
IOUtils.copyBytes(input, output,1024);
}
8.3.3、使用JavaAPI获取HDFS的元信息
-
查找某个文件的数据块在HDFS的DataNode的位置
代码如下:
@Test
public void test1 () throws Exception{
System.setProperty("HADOOP_USER_NAME","root");
Configuration conf = new Configuration();
//注意ip改为自己的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
FileSystem client = FileSystem.get(conf);
//得到文件的状态
FileStatus status = client.getFileStatus(new Path("/folder2/d.tar.gz"));
//获取文件的数据块信息
BlockLocation[] list = client.getFileBlockLocations(status,0,status.getLen());
for (BlockLocation blk : list){
System.out.println("数据块:主机" + Arrays.toString(blk.getHosts()));
}
client.close();
}
- 查看HDFS的数据节点
代码如下:
@Test
public void test2() throws Exception{
System.setProperty("HADOOP_USER_NAME","root");
Configuration conf = new Configuration();
//注意ip改为自己服务器的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
//使用FileSystem的子类
DistributedFileSystem client = (DistributedFileSystem) FileSystem.get(conf);
//获取所有的数据节点
DatanodeInfo[] list = client.getDataNodeStats();
for (DatanodeInfo data : list){
System.out.println(data.getHostName());
}
client.close();
}
-
删除HDFS数据
代码如下:
public void test3() throws Exception {
System.setProperty("HADOOP_USER_NAME","root");
Configuration conf = new Configuration();
//注意ip改为自己服务器的ip
conf.set("fs.defaultFS","hdfs://ip:9000");
FileSystem client = FileSystem.get(conf);
//删除数据
//第二个参数false,是否使用递归
boolean flag = client.delete(new Path("/folder2/c.tar.gz"),false);
System.out.println(flag?"删除成功":"删除失败");
client.close();
}
9、HDFS的原理解析(重要)
9.1、数据上传的过程
9.2、数据下载的过程
10、HDFS的底层实现:
10.1、RPC(remote procedure call远程过程调用)
10.2、java的代理对象Proxy
11、HDFS的高级特性
11.1、回收站
- 默认回收站是关闭的,可以通过在core-site.xml中添加fs.trash.interval来打开配置时间阈值,例如;
- 删除文件时,其实是放入回收站 /trash
- 回收站里的文件可以快速恢复
- 可以设置一个时间阈值,当回收站里文件的存放时间超过这个阈值,就被彻底删除,并且释放占用的数据块
- 配置参数如下
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
11.2、快照 SnapShot :备份(本质:CP命令)
11.2.1、 什么是快照
一个snapshot(快照)是一个全文件系统、或者某个目录在某一时刻的镜像。
11.2.2、快照的作用
- 防止用户的错误操作
- 备份
- 试验/测试
- 灾难恢复
11.2.3、开启快照
hdfs dfsadmin -allowSnapshot /input
11.2.4、创建快照(备份)
hdfs dfs -createSnapshot /input backup_input_01
往/input目录再存放一个文件,创建快照
hdfs dfs -put a.xml /input
hdfs dfs -createSnapshot /input backup_input_02
11.3、配额Quota
配额就是HDFS为每个目录分配的大小空间,新建立的目录是没有配额的,最大的配额是Long.Max_Value。配额为1可以强制目录保持为空。
- 名称配额
规定的是某个HDFS目录下文件的个数,
比如:设置名称配额是n,表示智能在该目录下存放N-1个文件或者目录
hdfs dfsadmin [-setQuota <quota> <dirname>...<dirname>]
hdfs dfsadmin [-clrQuota <dirname>...<dirname>]
举例:
hdfs dfs -mkdir /t1
设置该目录的名称配额是3
hdfs dfsadmin -setQuota 3 /t1
- 空间配额
规定的是某个HDFS目录下文件的大小
比如:设置某个HDFS目录的空间配额是200M,智能存放200M以下的文件
hdfs dfsadmin [-setSpaceQuota <quota> [-storageType <storagetype>] <dirname>...<dirname>]
hdfs dfsadmin [-clrSpaceQuota [-storageType <storagetype>] <dirname>...<dirname>]
举例:
hdfs dfs -mkdir /t2
设置该目录的空间配额是1M (逻辑单位)
hdfs dfsadmin -setSpaceQuota 1M /t2
错误
The DiskSpace quota of /t2 is exceeded: quota = 1048576 B = 1 MB but diskspace consumed = 134217728 B = 128 MB
11.4、安全模式 SafeMode
11.4.1、什么是安全模式?
安全模式是hadoop的一种保护机制,用于保证集群中的数据块的安全性。如果HDFS处于安全模式,则表示HDFS是只读状态。
11.4.2、安全模式的作用
当集群启动的时候,会首先进入安全模式。当系统处于安全模式时会检查数据块的完整性。假设我们设置的副本数(即参数dfs.replication)是5,name在datanade上就应该有5个副本存在,假设只存在3个副本,那么比例就是3/5=0.6。在配置文件hdfs-default.xml中定义了一个最小的副本的副本率0.999、我们的副本率0.6明显小于0.999,因此系统会自动的复制到其他的datanode,使得副本率不小于0.999,如果系统中有个8个副本,超过我们设定的5个副本,那么系统也会删除多余的3个副本。
11.4.3、安全模式的命令如下
hdfs dfsadmin -safemode get #查看安全模式状态
hdfs dfsadmin -safemode enter #进入安全模式状态
hdfs dfsadmin -safemode leave #离开安全模式
11.5、权限管理:类似linux
11.6、HDFS的集群
集群的两大功能:
(1)负载均衡
(2)失败迁移,实现HA
- 联盟 Federation
- HA