一.HDFS的命令行使用
HDFS的优点:
低成本,高容错性,高可靠性,高扩展性,流式数据访问,适合大数据处理
Hdfs的缺点:
不支持多用户同时的修改,不适合低延迟数据访问,无法高效存储大量小文件
1.HDFS初级命令使用
ls
格式: hdfs dfs -ls URI 作用:类似于Linux的ls命令,显示文件列表
hdfs dfs -ls /
lsr
格式 : hdfs dfs -lsr URI 作用 : 在整个目录下递归执行ls, 与UNIX中的ls-R类似
hdfs dfs -lsr /
mkdir
格式 : hdfs dfs [-p] -mkdir <paths> 作用 : 以<paths>中的URI作为参数,创建目录。使用-p参数可以递归创建目录
put
格式 : hdfs dfs -put <localsrc > ... <dst> 作用 : 将单个的源文件src或者多个源文件srcs从本地文件系统拷贝到目标文件系统中(<dst>对应的路径)。也可以从标准输入中读取输入,写入目标文件系统中
hdfs dfs -put /rooot/a.txt /dir1
moveFromLocal
格式: hdfs dfs -moveFromLocal <localsrc> <dst> 作用: 和put命令类似,但是源文件localsrc拷贝之后自身被删除
hdfs dfs -moveFromLocal /root/install.log /
get
格式 hdfs dfs -get [-ignorecrc ] [-crc] <src> <localdst> 作用:将文件拷贝到本地文件系统。 CRC 校验失败的文件通过-ignorecrc选项拷贝。 文件和CRC校验和可以通过-CRC选项拷贝
hdfs dfs -get /install.log /export/servers
mv
格式 : hdfs dfs -mv URI <dest> 作用: 将hdfs上的文件从原路径移动到目标路径(移动之后文件删除),该命令不能夸文件系统
hdfs dfs -mv /dir1/a.txt /dir2
rm
格式: hdfs dfs -rm [-r] 【-skipTrash】 URI 【URI 。。。】 作用: 删除参数指定的文件,参数可以有多个。 此命令只删除文件和非空目录。 如果指定-skipTrash选项,那么在回收站可用的情况下,该选项将跳过回收站而直接删除文件; 否则,在回收站可用时,在HDFS Shell 中执行此命令,会将文件暂时放到回收站中。
hdfs dfs -rm -r /dir1
cp
格式: hdfs dfs -cp URI [URI ...] <dest> 作用: 将文件拷贝到目标路径中。如果<dest> 为目录的话,可以将多个文件拷贝到该目录下。 -f 选项将覆盖目标,如果它已经存在。 -p 选项将保留文件属性(时间戳、所有权、许可、ACL、XAttr)。
hdfs dfs -cp /dir1/a.txt /dir2/b.txt
cat
hdfs dfs -cat URI [uri ...] 作用:将参数所指示的文件内容输出到stdout
hdfs dfs -cat /install.log
chmod
格式: hdfs dfs -chmod [-R] URI[URI ...] 作用: 改变文件权限。如果使用 -R 选项,则对整个目录有效递归执行。使用这一命令的用户必须是文件的所属用户,或者超级用户。
hdfs dfs -chmod -R 777 /install.log
chown
格式: hdfs dfs -chmod [-R] URI[URI ...] 作用: 改变文件的所属用户和用户组。如果使用 -R 选项,则对整个目录有效递归执行。使用这一命令的用户必须是文件的所属用户,或者超级用户。
hdfs dfs -chown -R hadoop:hadoop /install.log
appendToFile
格式: hdfs dfs -appendToFile <localsrc> ... <dst> 作用: 追加一个或者多个文件到hdfs指定文件中.也可以从命令行读取输入.
hdfs dfs -appendToFile a.xml b.xml /big.xml
2、hdfs的高级使用命令
1、HDFS文件限额配置
在多人共用HDFS的环境下,配置设置非常重要。特别是在Hadoop处理大量资料的环境,如果没有配额管理,很容易把所有的空间用完造成别人无法存取。Hdfs的配额设定是针对目录而不是针对账号,可以 让每个账号仅操作某一个目录,然后对目录设置配置。
hdfs文件的限额配置允许我们以文件个数,或者文件大小来限制我们在某个目录下上传的文件数量或者文件内容总量,以便达到我们类似百度网盘网盘等限制每个用户允许上传的最大的文件的量。
hdfs dfs -count -q -h /user/root/dir1 #查看配额信息
数量限额
hdfs dfs -mkdir -p /user/root/dir #创建hdfs文件夹 hdfs dfsadmin -setQuota 2 dir # 给该文件夹下面设置最多上传两个文件,发现只能上传一个文件
hdfs dfsadmin -clrQuota /user/root/dir # 清除文件数量限制
空间限额
在设置空间配额时,设置的空间至少是block_size * 3大小
hdfs dfsadmin -setSpaceQuota 4k /user/root/dir # 限制空间大小4KB hdfs dfs -put /root/a.txt /user/root/dir
生成任意大小文件的命令:
dd if=/dev/zero of=1.txt bs=1M count=2 #生成2M的文件
2丶hdfs的安全模式
hdfs dfsadmin -safemode get #查看安全模式状态
hdfs dfsadmin -safemode enter #进入安全模式
hdfs dfsadmin -safemode leave #离开安全模式
3丶HDFS基准测试
1.测试写入速度
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -fileSize 10MB
完成之后查看写入速度结果
hdfs dfs -text /benchmarks/TestDFSIO/io_write/part-00000
2.测试读取速度
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -read -nrFiles 10 -fileSize 10MB
完成之后查看写入速度结果
hdfs dfs -text /benchmarks/TestDFSIO/io_write/part-00000
3.清除测试数据
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -clean
4丶小文件合并
hdfs dfs -getmerge 小文件路径 合并到文件的路径
二.HDFS的javaAPI操作
1.配置Windows下的Hadoop环境
步骤:
第一步:将hadoop2.7.5文件夹拷贝到一个没有中文没有空格的路径下面
第二步:在windows上面配置hadoop的环境变量: HADOOP_HOME,并将%HADOOP_HOME%\bin添加到path中
第三步:把hadoop2.7.5文件夹中bin目录下的hadoop.dll文件放到系统盘: C:\Windows\System32 目录
第四步:关闭windows重启
2.导入Maven依赖
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- <verbal>true</verbal>-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
3.JavaAPI基本演示:
package cn.itcast.hdfs_api;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
import org.junit.Test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
public class HdfsApiDemo {
/*
* hdfs文件上传
* */
@Test
public void uploadFile() throws URISyntaxException, IOException, InterruptedException {
//1.获取FileSystem
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.23.129;8020"), new Configuration(),"root");
//调用方法实现下载
fileSystem.copyFromLocalFile(new Path("D://a.txt"),new Path("/"));
fileSystem.close();
}
/*
* hdfs文件下载
* */
@Test
public void downloadFile() throws URISyntaxException, IOException {
//1.获取FileSystem
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.23.129;8020"), new Configuration());
//调用方法实现下载
fileSystem.copyToLocalFile(new Path("/a.txt"),new Path("D://a.txt"));
fileSystem.close();
}
/*
* hdfs创建文件夹
* */
@Test
public void mkdirsTest() throws URISyntaxException, IOException {
//1.获取FileSystem实例
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.23.100:8020"), new Configuration());
//2.创建文件夹
boolean result = fileSystem.mkdirs(new Path("/aaa/bbb/ccc"));
System.out.println(result);
//关闭FileSystem
fileSystem.close();
}
/*
* hdfs文件遍历
* */
@Test
public void listFiles() throws URISyntaxException, IOException {
//1.获取FileSystem实例
FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.23.100:8020"), new Configuration());
//2.调用方法listFiles获取/目录下所有文件
RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);
//3.遍历迭代器
while (iterator.hasNext()){
LocatedFileStatus fileStatus = iterator.next();
//获取文件的绝对路径和文件名
System.out.println(fileStatus.getPath()+"---"+fileStatus.getPath().getName());
//文件的block信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println("block数"+blockLocations.length);
}
}
/*
* 获取FileSystem:方式1
* */
@Test
public void getFileSystem1() throws IOException {
//1:创建Configuration对象
Configuration configuration = new Configuration();
//2:设置文件系统的类型
configuration.set("fs.defaultFS","hdfs://192.168.23.100:8020");
//3:获取指定文件系统
FileSystem fileSystem =FileSystem.get(configuration);
//4:输出
System.out.println(fileSystem);
}
/*
* 获取FileSystem:方式2
* */
@Test
public void getFileSystem2() throws URISyntaxException, IOException {
FileSystem fileSystem= FileSystem.get(new URI("hdfs://192.168.23.100:8020"),new Configuration());
System.out.println(fileSystem);
}
/*
* 获取FileSystem:方式3
* */
@Test
public void getFileSystem3() throws IOException {
Configuration configuration = new Configuration();
configuration.set("fs.defaultFS","hdfs://192.168.23.100:8020");
FileSystem fileSystem = FileSystem.newInstance(configuration);
System.out.println(fileSystem);
}
/*
* 获取FileSystem:方式4
* */
@Test
public void getFileSystem4() throws URISyntaxException, IOException {
FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://192.168.23.100:8020"), new Configuration());
System.out.println(fileSystem);
}
@Test
public void urlHdfs() throws IOException {
//1.注册URl
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
//2.获取hdfs文件的输入流
InputStream inputStream = new URL("hdfs://192.168.23.100:8020/dir1/a.txt").openStream();
//3.获取本地文件的输入流
FileOutputStream outputStream = new FileOutputStream(new File("D:\\hello2.txt"));
//4.实现文件的拷贝
IOUtils.copy(inputStream,outputStream);
//5.关流
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
}
}
三.HDFS的高可用机制
1.高可用的介绍:
在Hadoop 中,NameNode 所处的位置是非常重要的,整个HDFS文件系统的元数据信息都由NameNode 来管理,NameNode的可用性直接决定了Hadoop 的可用性,一旦NameNode进程不能工作了,就会影响整个集群的正常使用。
2.在典型的HA集群中,两台独立的机器被配置为NameNode。在工作集群中,NameNode机器中的一个处于Active状态,另一个处于Standby状态。Active NameNode负责群集中的所有客户端操作,而Standby充当从服务器。Standby机器保持足够的状态以提供快速故障切换
2.组件介绍
ZKFailoverController
是基于Zookeeper的故障转移控制器,它负责控制NameNode的主备切换,ZKFailoverController会监测NameNode的健康状态,当发现Active NameNode出现异常时会通过Zookeeper进行一次新的选举,完成Active和Standby状态的切换
HealthMonitor
周期性调用NameNode的HAServiceProtocol RPC接口(monitorHealth 和 getServiceStatus),监控NameNode的健康状态并向ZKFailoverController反馈
ActiveStandbyElector
接收ZKFC的选举请求,通过Zookeeper自动完成主备选举,选举完成后回调ZKFailoverController的主备切换方法对NameNode进行Active和Standby状态的切换.
DataNode
NameNode包含了HDFS的元数据信息和数据块信息(blockmap),其中数据块信息通过DataNode主动向Active NameNode和Standby NameNode上报
共享存储系统
共享存储系统负责存储HDFS的元数据(EditsLog),Active NameNode(写入)和 Standby NameNode(读取)通过共享存储系统实现元数据同步,在主备切换过程中,新的Active NameNode必须确保元数据同步完成才能对外提供服务
3.Federation架构设计
HDFS Federation是解决namenode内存瓶颈问题的水平横向扩展方案。
Federation意味着在集群中将会有多个namenode/namespace。这些namenode之间是联合的,也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的datanode被用作通用的数据块存储存储设备。每个datanode要向集群中所有的namenode注册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。、
概括起来:
多个NN共用一个集群里的存储资源,每个NN都可以单独对外提供服务。
每个NN都会定义一个存储池,有单独的id,每个DN都为所有存储池提供存储。
DN会按照存储池id向其对应的NN汇报块信息,同时,DN会向所有NN汇报本地存储可用资源情况。