文档基于介绍基于Hadoop的大数据生态圈。介绍下图每一个组件的使用场景及使用方法,同时还对每一个组件有更深入的介绍。
1.Hadoop
1.1 Hadoop简介
2005年,Doug Cutting、Mike Cafarella及其团队,基于Google方案,开始设计研发一种开放式源代码项目,名为HADOOP。
Hadoop是基于JAVA语言开发的Apache开源框架,支持跨计算机集群的大规模数据集的分布式处理。
Hadoop利用MapReduce算法来运行程序,以并行处理方式在不同CPU节点上处理数据。
基于Hadoop框架的应用程序,能够支持跨计算机集群的分布式存储和计算。Hadoop框架设计旨在从单一服务器扩展到上千台机器,每一台机器能够提供本地计算和存储。
1.2 Hadoop架构
Hadoop框架包括以下四个模块:
Hadoop Common:这些是其他Hadoop模块所需的Java库和实用程序。这些库提供文件系统和操作系统级抽象,并包含启动Hadoop所需的Java文件和脚本。
Hadoop YARN:这是一个用于作业调度和集群资源管理的框架。
Hadoop Distributed File System (HDFS):分布式文件系统,提供对应用程序数据的高吞吐量访问。
Hadoop MapReduce:这是基于YARN的用于并行处理大数据集的系统。Hadoop MapReduce是一个软件框架,用于轻松编写应用程序,以可靠,容错的方式在大型集群(数千个节点)的商用硬件上并行处理大量数据。术语MapReduce实际上指的是Hadoop程序执行的以下两个不同任务:
The Map Task:术语MapReduce实际上指的是Hadoop程序执行的以下两个不同任务:
The Reduce Task:此任务将map任务的输出作为输入,并将这些数据元组合并为较小的元组集合。reduce任务总是在map任务之后执行。
通常输入和输出都存储在文件系统中。该框架负责调度任务,监视它们并重新执行失败的任务。
MapReduce框架由每个集群节点的单个主JobTracker和一个从属TaskTracker组成。主机负责资源管理,跟踪资源消耗/可用性以及调度从机上的作业组件任务,监视它们并重新执行失败的任务。从属TaskTracker按主控器指示执行任务,并定期向主控器提供任务状态信息。
JobTracker是Hadoop MapReduce服务的单点故障,这意味着如果JobTracker关闭,所有正在运行的作业都将停止。
可以使用下面的图来描述这四个组件在Hadoop框架中可用。
1.3 Hadoop的优缺点
Hadoop的优点
1、Hadoop具有按位存储和处理数据能力的高可靠性。
2、Hadoop通过可用的计算机集群分配数据,完成存储和计算任务,这些集群可以方便地扩展到数以千计的节点中,具有高扩展性。
3、Hadoop能够在节点之间进行动态地移动数据,并保证各个节点的动态平衡,处理速度非常快,具有高效性。
4、Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配,具有高容错性。
Hadoop的缺点
1、Hadoop不适用于低延迟数据访问。
2、Hadoop不能高效存储大量小文件。
3、Hadoop不支持多用户写入并任意修改文件。
1.4 Hadoop搭建
- 把压缩包通过xshell传入虚机的/root下,解压至存放目录:
tar -zxvf hadoop-2.7.4.tar.gz -C /opt/modules/
- 在存放目录下创建数据存放的文件夹,tmp、hdfs、hdfs/data、hdfs/name
mkdir /opt/modules/tmp
mkdir /opt/modules/hdfs
mkdir /opt/modules/hdfs/data
mkdir /opt/modules/hdfs/name
- 修改环境变量:
vi /etc/profile
#HADOOP_HOME
export HADOOP_HOME=/home/hadoop/hadoop-2.7.4
exportPATH=$PATH:$HOME/bin:$HADOOP_HOME/bin
- 生效:
source /etc/profile
- 配置文件:
- 配置hadoop的java环境支持,${HADOOP_HOME}/etc/hadoop目录下
hadoop-env.sh 、mapred-env.sh 、yarn-env.sh
- 在这3个文件中都配置
export JAVA_HOME=/opt/modules/jdk1.8.0_271
- 与hdfs相关的配置 ${HADOOP_HOME}/etc/hadoop
- 配置core-site.xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
<!--hadoop在运行时产生的文件,元数据在本地的存放目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value> /opt/modules/hdfs/data</value>
</property>
- 配置hdfs-site.xml
<!--存放到hdfs上的文件的副本数,伪分布式配置为1 -->
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
- 配置YARN 任务调度 (Mapreduce) 资源管理(resourcemanager nodemanager):
- 配置yarn-site.xml
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
<!-- 指明在执行MapReduce的时候使用shuffle-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
- 复制并重名模板文件:
cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
配置mapred-site.xml:
<!-- 指定MapReduce基于Yarn来运行-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
- 启动查看:
在master服务器启动Hadoop,从节点会自动启动,进入/opt/modules/hadoop-2.7.4目录。
输入命令进行初始化;
bin/hdfs namenode -format
输入命令启动全部守护进程,
sbin/start-all.sh
也可以分开启动各个进程
sbin/start-dfs.sh、sbin/start-yarn.sh;
输入命令,停止Hadoop集群;
sbin/stop-all.sh
- 输入jps命令,可以查看master上启动的5个守护进程,分别为NameNode、DataNode、SecondaryNameNode、NodeManager、ResourceManager。
1.5 HDFS
Hadoop分布式文件系统(HDFS)基于Google文件系统(GFS),并提供一个分布式文件系统,该系统设计为在大型集群(数千台计算机)上运行小型计算机机器以可靠,容错方式。HDFS使用主/从架构,其中主节点由管理文件系统元数据的单个NameNode和存储实际数据的一个或多个从节点DataNode组成。HDFS命名空间中的文件被拆分为几个块,这些块存储在一组DataNode中。NameNode决定块到DataNode的映射。DataNodes负责与文件系统的读写操作。它们还根据NameNode给出的指令来处理块创建,删除和复制。HDFS提供了一个类似任何其他文件系统的shell,并且有一个命令列表可用于与文件系统交互。
1.5.1 HDFS读取与写入
流程如图:
(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为单位(64kb),dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
(8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)。
(1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。
1.5.2 HDFS文件操作
参考官方文档:Apache Hadoop 2.10.1 – Overview
参考文档:
https://www.runoob.com/linux/linux-command-manual.html
(1)、appendToFile
appendToFile命令是将一个或者多个文件添加到HDFS系统中,他也是从标准输入中读取,然后添加到目标文件系统汇总。
命令用法:
hadoop fs -appendToFile localfile /user/hadoop/hadoopfile
hadoop fs -appendToFile localfile1 localfile2 /user/hadoop/hadoopfile
hadoop fs -appendToFile - hdfs://nn.example.com/hadoop/hadoopfile
- 、cat
cat(英文全拼:concatenate)命令用于连接文件并打印到标准输出设备上。
命令用法:
hadoop fs -cat hdfs://nn1.example.com/file1 hdfs://nn2/file2
hadoop fs -cat file:///file3 /user/hadoop/file4
- 、checksum
Datanode在把数据实际存储之前会验证数据的校验和(checksum的初始值)如果某个client在读取数据时检测到数据错误, 抛出ChecksumException
命令用法:
hadoop fs -checksum hdfs://nn1.example.com/file1
hadoop fs -checksum file:///etc/hosts
- 、chgrp
chgrp(英文全拼:change group)命令用于变更文件或目录的所属群组。与 chown 命令不同,chgrp 允许普通用户改变文件所属的组,只要该用户是该组的一员。
命令用法:
hadoop fs -chgrp [-R] GROUP URI [URI ...]
- 、chmod
用来修改权限
命令用法:
hadoop fs -chmod 777 /user/dataflair/dir1/sample
- 、chown
chown(英文全拼:change owner)命令用于设置文件所有者和文件关联组的命令。
命令用法:
hadoop fs -chown [-R] [属主][:[属组]] 路径
- 、copyFromLocal
从本地复制
命令用法:
hadoop fs -copyFromLocal <多个linux上的文件> <hdfs路径>
- 、copyToLocal
复制到本地
命令用法:
hadoop fs -copyToLocal [-ignoreCrc] [-crc] [hdfs源路径] [linux目的路径]
- 、count
统计文件(夹)数量
命令用法:
hadoop fs -count [-q] [-h] [-v] [-x] [-t [<storage type>]] [-u] <paths>
- 、cp
复制
命令用法:
hadoop fs -cp /opt/modules /usr
hadoop fs -cp /opt/modules /usr /root
- 、createSnapshot
创建快照
命令用法:
hadoop fs -createSnapsshot [snapshot names]
- 、deleteSnapshot
删除快照
命令用法:
hadoop fs -deleteSnapshot <path> <snapshotName>
- 、df
文件系统磁盘使用情况统计。
命令用法:
hadoop dfs -df /user/hadoop/dir1
- 、du
统计目录下个文件大小
命令用法:
hadoop fs -du [-s] [-h] [-x] URI [URI ...]
- 、dus(-du -s)
汇总统计目录下文件(夹)大小
命令用法:
hadoop fs -dus <args>
- 、expunge
擦去;删掉
命令用法:
hadoop fs -expunge
- 、find
用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。
命令用法:
hadoop fs -find / -name test -print
- 、get
命令用法:
hadoop fs -get /user/hadoop/file localfile
hadoop fs -get hdfs://nn.example.com/user/hadoop/file localfile
- 、getfacl
获取目录或文件访问控制列表
命令用法:
hadoop fs -getfacl /file
hadoop fs -getfacl -R /dir
- 、getfattr
获取文件系统对象的扩展属性
命令用法:
hadoop fs -getfattr -d /file
hadoop fs -getfattr -R -n user.myAttr /dir
- 、getmerge
合并到本地
命令用法:
hadoop fs -getmerge -nl /src /opt/output.txt
hadoop fs -getmerge -nl /src/file1.txt /src/file2.txt /output.txt
- 、help
帮助
命令用法:
hadoop fs -help
- 、ls
查看指定路径的当前目录结构
命令用法:
hadoop fs -ls /user/hadoop/file1
- 、lsr
递归查看指定路径的目录结构
命令用法:
hadoop fs -ls -R
- 、mkdir
创建空白文件夹
命令用法:
hadoop fs -mkdir /user/hadoop/dir1 /user/hadoop/dir2
- 、moveFromLocal
从本地移动
- 、moveToLocal
移动到本地
- 、mv
移动
- 、put
上传文件
命令用法:
hadoop fs -put localfile /user/hadoop/hadoopfile
hadoop fs -put -f localfile1 localfile2 /user/hadoop/hadoopdir
- 、rm
删除文件/空白文件夹
- 、rmdir
递归删除
命令用法:
hadoop fs -rmdir /user/hadoop/emptydir
- 、setfacl
setfacl命令可以用来细分linux下的文件权限。
命令用法:
hadoop fs -setfacl -m user:hadoop:rw- /file
hadoop fs -setfacl -x user:hadoop /file
hadoop fs -setfacl -b /file
hadoop fs -setfacl -k /dir
hadoop fs -setfacl -R -m user:hadoop:r-x /dir
hadoop fs -setfacl -m default:user:hadoop:r-x /dir
- 、setfattr
设置扩展属性
命令用法:
hadoop fs -setfattr -n user.myAttr -v myValue /file
hadoop fs -setfattr -n user.noValue /file
hadoop fs -setfattr -x user.myAttr /file
- 、setrep
修改副本数量
命令用法:
hadoop fs -setrep -w 3 /user/hadoop/dir1
- 、stat
显示文件统计信息
命令用法:
hadoop fs -stat "type:%F perm:%a %u:%g size:%b mtime:%y atime:%x name:%n" /file
- 、tail
查看文件尾部信息
命令用法:
hadoop fs -tail pathname
- 、test
查看文件内容
命令用法:
hadoop fs -test -e filename
- 、touchz
创建空白文件
命令用法:
hadoop fs -touchz pathname
- 、truncate
truncate删除数据
命令用法:
hadoop fs -truncate 55 /user/hadoop/file1 /user/hadoop/file2
hadoop fs -truncate -w 127 hdfs://nn1.example.com/user/hadoop/file1
1.6 Snapshot
参考官方文档:http://hadoop.apache.org/docs/r2.10.1/hadoop-project-dist/hadoop-hdfs/HdfsSnapshots.html
一个snapshot(快照)是一个全部文件系统、或者某个目录在某一时刻的镜像。快照在下面场景下是非常有用:
防止用户的错误操作:管理员可以通过以滚动的方式周期性设置一个只读的快照,这样就可以在文件系统上有若干份只读快照。如果用户意外地删除了一个文件,就可以使用包含该文件的最新只读快照来进行回复。
备份:管理员可以根据需求来备份整个文件系统,一个目录或者单一一个文件。管理员设置一个只读快照,并使用这个快照作为整个全量备份的开始点。增量备份可以通过比较两个快照的差异来产生。
试验/测试: 一个用户当想要在数据集上测试一个应用程序。一般情况下,如果不做该数据集的全量拷贝,测试应用程序会覆盖/损坏原来的生产数据集,这是非常危险的。管理员可以为用户设置一个生产数据集的快照(Read write)用于用户测试使用。在快照上的改变不会影响原有数据集。
灾难恢复:只读快照可以被用于创建一个一致的时间点镜像用于拷贝到远程站点作灾备冗余。
1.7 MapReduce
MapReduce最早是由Google公司研究提出的一种面向大规模数据处理的并行计算模型和方法。Google公司设计MapReduce的初衷主要是为了解决其搜索引擎中大规模网页数据的并行化处理。Google公司发明了MapReduce之后首先用其重新改写了其搜索引擎中的Web文档索引处理系统。但由于MapReduce可以普遍应用于很多大规模数据的计算问题,因此自发明MapReduce以后,Google公司内部进一步将其广泛应用于很多大规模数据处理问题。Google公司内有上万个各种不同的算法问题和程序都使用MapReduce进行处理。
1.7.1 Wordcount案例
代码实现:
###WordCountMapper:
package cn.imnu.wzy;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
/**
* map阶段的业务逻辑就写在自定义的map()方法中
* maptask会对每一行输入数据调用一次我们自定义的map()方法
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// 1 将maptask传给我们的文本内容先转换成String
String line = value.toString();
// 2 根据空格将这一行切分成单词
String[] words = line.split(" ");
// 3 将单词输出为<单词,1>
for(String word:words){
// 将单词作为key,将次数1作为value,以便于后续的数据分发,可以根据单词分发,以便于相同单词会到相同的reducetask中
context.write(new Text(word), new IntWritable(1));
}
}
}
###WordCountReducer:
package cn.imnu.wzy;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/**
* KEYIN , VALUEIN 对应mapper输出的KEYOUT, VALUEOUT类型
* KEYOUT,VALUEOUT 对应自定义reduce逻辑处理结果的输出数据类型 KEYOUT是单词 VALUEOUT是总次数
*/
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
/**
* key,是一组相同单词kv对的key
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int count = 0;
// 1 汇总各个key的个数
for(IntWritable value:values){
count +=value.get();
}
// 2输出该key的总次数
context.write(key, new IntWritable(count));
}
}
###WordCountDriver:
package cn.imnu.wzy;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 相当于一个yarn集群的客户端,
* 需要在此封装我们的mr程序相关运行参数,指定jar包
* 最后提交给yarn
* @author Administrator
*/
public class WordCountDriver {
public static void main(String[] args) throws Exception {
// 1 获取配置信息,或者job对象实例
Configuration configuration = new Configuration();
Job job = Job.getInstance(configuration);
// 6 指定本程序的jar包所在的本地路径
job.setJarByClass(WordCountDriver.class);
// 2 指定本业务job要使用的mapper/Reducer业务类
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
// 3 指定mapper输出数据的kv类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
// 4 指定最终输出的数据的kv类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 5 指定job的输入原始文件所在目录
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 7 将job中配置的相关参数,以及job所用的java类所在的jar包, 提交给yarn去运行
// job.submit();
boolean result = job.waitForCompletion(true);
System.exit(result?0:1);
}
}
1.8 API编程(java)
上传文件:
package cn.qst.test;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;