Hadoop概念&命令操作&java操作
1. Hadoop概述
- HADOOP是apache旗下的一套开源软件平台,利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理
- HADOOP的核心组件有:
HDFS(分布式文件系统)
YARN(运算资源调度系统)
MAPREDUCE(分布式运算编程框架)
2. HDFS的概念
hdfs是一个文件系统,用于存储文件,通过统一的命名空间–目录树来定位文件。它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。主要特性如下
- HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M,老版本中是64M.
- HDFS文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
- 目录结构及文件分块信息(元数据)的管理由namenode节点承担
——namenode是HDFS集群主节点,负责维护整个hdfs文件系统的目录树,以及每一个路径(文件)所对应的block块信息(block的id,及所在的datanode服务器) - 各个block的存储管理由datanode节点承担
---- datanode是HDFS集群从节点,每一个block都可以在多个datanode上存储多个副本(副本数量也可以通过参数设置dfs.replication) - HDFS是设计成适应一次写入,多次读出的场景,且不支持文件的修改
3. hdfs不适用的场景
- 低延迟的数据访问:hdfs的强项在与大量数据传输,延迟不适合他,10毫秒一下的访问可以无视hdfs,不过hbase可以弥补这个缺陷。
- 太多小文件: namenode节点在内存中hold住了整个文件系统的元数据,因此文件的数量就会受到限制,每个文件的元数据大约150字节,1百万个文件,每个文件只占一个block,那么就需要150MB内存。你的服务器可以hold住多少呢?
- 多处写和随机修改:目前还不支持多处写入以及通过偏量随机修改。
4. namenodes和datanodes
hdfs集群有两种类型的节点,一种为master及namenode,另一种为worker及datanodes。namenode节点管理文件系统的命名空间。它包含一个文件系统的树,所有文件和目录的原数据都在这个树上,这些信息被存储在本地磁盘的两个文件中,image文件和edit log文件。文件相关的块存在哪个块中,块在哪个地方,这些信息都是在系统启动的时候加载namenode的内存中,并不会存储在磁盘中。datanode节点在文件系统中充当的角色就是苦力,按照namenode和client的指令进行存储或者检索block,并且周期性的向namenode节点报告它存了哪些文件的block。
5. secondarynamenode
它是namenode的一个快照,会根据configuration中设置的值来决定多少时间周期性的去cp一下namenode,记录namenode中的metadata及其它数据。
6. NodeManager(NM)
NodeManager是YARN中每个节点上的代理,它管理Hadoop集群中单个计算节点包括与ResourceManger保持通信,监督Container的生命周期管理,监控每个Container的资源使用(内存、CPU等)情况,追踪节点健康状况。
7. ResourceManager
在YARN中,ResourceManager负责集群中所有资源的统一管理和分配,它接收来自各个节点(NodeManager)的资源汇报信息,并把这些信息按照一定的策略分配给各个应用程序(实际上是ApplicationManagerRM与每个节点的NodeManagers (NMs)和每个应用ApplicationMasters (AMs)一起工,b.ApplicationMasters负责与ResourceManager协商资源与NodeManagers合作启动容器.
8. hdfs客服端常用命令
查看集群状态: hdfs dfsadmin -report
hadoop fs -ls /
//如果提示警告:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform...
原因:系统预装的glibc库是2.12版本,而hadoop期望是2.14版本,所以打印警告信息。
解决方案:在log4j日志中去除告警信息,在/hadoop-2.5.2/etc/hadoop/log4j.properties文件中添加:log4j.logger.org.apache.hadoop.util.NativeCodeLoader=ERROR
-ls
功能:显示目录信息
示例: hadoop fs -ls hdfs://localhost:9000/
备注:这些参数中,所有的hdfs路径都可以简写
-->hadoop fs -ls / 等同于上一条命令的效果
-mkdir
功能:在hdfs上创建目录
示例:hadoop fs -mkdir -p /aaa/bbb/cc/dd
-moveFromLocal
功能:从本地剪切粘贴到hdfs
示例:hadoop fs - moveFromLocal /home/hadoop/a.txt /aaa/bbb/cc/dd
-moveToLocal
功能:从hdfs剪切粘贴到本地
示例:hadoop fs - moveToLocal /aaa/bbb/cc/dd /home/hadoop/a.txt
--appendToFile
功能:追加一个文件到已经存在的文件末尾
示例:hadoop fs -appendToFile ./hello.txt hdfs://hadoop-server01:9000/hello.txt
可以简写为:
Hadoop fs -appendToFile ./hello.txt /hello.txt
-cat
功能:显示文件内容
示例:hadoop fs -cat /hello.txt
-chmod
功能:linux文件系统中的用法一样,对文件所属权限
示例:
hadoop fs -chmod 666 /hello.txt
-copyFromLocal
功能:从本地文件系统中拷贝文件到hdfs路径去
示例:hadoop fs -copyFromLocal ./jdk.tar.gz /aaa/
-copyToLocal
功能:从hdfs拷贝到本地
示例:hadoop fs -copyToLocal /aaa/jdk.tar.gz
-cp
功能:从hdfs的一个路径拷贝hdfs的另一个路径
示例: hadoop fs -cp /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2
-mv
功能:在hdfs目录中移动文件
示例: hadoop fs -mv /aaa/jdk.tar.gz /
-get
功能:等同于copyToLocal,就是从hdfs下载文件到本地
示例:hadoop fs -get /aaa/jdk.tar.gz
-getmerge
功能:合并下载多个文件
示例:比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...
hadoop fs -getmerge /aaa/log.* ./log.sum
-put
功能:等同于copyFromLocal
示例:hadoop fs -put /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2
-rm
功能:删除文件或文件夹
示例:hadoop fs -rm -r /aaa/bbb/
-rmdir
功能:删除空目录
示例:hadoop fs -rmdir /aaa/bbb/ccc
-df
功能:统计文件系统的可用空间信息
示例:hadoop fs -df -h /
-du
功能:统计文件夹的大小信息
示例:
hadoop fs -du -s -h /aaa/*
-count
功能:统计一个指定目录下的文件节点数量
示例:hadoop fs -count /aaa/
9. java操作HDFS
1. 引入依赖
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.1</version>
</dependency>
2. 测试类
public class OperationFileTest {
FileSystem fs = null;
Configuration conf = null;
/**
* 初始化文件系统操作的客户端实例对象
*/
@Before
public void init() throws IOException, URISyntaxException, InterruptedException {
conf = new Configuration();
// uri和用户身份 ---> 一个文件系统操作的客户端实例对象
fs = FileSystem.get(new URI("hdfs://192.168.133.11:9000"),conf,"root");
}
/**
* 上传文件
*/
@Test
public void testUpload() throws IOException {
fs.copyFromLocalFile(new Path("D:\\examProject.rar"), new Path("/examProject.rar"));
fs.close();
}
/**
* 下载文件
*/
@Test
public void testDownload() throws Exception{
Path remotePath = new Path("/examProject.rar");
Path localPath = new Path("f:/");
fs.copyToLocalFile(remotePath,localPath);
fs.close();
}
/**
* conf加载的内容
*/
@Test
public void testConf(){
Iterator<Map.Entry<String,String>> iterator = conf.iterator();
while (iterator.hasNext()){
Map.Entry<String, String> item = iterator.next();
System.out.println(item.getValue()+"--"+item.getValue());
}
}
/**
* 创建目录
*/
@Test
public void makdirTest() throws Exception {
boolean mkdirs = fs.mkdirs(new Path("/a/b"));
System.out.println(mkdirs);
}
/**
* 删除
*/
@Test
public void deleteTest() throws Exception{
boolean delete = fs.delete(new Path("/a"), true);//true, 递归删除
System.out.println(delete);
}
/**
* 列出根目录下的文件路径
*/
@Test //
public void listTest() throws Exception{
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
System.err.println(fileStatus.getPath()+"================="+fileStatus.toString());
}
//会递归找到所有的文件
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while(listFiles.hasNext()){
LocatedFileStatus next = listFiles.next();
String name = next.getPath().getName();
Path path = next.getPath();
System.out.println(name + "---" + path.toString());
}
}
}
分布式运行
- 在idea 打成jar,在打jar包的时候选择要运行的主类
- 上传到linux上,使用命令运行: hadoop jar + jar包路径 + main函数的参数
eg: hadoop jar /home/zhm/example.jar com/zhm/test/hdfs/FsGetFile
10. 集成hadoop遇到的问题
-
初始化工作目录结构
hdfs namenode -format 只是初始化了namenode的工作目录而datanode的工作目录是在datanode启动后自己初始化的,在格式化前用户不需要创建工作目录,格式化后会自动创建namenode的工作目录。 -
datanode不被namenode识别的问题
namenode在format初始化的时候会形成两个标识:
blockPoolId(块池id)与clusterId(集群id)
新的datanode加入时,会获取这两个标识作为自己工作目录中的标识
一旦namenode重新format后,namenode的身份标识已变,而datanode如果依然
持有原来的id,就不会被namenode识别. 所以在namenode格式化的时候要将老的datanode的工作目录删除掉,否则新格式化的namenode不会识别旧的datanode. -
关于副本数量的问题
副本数由客户端的参数dfs.replication决定(优先级: conf.set > 自定义配置文件 > jar包中的hdfs-default.xml)
11.hadoop 运行的三种模式详解
1、独立模式(本地模式) standalone
无需任何守护进程,所有的程序都运行在同一个JVM上执行。在独立模式下调试MR程序非常高效方便。所以一般该模式主要是在学习或者开发阶段调试使用 。
2、伪分布模式 pseudodistributed
Hadoop守护进程运行在本地机器上,模拟一个小规模的集群,换句话说,可以配置一台机器的Hadoop集群,伪分布式是完全分布式的一个特例。
3、完全分布模式 fulldistributed
Hadoop守护进程运行在一个集群上。
三种模式的集群必须配置信息