前言
Hadoop在大数据技术体系中的地位至关重要,Hadoop是大数据技术的基础。
这是一篇记录我自己学习的文章,Hadoop的学习方法很多,网上也有很多学习路线图。
hadoop介绍
Hadoop是一个能够对海量数据进行分布式处理的系统架构。我采用的是hadoop-2.8.0,它主要包含3大块:
- hdfs:分布式存储系统HDFS(Hadoop Distributed File System)分布式存储层
- mapreduce:分布式计算框架MapReduce分布式计算层
- yarn:资源管理系统YARN(Yet Another Resource Negotiator)集群资源管理层
Hadoop的核心是:HDFS和MapReduce。
分布式存储系统HDFS
HDFS(Hadoop Distributed File System,Hadoop 分布式文件系统)是一个高度容错性的系统,适合部署在廉价的机器上。HDFS 能提供高吞吐量的数据访问,适合那些有着超大数据集(largedata set)的应用程序。HDFS负责大数据的存储,通过将大文件分块后进行分布式存储方式,突破了服务器硬盘大小的限制,解决了单台机器无法存储大文件的问题,HDFS是个相对独立的模块,可以为YARN提供服务,也可以为HBase等其他模块提供服务。
核心
- NameNode
- DataNode
- SecondaryNameNode(NameNode的快照)
HDFS是一个主从结构,一个HDFS集群由一个名字节点(NameNode)和多个数据节点(DataNode)组成。
HDFS的优点(设计思想)
1.高容错性 HDFS 认为所有计算机都可能会出问题,为了防止某个主机失效读取不到该主机的块文件,它将同一个文件块副本分配到其它某几个主机上,如果其中一台主机失效,可以迅速找另一块副本取文件。数据自动保存多个节点;备份丢失后,自动恢复。
2.海量数据的存储 非常适合上T 级别的大文件或者一堆大数据文件的存储
3.文件分块存储 HDFS 将一个完整的大文件平均分块(通常每块64M)存储到不同计算机上,这样读取文件可以同时从多个主机取不同区块的文件,多主机读取比单主机读取效率要高得多得多。
4.移动计算 在数据存储的地方进行计算,而不是把数据拉取到计算的地方,降低了成本,提高了性能!
5.流式数据访问 一次写入,并行读取。不支持动态改变文件内容,而是要求让文件一次写入就不做变化,要变化也只能在文件末添加内容。
6.可构建在廉价的机器上 通过多副本提高可靠性,提供了容错和恢复机制。HDFS 可以应用在普通PC 机上,这种机制能够让一些公司用几十台廉价的计算机就可以撑起一个大数据集群。
NameNode
作用
- 它是一个管理文件的命名空间
- 协调客户端对文件的访问
- 记录每个文件数据在各个DataNode上的位置和副本信息
文件解析
- version:是一个properties文件,保存了HDFS的版本号
- editlog:任何对文件系统数据产生的操作,都会被保存!
- fsimage /.md5:文件系统元数据的一个永久性的检查点,包括数据块到文件的映射、文件的属性等
- seen_txid :非常重要,是存放事务相关信息的文件
什么是FSImage和EditsLog
FsImage和Editlog是HDFS的核心数据结构。这些文件的损坏会导致整个集群的失效。因此,名字节点可以配置成支持多个FsImage和EditLog的副本。任何FsImage和EditLog的更新都会同步到每一份副本中。
SecondaryNameNode
作用
- Namenode的一个快照,周期性的备份Namenode
- 记录Namenode中的metadata及其它数据
- 可以用来恢复Namenode,并不能替代NameNode!
执行流程
- SecondaryNameNode节点会定期和NameNode通信,请求其停止使用EditLog,暂时将新的写操作到一个新的文件edit.new上来,这个操作是瞬间完成的。
- SecondaryNameNode 通过HTTP Get方式从NameNode上获取到FsImage和EditLog文件并下载到本地目录
- 将下载下来的FsImage 和EditLog加载到内存中这个过程就是FsImage和EditLog的合并(checkpoint)
- 合并成功之后,会通过post方式将新的FsImage文件发送NameNode上。
- SecondaryNamenode 会将新接收到的FsImage替换掉旧的,同时将edit.new替换EditLog,这样EditLog就会变小。
DataNode
作用
- 真实数据的存储管理
- 一次写入,多次读取(不修改)
- 文件由数据块组成,Hadoop2.x的块大小默认是128MB
- 将数据块尽量散布到各个节点
文件解析
- blk_<id>:HDFS的数据块,保存具体的二进制数据
- blk_<id>.meta:数据块的属性信息:版本信息、类型信息
可以通过修改hdfs-site.xml的dfs.replication属性设置产生副本的个数!默认是3!
基本操作
MapReduce
MapReduce分布式处理框架为海量的数据提供了计算。MapReduce是一个计算框架,它给出了一种数据处理的方式,即通过Map阶段、Reduce阶段来分布式地流式处理数据。它只适用于大数据的离线处理,对实时性要求很高的应用不适用。
简介
- MapReduce是一种分布式计算模型,是Google提出的,主要用于搜索领域,解决海量数据的计算问题。
- MR有两个阶段组成:Map和Reduce,用户只需实现map()和reduce()两个函数,即可实现分布式计算。
MapReduce执行流程
MapReduce原理
MapReduce的执行步骤
- 读取HDFS中的文件。每一行解析成一个<k,v>。每一个键值对调用一次map函数。 - <0,hello you> <10,hello me>
- 覆盖map(),接收1产生的<k,v>,进行处理,转换为新的<k,v>输出。 - <hello,1> <you,1> <hello,1> <me,1>
- 对2输出的<k,v>进行分区。默认分为一个区。
- 对不同分区中的数据进行排序(按照k)、分组。分组指的是相同key的value放到一个集合中。 - 排序后:<hello,1> <hello,1> <me,1> <you,1> ;分组后:<hello,{1,1}><me,{1}><you,{1}>
- (可选)对分组后的数据进行归约
- 多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点上。(shuffle)
- 对多个map的输出进行合并、排序。覆盖reduce函数,接收的是分组后的数据,实现自己的业务逻辑 - <hello,2> <me,1> <you,1> 处理后,产生新的<k,v>输出。
- 对reduce输出的<k,v>写到HDFS中。
MapReduce原理总结
原语通常由若干条指令组成,用来实现某个特定的操作。通过一段不可分割的或不可中断的程序实现其功能。且常驻内存。但是这样一来,如果原语执行需要的开销超过了机器能给予的开销,则该原语在机器上无法执行,通常解决该问题的办法是增加机器配置,但计算机的配置在上层每提升一点所需要的资金都是翻倍的。因此根据分布式文件系统的原理,MapReduce诞生了。它将原语分成了两个步骤即map()和reduce(),同时两个阶段还可以分成多个模块在不同的机器上执行。
开始学习
- 上传hadoop.tar.gz到服务器并解压
- 配置hadoop环境变量
vi /etc/prifile
复制代码
添加配置
export HADOOP_HOME="/opt/modules/hadoop-2.8.0"
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
复制代码
source /etc/profile
复制代码
使得配置生效,并验证参数
echo ${HADOOP_HOME}
复制代码
- 配置 hadoop-env.sh、mapred-env.sh、yarn-env.sh文件的JAVA_HOME参数
修改JAVA_HOME参数为java的安装路径
如何查看java安装路径:
4.配置core-site.xml
以下操作都是在hadoop解压后的目录中操作
vi etc/hadoop/core-site.xml
复制代码
其中:
- fs.defaultFS - 配置的是hdfs的地址,又为默认文件系统的名称。一个URI,其方案和权限决定了FileSystem的实现。uri的方案确定命名FileSystem实现类的config属性(fs.SCHEME.impl)。 uri的权限用于确定文件系统的主机,端口等。 如果是本地模式,该配置可以如下:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
复制代码
如果是全分布模式配置,该配置可以如下:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/home/hadoop/tmp</value>
</property>
<property>
<name>hadoop.proxyuser.hduser.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hduser.groups</name>
<value>*</value>
</property>
</configuration>
复制代码
- hadoop.tmp.dir - 配置的是Hadoop临时目录,比如HDFS的NameNode数据默认都存放这个目录下,查看*-default.xml等默认配置文件,就可以看到很多依赖${hadoop.tmp.dir}的配置。默认的hadoop.tmp.dir是/tmp/hadoop-${user.name},此时有个问题就是NameNode会将HDFS的元数据存储在这个/tmp目录下,如果操作系统重启了,系统会清空/tmp目录下的东西,导致NameNode元数据丢失,是个非常严重的问题,所有我们应该修改这个路径。
更多配置属性介绍可以查看这里
5.配置hdfs-site.xml
vi etc/hadoop/hdfs-site.xml
复制代码
dfs.replication - 配置的是HDFS存储时的备份数量,因为这里是伪分布式环境只有一个节点,所以这里设置为1。
- 格式化hdfs
hdfs namenode -format
复制代码
格式化是对HDFS这个分布式文件系统中的DataNode进行分块,统计所有分块后的初始元数据的存储在NameNode中。格式化后,查看core-site.xml里hadoop.tmp.dir(本例是/opt/data目录)指定的目录下是否有了dfs目录,如果有,说明格式化成功。
ll /opt/data/tmp
复制代码
注意:
- 格式化时,这里注意hadoop.tmp.dir目录的权限问题,应该hadoop普通用户有读写权限才行,可以将/opt/data的所有者改为hadoop。
sudo chown -R hadoop:hadoop /opt/data
复制代码
查看NameNode格式化后的目录
ll /opt/data/tmp/dfs/name/current
复制代码
- fsimage - 是NameNode元数据在内存满了后,持久化保存到的文件。
- fsimage*.md5 - 是校验文件,用于校验fsimage的完整性。
- seen_txid - 是hadoop的版本
- VERSSION - 文件中保存着namespaceID:NameNode的唯一ID。clusterID:集群ID,NameNode和DataNode的集群ID应该一致,表明是一个集群。
- 启动namenode、datanode、secondarynamenode
- hdfs上测试创建目录、上传、下载文件
- 创建目录
hdfs dfs -mkdir /demol
复制代码
通过hdfs创建的目录我们直接用ls是查看不到的,此时可以使用以下命令查看
hdfs dfs -ls /
复制代码
- 上传本地文件到HDFS上
hdfs dfs -put {本地文件路径} /demol
复制代码
这里我遇到了一个问题,上传的时候提示我datanode没有启动,后来我用jps命令查看了发现datanode自动关闭了,这个问题的原因是因为datanode的clusterID 和 namenode的clusterID 不匹配。
解决办法,检查hdfs-site.xml和core-site.xml的配置,如果没有错误,则查看tmp/dfs下的name和data的VERISON中的集群id是否匹配,如果不匹配则删除datanode中current下的文件然后重新启动;或者直接修改集群id
- 下载文件到本地
hdfs dfs -get {HDFS文件路径}
复制代码
- 配置mapred-site.xml,yarn-site.xml
默认没有mapred-site.xml文件,但是有个mapred-site.xml.template配置模板文件。复制模板生成mapred-site.xml
cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
复制代码
添加配置如下:
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
复制代码
指定mapreduce运行在yarn框架上。
配置yarn-site.xml,添加配置如下:
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>0.0.0.0</value>
</property>
复制代码
- yarn.nodemanager.aux-services配置了yarn的默认混洗方式,选择为mapreduce的默认混洗算法。
- yarn.resourcemanager.hostname指定了Resourcemanager运行在哪个节点上。
更多属性查看
- 启动resourcemanager、nodemanager
yarn-daemon.sh start resourcemanager
yarn-daemon.sh start nodemanager
复制代码
通过jsp查看是否成功开启
- 运行MapReduce Job
在hadoop的share目录里,自带了一些jar包,里面带有一些mapreduce实例的小例子,位置在share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar,这里运行一个经典的单词统计实例
创建测试用的input文件
创建输入目录并将文件上传上去
hdfs dfs -mkdir -p /wordcount/input
hdfs dfs -put /opt/data/wc.input /wordcount/input
复制代码
运行wordcount mapreduce job
yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.0.jar wordcount /wordcount/input /wordcount/output
复制代码
查看结果目录
hdfs dfs -ls /wordcount/output
复制代码
-
output目录中有两个文件,_SUCCESS文件是空文件,有这个文件说明Job执行成功。
-
part-r-00000文件是结果文件,其中-r-说明这个文件是Reduce阶段产生的结果,mapreduce程序执行时,可以没有reduce阶段,但是肯定会有map阶段,如果没有reduce阶段这个地方有是-m-。
-
一个reduce会产生一个part-r-开头的文件。
查看结果文件
总结
- hdfs - 负责大数据文件的存储,文件保存为hadoop二进制文件,无法被直接查看,保证了安全性。其中的目录相当于虚拟目录。
- yarn - 一个任务调度框架,mapreduce在它上面运行。同时它还可以运行storm,spark等
- mapreduce - 计算框架,给出数据处理方案,然后通过yarn在多台机器上运行,如果将每台机器看作一个CPU,那么该程序编写过程中要求能支持并行且不会导致数据混乱。