大数据Hadoop运维应用实践——通过Ambari自动化部署hadoop集群(下)文章浏览阅读29次。本文是关于安装部署完成Ambari Server后,使用Ambari Web管理界面实现hadoop集群的安装部署操作,详细讲解了初始化一个hadoop集群的实践操作步骤;可视化的操作与配置,极大提升了hadoop集群的搭建操作;最后还讲解了使用Ambari Web管理界面对hadoop集群添加节点进行扩容、添加服务进行了详细的说明。https://coffeemilk.blog.csdn.net/article/details/163087528
一、HDFS的基础架构原理解析
1.0、HDFS的基础架构原理
| HDFS基础架构内容 | 说明 |
|---|---|
| NameNode | NameNode是HDFS分布式存储的管理节点,专门用来存储元数据的相关信息(所谓的“元数据”是指文件内容之外的数据【如:文件的存储位置、文件信息、文件大小、文件名称等】这些与文件属性相关的信息;也可以简单的类比为现实书籍中的目录【记录了内容章节、位置等信息】);是十分重要的,一旦元数据丢失,那么文件内容就很难找回来了,因此对元数据的保护尤其重要。 元数据首先是保存在内存中的(而对元数据的各种增删改查都是在内存中完成)内存中操作后的元数据会定时持久化到磁盘上。当NameNode启动时会从磁盘上加载元数据到内存中,后续对元数据的操作都是在内存中完成。 |
| DataNode | DataNode是HDFS分布式存储的数据节点,是真正存储数据的部分。 而HDFS分布式存储数据都是以数据块(data block)的方式保存在DataNode节点服务器的本地磁盘的文件系统上;同时DataNode也做了数据块到本地文件系统的映射(即:每个数据块都有具体的标识id或名称,每个数据块对应哪个文件,数据块与文件的映射关系,都是在DataNode上保存的)。 |
| Client | Client是HDFS分布式存储的客户端,用来与HDFS进行交互的。 |
| SecondaryNameNode | SecondaryNameNode是NameNode的备份节点,主要是用来备份NameNode的元数据。 需要注意的是SecondaryNameNode是对NameNode的异地冷备份,而不是热备份。 热备份:是指服务在正常运行的过程中,不用重启服务(或关闭启动服务)就能够对服务的元数据进行备份,并且是可以做到实时,无差别的备份。 冷备份:是指定时的备份,且备份的数据是不完整的,与主体的数据是不一致的。 StandbyNameNode:是NameNode的热备份节点,实现对NameNode元数据的实时备份,确保元数据的一致性。 注意:StandbyNameNode不能对外提供服务;但是可以通过JournalNode集群实时拉取NameNode的元数据到自己中;当NameNode发生故障时,StandbyNameNode会第一时间发现,并自己切换为主节点激活对外提供服务,而NameNode就转为备节点了(即:StandbyNameNode与NameNode是通过zookeeper集群进行双方的状态监控,一旦一方故障另一方就会第一时间发现进行角色的切换,然后另一方就会转为主节点激活对外提供服务了)。 JournalNode:只在HDFS的HA模式下出现,JournalNode作为一个守护进程,实现了元数据在主、备节点的共享。 |
1.1、NameNode的工作原理解析
NameNode是HDFS分布式存储的心脏,它管理和维护着整个HDFS文件系统,主要功能作用如下表:
| NameNode的主要功能作用 |
|---|
| 《1》负责接收用户的操作请求。 |
| 《2》负责管理文件系统命名空间(namespace)、集群配置信息以及存储块的复制等。 |
| 《3》负责文件目录树的维护以及文件对应block列表的维护。 |
| 《4》负责管理block与DataNode之间的关系。 |
在HDFS分布式存储中,【FsImage】与【Edit Log】是NameNode两个非常重要的文件。它们存储在NameNode节点的本地磁盘上,这就是NameNode的元数据信息。
| NameNode的元数据组成 | 说明 |
|---|---|
| FsImage | FsImage文件用来记录数据块到文件的映射、目录或文件的结构、属性等信息,里面记录了自最后一次检查点之前HDFS文件系统中所有目录和文件的信息。 |
| Edit Log | EditLog文件记录了对文件的创建、删除、重命名等操作日志,也就是自最后一次检查点之后所有针对HDFS文件系统的操作都会记录在EditLog文件中(如:在HDFS中创建一个文件, Namenode就会在EditLog中插入一条记录;同样地,修改文件的副本系数也会在EditLog中插入一条记录)。 检查点:当NameNode启动时,首先会将元数据加载到内存中(即将磁盘上的FsImage与EditLog数据加载到内存中,FsImage作为文件系统的基础镜像,而EditLog内容会回放一遍到FsImage中合并形成一份新的FsImage文件,新的FsImage文件会保存一份到磁盘中,同时会删除旧的EditLog文件;其中EditLog内容会回放一遍到FsImage中合并形成一份新的FsImage文件的过程就称为一个检查点)。 检查点就是为了解决EditLog文件不断变大的问题(即:当NameNode启动后会形成一个检查点,之后对于元数据的所有操作都会记录到EditLog文件中,正常来说NameNode启动后半年或几年都不会重启一次的,这样EditLog文件就会变得十分庞大【即NameNode启动的时间越长,EditLog文件也会越大】,虽然对于我们使用HDFS分布式存储来说并没有什么问题,但是若当NameNode服务器故障后【如:突然断电、宕机】恢复后再次重启NameNode时,EditLog文件十分庞大【如:几百几千GB】,此时元数据加载到内存中进行FsImage与EditLog合并时就会需要花费几个或几十个小时的时间,合并完不成,NameNode也无法启动,这样在生产环境下是绝对无法忍受的);在NameNode正常运行的时候就多产生几次检查点,这样就能够平衡元数据(FsImage与EditLog文件了),有两种方法可以多产出检查点:
注意:检查点是不能随意触发的,因为每次检查点执行的过程会消耗大量的CPU、IO与内存资源,且检查点执行时是会阻塞HDFS对外的读写操作,(即:无法接收外部的读写等请求,导致无法对外提供服务);因此检查点是不会在主节点NameNode触发,HDFS给出了几种方案:
|
1.2、SecondaryNameNode工作原理解析
| SecondaryNameNode的工作原理解析 |
|---|
| 《1》SecondaryNameNode节点会定期和NameNode通信,请求其停止使用EditLog,暂时将新的写操作转到一个新的文件edit.new上来,这个操作是瞬间完成的。 |
| 《2》SecondaryNameNode 通过HTTP Get方式从NameNode上获取元数据(FsImage和EditLog文件),并下载到本地目录。 |
| 《3》将下载下来的元数据(FsImage和EditLog文件)加载到内存中(即:使用FsImage为基础镜像逐一读取EditLog内容加入,直到两者合并完成),合并完成后会产生一个新的FsImage文件,这个过程就是检查点(checkpoint)。 |
| 《4》合并成功之后,会通过post方式将新的FsImage文件发送NameNode上。 |
| 《5》Namenode会将新接收到的FsImage替换掉旧的(即将旧的重命名),同时用edit.new替换EditLog,这样EditLog就会变小。 |
#1-【轮询间隔】SecondaryNameNode多久向NameNode发起一次轮,查询【EditLog文件中未执行检查点的累计事务数量上限】【距离上一次检查点的时长】 #单位:秒,默认值:60秒=1分钟 dfs.namenode.checkpoint.check.period #2-【时间阈值】连续两次检查点的最大时间阈值,超过该阈值就立刻触发检查点 #单位:秒,默认值:3600秒 = 1小时 dfs.namenode.checkpoint.period #3-【事务阈值】EditLog文件中的累计的未执行检查点的事务数量上限,达到阈值就立刻触发检查点 # 默认值:1000000 = 100万条事务 dfs.namenode.checkpoint.txns #应用在【hdfs-site.xml】配置文件中 <configuration> <!-- 【轮询间隔】SecondaryNameNode/CheckpointNode多久向NameNode发起一次轮询,查询待合并事务数 单位:秒,默认值:60秒 --> <property> <name>dfs.namenode.checkpoint.check.period</name> <value>60</value> </property> <!-- 【时间阈值】两次检查点之间的最大时间间隔;超过该时长触发checkpoint 单位:秒,默认值:3600秒 = 1小时 --> <property> <name>dfs.namenode.checkpoint.period</name> <value>3600</value> </property> <!-- 【事务阈值】未执行checkpoint的累积事务数量上限;达到阈值立即触发checkpoint 默认值:1000000 = 100万条事务 --> <property> <name>dfs.namenode.checkpoint.txns</name> <value>1000000</value> </property> </configuration>| SNN的核心执行逻辑 |
|---|
| ✅SNN/CheckpointNode每 dfs.namenode.checkpoint.check.period 秒询问 Active NN:当前未 checkpoint 事务数量、距离上一次 checkpoint 时长; |
✅满足任一条件,立刻执行 checkpoint:
|
✅HA 集群中,Standby NameNode 承担原来 SecondaryNameNode 的 checkpoint 逻辑,参数完全复用这套配置。 |
1.3、NameNode的元数据存储解析
元数据在Namenode中有3种存储形式,分别是【内存】、【EditLog文件】与【FsImage】文件;最完整、最新的元数据一定是内存中的这一部分。
可在NameNode服务器的【/etc/hadoop/conf/hdfs-site.xml】文件的【dfs.datanode.data.dir】节点下获取到元数据的存储路径;或者在Ambari Web管理界面的【Services-->HDFS-->CONFIGS-->SETTINGS】下查看到元数据的存储路径(如:/data/hadoop/dfs/data,/data1/hadoop/dfs/data)这两个路径存储的内容是一样的,随便进入一个路径下查看即可:
| HDFS分布式存储元数据内容 | 说明 |
|---|---|
| Edit Log | 格式:edits_事务的开始ID-事务的结束ID 示例:edits_0000000000000001026-0000000000000001027 edits_inprogress_0000000000000001058是当前正在写入的事务日志; seen_txid:保存着最后一次检查点的事务ID |
| fsimage | 格式:fsimage_事务的结束ID 示例:fsimage_0000000000000001027 从fsimage的示例中的事务ID可以判断,后续若要手动清理Edit Log文件则可以将事务ID为1027之前的EditLog文件都删除掉,因为fsimage_0000000000000001027文件已经包含了。 VERSION文件是记录着当前HDFS的版本信息 |
1.4、StandbyNameNode下JournalNode的元数据管理
StandbyNameNode下JournalNode的元数据管理(也就是说必须是双NameNode的Hadoop集群【即:激活的NameNode是主节点、standby的NameNode节点是备用节点】)。
大数据Hadoop运维应用实践——双NameNode高可用Hadoop集群架构(上)https://coffeemilk.blog.csdn.net/article/details/162849636
| StandbyNameNode下JournalNode的元数据管理解析 |
|---|
| JournalNode只在HDFS的HA模式下出现,JournalNode作为一个守护进程,实现了元数据在主、备节点的共享。JournalNode的元数据目录在hdfs-site.xml文件中通过【dfs.journalnode.edits.dir】参数指定。JournalNode的元数据包含【一个VERSION文件】、【多个edits_xx文件】与【一个edits_inprogress_xxx文件】,还包含一些与HA实现相关的文件,这些文件主要是为了防止脑裂,但JournalNode中并不包含fsimage和seen_txid文件。 |
| 在HA模式下,StandbyNameNode会周期的让主NameNode对Edit Log文件进行回滚,间隔周期由dfs.ha.log-roll.period指定,默认是120s,StandbyNameNode之所以周期性的让主NameNode回滚Edit Log,是因为StandbyNameNode不会读取inprogress的Edit Log文件,它只会周期性(dfs.ha.tail-edits.period,默认是60s)的去检测已经完成的Edit Log文件,然后将该Edit Log文件通过JournalNode读取到内存,进而更新fsimage在内存中的状态。在达到checkpoint触发条件后,新的fsimage文件会在StandbyNameNode上生成,接着,StandbyNameNode会删除自己磁盘上保留的陈旧的fsimage文件,然后将新的fsimage文件上传给主NameNode。 |
Edit Log文件的生成时每2分钟生成一个edits_xxx-xxx文件,是由【dfs.ha.log-roll.period】参数控制(默认是120秒=2分钟)。
JounalNode的元数据目录下只有Edit Log文件,没有fsimage文件,如下图所示:
StandbyNameNode(备用NameNode节点)的元数据目录下是只有【edits_inprogress_xxx】与【fsimage】文件,如下图所示:
二、HDFS读取、写入数据流程解析
2.1、HDFS分布式存储特点
| HDFS分布式存储的特点 |
|---|
| 《1》一次写入,多次读取(不可修改,只可追加)。 |
| 《2》文件由数据块(block)组成,数据块大小默认是128MB,若文件大小不足128M,则也会单独存成一个块,一个块只能存一个文件的数据,即使一个文件不足128M,也会占用一个块,块是一个逻辑空间,并不会占磁盘空间。 |
| 《3》默认情况下每个块都有三个副本,三个副本会存储到不同的节点上。副本越多,磁盘利用率越低,但是数据的安全性越高。可以通过修改hdfs-site.xml的【dfs.replication】属性设置副本的个数。 |
| 《4》文件按大小被切分成若干个块,存储到不同的节点上,块大小可通过配置文件进行配置或修改。 |
2.2、客户端读取HDFS分布式存储数据流程
| 客户端读取HDFS分布式存储数据流程(如上图所示) |
|---|
| 《1》客户端向Namenode请求读取一个文件,Namenode通过查询元数据,找到请求文件对应的数据块所在的位置,也就是块文件对应的datanode节点地址。 |
| 《2》Namenode返回自己查询到的元数据信息给客户端。 |
| 《3》客户端挑选一台Datanode(根据就近原则,然后随机原则)服务器,开始请求读取数据。 |
| 《4》datanode开始传输数据给客户端(从磁盘里面读取数据放入流,以packet为单位来做校验)。 |
| 《5》客户端以packet为单位接收,先在本地缓存,然后写入目标文件。 |
2.3、客户端写入数据到HDFS分布式存储流程
| 客户端写入数据到HDFS分布式存储流程(如上图所示) |
|---|
| 《1》客户端(Client)对Namenode发起上传文件的请求,Namenode接到请求后,马上检查请求文件是否已存在,上级目录是否存在。 |
| 《2》Namenode检查发现,请求的文件如果不存在,那么就响应客户端请求,可以上传文件。 |
| 《3》客户端(Client)首先对文件进行切分(假定HDFS的一个块(block)大小是128M,如果写入的文件大小有300M,那么此文件就会被切分成3个块,分别是两个128M和一个44M),接着,客户端向Namenode发起请求第一个block该传输到哪些datanode服务器上。 |
| 《4》Namenode返回信息给客户端(Client),告知可以上传到哪些datanode服务节点上(这里假定有三个副本,所以一个块需要上传到三个节点上,这里设定上传到A、B、C三个datanode节点)。 |
| 《5》Client开始和Datanode建立传输通道(首先请求datanode A节点上传数据(本质上是一个RPC调用,建立pipeline),Datanode A收到请求后,会继续调用Datanode B,然后Datanode B再去调用第三个datanode C,将整个pipeline建立完成,逐级返回Client)。 |
| 《6》Client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(一个packet为64kb),Datanode A收到一个packet就会传给Datanode B,Datanode B接着传给Datanode C;Datanode A每传一个packet会放入一个应答队列,等待应答。 |
| 《7》当一个block传输完成之后,Client再次请求Namenode开始上传第二个block,上传过程重复上面4-6步骤。 |
三、HDFS Shell操作
3.1、查看HDFS文件系统上文件
#查看HDFS文件系统上文件 su - hadoop hadoop fs -ls / hadoop fs -ls /user hadoop fs -cat /logs/coffeemilk/test.txt #通过-text可查看压缩文件的内容,支持场景的zip、gzip、bzip2等压缩格式 hadoop fs -text /logs/coffeemilk/nginx-1.28.0.tar.gz3.2、HDFS文件系统中增加文件
#HDFS文件系统中增加文件 hadoop fs -mkdir -p /logs/coffeemilk hadoop fs -touch /logs/coffeemilk/text.txt #将本地的/data/nginx-1.28.0.tar.gz文件上传到HDFS分布式存储下的/logs/coffeemilk目录 hadoop fs -put /data/nginx-1.28.0.tar.gz /logs/coffeemilk #将HDFS分布式存储下的/logs/coffeemilk/nginx-1.28.0.tar.gz文件拉取到本地的/home/hadoop目录下 hadoop fs -get /logs/coffeemilk/nginx-1.28.0.tar.gz /home/hadoop3.3、HDFS文件系统中移动文件
#HDFS文件系统中移动文件 #移动文件可以实现本地磁盘文件移动到HDFS、HDFS上各个路径直接的移动、文件改名等操作 #1-两个路径均为HDFS上路径 hadoop fs -mv /logs/coffeemilk/nginx-1.28.0.tar.gz /tmp #将本地/data/mysql-8.4.5-linux-glibc2.28-x86_64.tar.xz文件上传到HDFS的/tmp目录下 hadoop fs -moveFromLocal /data/mysql-8.4.5-linux-glibc2.28-x86_64.tar.xz /tmp3.4、HDFS文件系统中删除文件
#HDFS文件系统中删除文件 #1-无论是文件或者目录,都可以通过如下命令进行删除 hadoop fs -rm -r /logs/coffeemilk/text.txt #2-如果你确定这个某个文件可以删除,不需要进入回收站的话,可以执行如下命令 hadoop fs -rm -r -skipTrash /tmp/nginx-1.28.0.tar.gz #-只看HDFS回收站可恢复文件 hdfs dfs -ls /user/hadoop/.Trash/Current # 递归查看所有文件 hdfs dfs -ls -R /user/hadoop/.Trash/Current #3-要清空HDFS回收站,可执行如下命令 hadoop fs -expunge3.5、HDFS文件系统中追加文件内容
#HDFS文件系统中追加文件内容 #HDFS上的文件不能修改,但可以在文件最后追加内容,要对一个已经存在的文件追加内容 #1-将本地coffeemilk.log文件的内容追加到HDFS的/logs/coffeemilk.log文件的最后 echo "this is append info test 666">>coffeemilk.log hadoop fs -appendToFile coffeemilk.log /logs/coffeemilk.log #2-管道直接追加,不产生本地文件 echo "direct add info 777" | hdfs dfs -appendToFile - /logs/coffeemilk.log3.6、HDFS文件系统中对文件进行授权
#HDFS文件系统中对文件进行授权 #对文件或目录进行授权,主要使用了linux上的两个命令chown和chmod,hdfs上授权文件的用法如下 hadoop fs -chown -R hadoop:hadoop /logs/coffeemilk.log hadoop fs -chmod 744 /logs/coffeemilk.log