看完就能独自把集群搭起来!Hadoop HDFS完全分布式环境搭建以及技术详解
作者 | 慢慢变成大佬
责编 | Carol
出品 | CSDN云计算(ID:CSDNcloud)
Hadoop是一个框架:Hadoop的本质其实就是一系列功能模块儿组成的框架,每个模块分别负责Hadoop的一些功能,如HDFS负责大数据的存储功能,Yarn,负责整个集群的资源调度,Common则负责Hadoop远程过程调用的实现以及提供序列化机制。
Hadoop具有高容错性,以及高拓展性。
Hadoop适合处理大数据数据。
这里对HDFS的组成架构做说明:
1)NameNode : 是HDFS的主从架构中的Master,负责维护整个文件系统的目录树,管理数据块(Block)的元数据信息,处理客户端的读写请求,并且管理Block的副本放置策略。
2)DataNode: 是HDFS的主从架构中的Slave,存放在HDFS中的文件都被分成块来存储,DataNode负责存储文件的块,对于DataNode所在的节点来说,块就是一个普通的文件,可以在DataNode存放块的目录下查看,如果不改动,默认是$(dfs.data.dir)/current),块的文件名为blk_blkID。DataNode会通过心跳机制和NameNode通信。
在集群初始化时,每个DataNode启动后都将当前存储的块的元数据信息告诉NameNode,在集群正常工作时,DataNode会不断的向NameNode通信,向它提供自己本地的信息,同时会接受来自NameNode的读写命令,来操作本地的数据块。
这个时候我们会有疑问,NameNode的元数据到底存放在哪里? 首先不可能是磁盘,因为如果存放在 磁盘,那么经常操作HDFS,效率会非常低,那么就只能会存放内存里,可是,效率虽然快了,但是如果 内存满了,或者集群停止服务,那么数据的元数据就会丢失,对于这个问题,HDFS做了一个专门用来解决 这个问题的角色,SecondaryNameNode
3)SecondaryNamenode: 是用于定期合并命名空间镜像和命名空间镜像的编辑日志的辅助守护进程,每个HDFS集群都有一个SecondaryNameNode,在生产环境下,一般SecondaryNameNode也会单独运行在一台服务器上。
FSImage文件(命名空间镜像) 可以理解为NameNode当时的内存状态或者内存中元数据序列化后形成的文件,所有信息保存做成的镜像文件,是可以被加载的。也可以理解为是文件系统元数据的一个永久的性检查点,但并不是每一个写操作都会更新这个文件,因为FSImage肯定是一个大型的文件,如果频繁地执行对这个文件进行写操作,会使系统运行极为缓慢。
解决方案是,NameNode只将改动内容预写日志(WAL),即写入命名空间镜像的编辑日志(edit log 记录客户端更新元数据信息的每一步操作)可通过Edits运算出元数据。随着时间的推移,编辑日志会变得越来越大,那么如果发生故障,将会花费非常多的时间来进行回滚操作,所以就像传统的关系型数据库一样,需要定期地合并FSImage和编辑日志。
如果由NameNode来做合并的操作,那么NameNode在为集群提供服务时可能无法提供足够的资源,那么为了彻底解决这一问题,就加入了SecondaryNameNode这个角色。
工作详解:
NameNode启动时,先滚动Edits并生成一个空的edits.inprogress,然后加载Edits和Fsimage到内存中,此时NameNode内存就持有最新的元数据信息。Client开始对NameNode发送元数据的增删改的请求,这些请求的操作首先会被记录到edits.inprogress中(查询元数据的操作不会被记录在Edits中,因为查询操作不会更改元数据信息),如果此时NameNode挂掉,重启后会从Edits中读取元数据的信息。然后,NameNode会在内存中执行元数据的增删改的操作。
由于Edits中记录的操作会越来越多,Edits文件会越来越大,导致NameNode在启动加载Edits时会很慢,所以需要对Edits和Fsimage进行合并(所谓合并,就是将Edits和Fsimage加载到内存中,照着Edits中的操作一步步执行,最终形成新的Fsimage)。SecondaryNameNode的作用就是帮助NameNode进行Edits和Fsimage的合并工作。
4)块: 每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位,文件系统也有文件块的概念,HDFS同样也有块(block)的概念,但是HDFS的块比一般文件系统的块大得多,默认为128MB,并且可以随着实际需要而变化,配置项为HDFS-site.xml文件中的dfs.block.size项。
与单一文件系统相似,HDFS上的文件也被划分为块大小的多个分块,它是HDFS存储处理的最小单元。HDFS中的块如此之大的原因是为了最小化寻址开销。如果块设置的足够大,从磁盘传输数据的时间可以明显大于定位这个块开始位置所需的时间。这样,传输一个由多个块组成的文件的时间取决于磁盘传输的效率。得益于磁盘传输速率的提升,块的大小可以被设为300 MB甚至更大。
2、HDFS的容错机制
3、副本的选择策略
Hadoop的默认布局是在HDFS客户端节点上放第一个副本,但是由于HDFS客户端有可能运行于集群之外,就随机选择一个节点,不过Hadoop会尽量避免选择那些存储太满或者太忙的节点。
第二个副本放在与第一个不同且随机另外选择的机架中的节点上。第三个副本与第二个副本放在相同的机架,且随机选择另外一个节点。其他副本(如果dfs.replication大于3)放在集群随机选择的节点上,Hadoop也会尽量避免在相同的机架上放太多副本。
4、HDFS写文件流程
注意: 如果写入的时候,复制管道中的某一个DataNode无法将数据写入磁盘(如DataNode死机)。发生这种错误时,管道会立即关闭,已发送的但尚未收到确认的数据包会被退回到队列中,以确保管道中错误节点的下游节点可以得到数据包。而在剩下的健康的DataNode中,正在写入的数据块会被分配新的blk_id。
这样,当发生故障的数据节点恢复后,冗余的数据块就会因为不属于任何文件而被自动丢弃,由剩余DataNode节点组成的新复制管道会重新开放,写入操作得以继续,写操作将继续直至文件关闭。
NameNode如果发现文件的某个数据块正在通过复制管道进行复制,就会异步地创建一个新的复制块,这样,即便HDFS的多个DataNode发生错误,HDFS客户端仍然可以从数据块的副本中恢复数据,前提是满足最少数目要求的数据副本(dfs.replication.min)已经被正确写入(dfs.replication.min配置默认为1)。
5、HDFS读文件流程
1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。
1. 首先准备3台虚拟机,并且要保证虚拟机的时间同步和hosts,ip都配置好,集群能互相通信。
这里可以看到,我的三台都配好了ip,而且hosts也都写了,并且集群时间同步也都已经做了。
接下来进行第二步。
2. 解压安装JDK,并且在/etc/profile 里面配置环境变量
通过xftp把文件传到linux本地里面 ,自己新建文件夹,放到里面 ,然后解压到自己的文件夹内。
通过tar命令进行解压并进行环境变量的配置,最后记得source配置文件。
3. 接下来,我们进入etc目录,并且对Hadoop的配置进行修改。
我们总共要修改 core-site.xml . hadoop-env.sh . hdfs-site.xml ,mapred-env.sh, mapred-site.xml , slaves, yarn-env.sh, yarn-site.xml
首先,在上面这些配置文件后缀都是sh的,比如hadoop-env.sh,我们就只需要把JavaHome配置一下。
其他的-env.sh的也是这样,只需要配置JDK即可,这里就不多阐述 。
接下来,我们vim core-site,并配置这些东西
<!-- 指定HDFS中NameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:9000</value>
</property>
<!-- 指定Hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp</value>
</property>
这个就配置完成,接着,我们就配置hdfs-site.xml
<!-- 配置块的副本数 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 指定Hadoop辅助名称节点主机配置 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop104:50090</value>
</property>
然后配置yarn-site.xml
<!-- Reducer获取数据的方式 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定YARN的ResourceManager的地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop103</value>
</property>
接着配置mapred-site.xml
<!-- 指定MR运行在Yarn上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
到这里,我们Hadoop的配置就已经完成,因为是分布式,所以我们就通过scp -r 的命令把jdk,和Hadoop都拷贝过去,并且各自配置一下环境变量,并source,到这里我们完全分布式就配置完成。
然后我们可以单点启动,也可以群起,不过群起需要配置免密,免密配置很简单,就不再多说,接下来我们直接通过start-all.sh启动集群,可以通过jps查看一下。
至此,我们的完全分布式搭建成功,相信大家也对搭建的过程很了解了,对Hadoop HDFS也都算是非常详细的介绍了,希望大家看完都能自己搭建一个集群,对以后的大数据学习打下基础,至于shell操作HDFS,或者JavaAPI操作,都是非常简单的,在这里简单说一下, shell操作Hadoop十分简单,部分命令和linux很像。
```powershell
-mkdir 在HDFS上创建目录
-moveFromLocal:从本地剪切粘贴到HDFS
-appendToFile:追加一个文件到已经存在的文件末尾
-cat:显示文件内容
-chgrp 、-chmod、-chown:Linux文件系统中的用法一样,修改文件所属权限
-copyFromLocal:从本地文件系统中拷贝文件到HDFS路径去
-copyToLocal:从HDFS拷贝到本地
-cp :从HDFS的一个路径拷贝到HDFS的另一个路径
-mv:在HDFS目录中移动文件
-get:等同于copyToLocal,就是从HDFS下载文件到本地
-getmerge:合并下载多个文件,比如HDFS的目录 /user/lmr/test下有多个文件:log.1, log.2,log.3,...
-put:等同于copyFromLocal
-tail:显示一个文件的末尾
-rm:删除文件或文件夹
-rmdir:删除空目录
-du统计文件夹的大小信息
你的企业混合云了吗?来看看评估混合云解决方案时要注意的6个原则! 程序员笔试面试最爱考察的算法,到底怎么搞定? 基于区块链技术的数据共享赋能AI驱动网络
钉钉爆火背后,真正的在线教育机构过得怎么样?已有 1 家倒闭
先马后看!详解线性回归、朴素贝叶斯、随机森林在R和Python中的实现应用!(附代码)