Hadoop的集群搭建(HA),HDFS的工作流程(读、写、nn和snn)、负载均衡、安全模式、基本配置、命令等

Hadoop理论

hadoop的优势

1.高可靠性:维护了多个数据副本,即使某个节点出现错误也不会导致数据丢失。
2. 高扩展性:集群间分配任务数据,可以方便扩展节 点。
3. 高效性:在MapReduce的思想下,Hadoop是并行工作的。
4. 高可靠性:能够自动将失败的任务重新分配给其他节点。
5. 适合批处理:移动计算而非数据,将数据位置暴露给计算框架(数据块Block,每个数据块有一个Id标识);
6. 保证数据一致性(参考);

VM集群配置的基本步骤

  1. 安装虚拟机,设置主机名,配置网络。参考
  2. 最小系统需要安装软件仓库,工具包(ifconfig等命令),vim(编辑器)
    2.1 yum install -y epel-release
    2.2 yum install -y net-tools
    2.3 yum install -y vim
  3. 关闭防火墙
    3.1关闭防火墙 systemctl stop firewalld
    3.2关闭防火墙自启动 systemctl disable firewalld.service
  4. 创建用户(xrl),修改其权限
    4.1设置用户 useradd xrl
    4.2设置密码 passwd xrl
    4.3配置权限,在/etc/sudoers文件的%wheel ALL=(ALL) ALL这一行下面插入 xrl ALL=(ALL) NOPASSWD:ALL
  5. 创建软件放置的位置:
    5.1 在/opt目录下mkdir ./module ./software文件夹
    5.2修改两个文件的所有者为xrl用户:chown xrl:xrl 【文件夹路径】
  6. 安装jdk:
    6.1 如果有jdk先删除:rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps 然后重启虚拟机reboot
    【rpm -qa:查询所安装的所有rpm软件包】
    【grep -i:忽略大小写】
    【xargs -n1:表示每次只传递一个参数】
    【rpm -e –nodeps:强制卸载软件】
    6.2 利用Shell,将文件导入/opt/software/目录。并解压到/opt/module目录,tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/module/
  7. 安装hadoop
    7.1 利用Shell,将文件导入/opt/software/目录。并解压到/opt/module目录,tar -zxvf hadoop-3.3.1.tar.gz -C /opt/module/
  8. 配置环境变量
    8.1 sudo vim /etc/profile.d/my_env.sh 创建一个文件,存放我们配置的环境变量。
    8.2 添加内容:export 是将变量发布,$ PATH:$JAVA_HOME/bin向PATH后面追加环境变量
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$ PATH:$JAVA_HOME/bin

#HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-3.3.1
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin

8.3 让环境变量生效 source /etc/profile
8.4 测试:hadoop version 、jdk version 不能使用则重启虚拟机;

  1. 复制三台虚拟机,修改ip地址和主机名称;
  2. SSH免密登录配置:
    10.1 在hadoop102上用xrl用户操作:cd /home/atguigu/.ssh
    10.2 生成公钥(id_rsa.pub)和私钥(id_rsa):ssh-keygen -t rsa
    10.3 将公钥拷贝的想要免密登录的目标机器102、103、10.4:ssh-copy-id hadoop102
    10.5:然后在hadoop103,hadoop104、hadoop102的root用户上进行相同操作,

修改hadoop配置文件

  1. 默认文件 存储路径
    [core-default.xml] hadoop-common-3.3.1.jar/core-default.xml
    [hdfs-default.xml] hadoop-hdfs-3.3.1.jar/hdfs-default.xml
    [yarn-default.xml] hadoop-yarn-common-3.3.1.jar/yarn-default.xml
    [mapred-default.xml] hadoop-mapreduce-client-core-3.3.1.jar/mapred-default.xml
  2. 自定义配置文件在$HADOOP_HOME/etc/hadoop这个路径下,有:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml
  3. 核心配置文件core-site.xml:
 <!-- 指定NameNode的地址 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop102:9000</value>
    </property>

    <!-- 指定hadoop数据的存储目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-3.3.1/data</value>
    </property>

    <!-- 配置HDFS网页登录使用的静态用户为xrl,可以在web界面上操作HDFS-->
    <property>
        <name>hadoop.http.staticuser.user</name>
        <value>xrl</value>
    </property>
   <!-- 主类的配置,如果启动报找不到类的错误配置-->
<property>
        <name>yarn.application.classpath</name>
        <value>/opt/module/hadoop-3.3.1/etc/hadoop:/opt/module/hadoop-3.3.1/share/hadoop/common/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/common/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/*:/opt/module/hadoop-3.3.1/share/hadoop/mapreduce/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn:/opt/module/hadoop-3.3.1/share/hadoop/yarn/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn/*</value>
</property>

  1. HDFS配置文件hdfs-site.xml:
<configuration>
	<!-- 文件副本数-->
	<property>
	        <name>dfs.replication</name>
	        <value>3</value>
	 </property>
	 <property>

	<!-- nn web端访问地址-->
	<property>
        <name>dfs.namenode.http-address</name>
        <value>hadoop102:9870</value>
    </property>
	<!-- 2nn web端访问地址-->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>hadoop104:9868</value>
    </property>
</configuration>

  1. YARN配置文件yarn-site.xml:
<configuration>
<!-- 指定MR走shuffle -->
<property>
     <name>yarn.nodemanager.aux-services</name>
     <value>mapreduce_shuffle</value>
</property>

<!-- 指定ResourceManager的地址-->
<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>hadoop103</value>
</property>
<!-- 开启日志聚集功能 -->
<property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property>  
    <name>yarn.log.server.url</name>  
	<value>http://hadoop102:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为7-->
<property>
    <name>yarn.log-aggregation.retain-seconds</name>
    <value>604800</value>
</property>


  1. MapReduce配置文件mapred-site.xml
<configuration>
	<!-- 指定MapReduce程序运行在Yarn-->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
<!-- 历史服务器端地址 -->
<property>
    <name>mapreduce.jobhistory.address</name>
    <value>hadoop102:10020</value>
</property>
<!-- 历史服务器web端地址 -->
<property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>hadoop102:19888</value>
</property>

</configuration>
  1. 配置workers,hadoop2.X版本是slaves文件,添加以下内容
hadoop102
hadoop103
hadoop104
  1. 分发配置xsync ./

基本测试(格式化、启动、停止),hadoop-3.3.1目录下:

13.1 格式化NameNode:hdfs namenode -format;如果不是第一次格式化需要停止NameNode和DataNode,删除所有机器上的data和logs目录,否则因为格式化后NameNode中保存了集群id,启动集群后DataNode也会保存与NameNode一样的集群id,如果再次格式化NameNode会新生成一个集群id,这个集群id与为删除的DataNode中的集群id不一致。
13.2 启动hdfs:sbin/start-dfs.sh
13.3 启动yarn:sbin/start-yarn.sh
13.4 查看hdfs和yarn的web页面:http://hadoop102:9870,http://hadoop103:8088
13.5 创建一个文件夹,hadoop fs -mkdir /input
13.6 上传一个文件,hadoop fs -put /opt/software/jdk-8u212-linux-x64.tar.gz /
13.7 在目录下有test文件,执行wordcount程序 :hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar wordcount /input /test;观察http://hadoop102:19888/jobhistory历史服务器历史任务。
14. 集群启动/停止方式:
14.1 整体停止/启动HDFS:start-dfs.sh/stop-dfs.sh
14.1 整体停止/启动YARN:start-yarn.sh/stop-yarn.sh
14.3 分别启动/停止hdfs组件:hadoop-daemon.sh start/stop 【namenode/datanode…】
14.4 别启动/停止YARN:yarn --daemon start/stop resourcemanager/nodemanager
15. 集群时间同步

集群脚本编写/home/xrl/bin目录下:

  1. 集群分发脚本xsync,创建xsync文件写入以下内容:
#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]
then
    echo Not Enough Arguement!
    exit;
fi

#2. 遍历集群所有机器
for host in hadoop102 hadoop103 hadoop104
do
    echo ====================  $host  ====================
    #3. 遍历所有目录,挨个发送

    for file in $@
    do
        #4. 判断文件是否存在
        if [ -e $file ]
            then
                #5. 获取父目录
                pdir=$(cd -P $(dirname $file); pwd)

                #6. 获取当前文件的名称
                fname=$(basename $file)
                ssh $host "mkdir -p $pdir"
                rsync -av $pdir/$fname $host:$pdir
            else
                echo $file does not exists!
        fi
    done
done

1.1 修改xsync的执行权限:chmod +x xsync
1.1 将脚本复制到bin中,以便全局调用:sudo cp xsync /bin/
1.1同步环境变量配置 sudo ./bin/xsync /etc/profile.d/my_env.sh
1.1 让环境变量生效:source /etc/profile
1.1 测试分发:xsync /home/xrl/bin;观察hadoop103 104上是否有这个文件了。

  1. Hadoop集群启停脚本myhadoop.sh:
#!/bin/bash

if [ $# -lt 1 ]
then
    echo "No Args Input..."
    exit ;
fi

case $1 in
"start")
        echo " =================== 启动 hadoop集群 ==================="

        echo " --------------- 启动 hdfs ---------------"
        ssh hadoop102 "/opt/module/hadoop-3.3.1/sbin/start-dfs.sh"
        echo " --------------- 启动 yarn ---------------"
        ssh hadoop103 "/opt/module/hadoop-3.3.1/sbin/start-yarn.sh"
        echo " --------------- 启动 historyserver ---------------"
        ssh hadoop102 "/opt/module/hadoop-3.3.1/bin/mapred --daemon start historyserver"
;;
"stop")
        echo " =================== 关闭 hadoop集群 ==================="

        echo " --------------- 关闭 historyserver ---------------"
        ssh hadoop102 "/opt/module/hadoop-3.3.1/bin/mapred --daemon stop historyserver"
        echo " --------------- 关闭 yarn ---------------"
        ssh hadoop103 "/opt/module/hadoop-3.3.1/sbin/stop-yarn.sh"
        echo " --------------- 关闭 hdfs ---------------"
        ssh hadoop102 "/opt/module/hadoop-3.3.1/sbin/stop-dfs.sh"
;;
*)
    echo "Input Args Error..."
;;
esac

2.1 chmod +x myhadoop.sh
2.2 分发这个脚本 xsync ./

  1. jpsall查看节点类型
#!/bin/bash
for host in hadoop102 hadoop103 hadoop104
do
        echo =============== $host ===============
        ssh $host jps 
done

3.1 chmod +x jpsall
3.2 分发这个脚本 xsync ./

Hdoop-HDFS

定义

1. HDFS的是基于流数据模式访问(来了一点数据,就立马处理掉,立马分发到各个存储节点来响应分析、查询等,重点关注数据的吞吐量而不是访问速度)和处理超大文件的需求而开发的一个主从架构的分布式文件系统(分布式文件系统:一种允许文件透过网络在多台主机上分享的文件系统,可让多机器上的多用户分享文件和存储空间);
2. 流式数据:  将数据序列化为字节流来存储;
3. 序列化:对文件进行切片就需要该文件支持序列化;
4. 存储文件,通过目录树定位文件;
6. 适合一次写入,多次读出的场景。一个文件只能有一个写者,只能进行append追加内容,不能修改。

优缺点

优点
1. 高容错性:数据保存了多个副本,一个副本丢失或者损坏,可以自动恢复,默认保存三个副本。
2. 适合处理大数据,可以处理的数据规模和文件规模巨大。
3. 可以构建在廉价机器上,数据保存多副本的机制提高了可靠性
4. 适合处理离线数据,不适合处理实时数据。
5. 可以处理:结构化(关系型)、半结构化(word,ppt)、非结构化(视频,音频)数据;
缺点
7. 不适合低延时的数据访问;(hadoop针对高数据吞吐量做了优化,牺牲了获取数据延迟)
8. 无法高效的对小文件进行存储。因为,大量的小文件会大量占用NameNode的内存来存储文件目录和块信息。并且会影响文件存储地址的寻址时间。解决办法:通过SequenceFile 将小文件合并。
9. 不支持并发写入和文件随机修改,只支持数据的追加,不能修改。

组成架构

HDFS 具有主/从架构。HDFS组成架构

NameNode(nn):

  1. 处理客户端的读写请求。
  2. 管理数据块(Block)的映射信息。每个文件的块列表和块所在的DataNode等;
  3. 配置副本策略;
  4. 储存文件的元数据(文件、目录自身的属性信息,例如文件名,目录名,修改信息等;文件记录的信息的存储相关的信息,例如存储块信息,分块情况,副本个数等;记录 HDFS 的 Datanode 的信息,用于 DataNode 的管理);
  5. 负责管理数据块的副本,按一定周期,接受来自每个DataNode的心跳信号和块状态报告。心跳用于判断datanode是否正常,块状态报告则关于某个datanode上存储的所有数据块的列表.。

DataNode(dn):

  1. 存储实际的数据块。
  2. 执行NameNode的下达的命令,执行数据块的读写操作。
  3. 在启动时向NameNode进行注册并周期性(默认6小时)的向NameNode上报所有块信息。
  4. 周期性的扫描自己节点块的信息(默认6小时)。
  5. 向DataNode维持(默认三秒)的心跳(带有 Block块的使用情况),NameNode返回心跳的结果(带有NameNode该给哪个DataNode的命令,如复制块数据到另一台机器,或删除某个块数据),如果超过十分钟+30秒(默认,超时时间 = 2* dfs.namenode.heartbeat.recheck-interval(超时时长,默认5分钟)+ dfs.heartbeat.interval(心跳时长,3s))NameNode没有收到某个DataNode的心跳,则认为该节点不可用,NameNode会检查不可用的DeadNode中的副本数据,复制到其他的DeadNode中。
  6. DataNode还有一个自检功能,数据块创建3周后,自动触发校验和运算,以保证集群中数据块的安全。

数据块(Block):

  1. HDFS中文件是分块存储的,数据块以文件的方式存储了实际数据;
  2. 默认存在三个副本;查看(hdfs fsck -locations),可以通过hdfs-site.xml配置文件修改(dfs.replication),可以通过命令修改已上传的文件副本数(hadoop fs -setrep -R 3 /),可以上传文件时指定(hdfs dfs -Ddfs.replication=1 -put core-site.xml /)
    3.块的大小默认为128MB,最佳状态为:寻址时间为传输时间的1%。大小主要取决于磁盘传输速率(不宜太小也不宜太大)。机械硬盘一般设置为128MB,固态一般设置为256MB
  3. 包含两个文件:一个是数据本身,另一个是数据快的长度,时间戳和数据快的校验和(CRC算法计算校验和,保证数据的完整性)

Secondary(2nn):

  1. 每隔一段时间对NameNode进行备份,并帮助NameNode进行Edits和Fsimage进行合并,生成新的Fsimage并拷贝到NameNode中。紧急情况下可辅助恢复NameNode。
  2. Edits(日志文件):记录HDFS文件系统的更新操作,客户端执行的操作会先被记录到Edits文件中,Edits文件只能追加内容。
  3. Fsimage(镜像):是元数据的一个持久化的检查点,包含 Hadoop 文件系统中的所有目录和文件元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,是在 datanode 加入集群的时候,namenode 询问 datanode 得到的,并且间断的更新。

Client(客户端):

  1. 文件切分。文件上传HDFS的时候Client将文件切分成一个一个的Bock,然后进行上传;
  2. 与NameNode交互,获取文件的位置信息;
  3. 与DataNode交互,读取或者写入数据:
  4. Client提供一些命令来管理DFS,比NameNode格式化、磁盘整理等;
  5. Client可以通过一些命令来访问HDFS,比如:对HDFS增删改查操作;

工作流程

HDFS数据读写流程

HDFS数据写入流程

数据写入的流程图

  1. Client(客户端)先创建一个DistributedFileSystem(分布式的文件系统),向NameNode请求上传文件。

  2. NameNode对Client请求上传文件路径的权限和结构(是否已经存在)进行检查,并给与Client回复。

  3. Client收到NameNode的允许上传的回复,则向NameNode请求上传,文件切分生成的数据块(Block)。

  4. NameNode收到Block上传的请求,通过机架感知算法计算出存储数据的节点(默认三个),回复给Client。

  5. Client收到NameNode的回复后,创建FSDataOutputStream数据流系统,并向DataNode请求建立Block传输通道(只向一个DataNode请求,通过DataNode的节点距离和负载情况选择,然后由这个DataNode节点再向其他DataNode节点请求建立通道,通道建立成功,给请求建立通道的节点应答成功,所有节点应答成功后,由于Client建立通道的节点给Client回复应答成功)。

  6. Client收到DataNode的应答成功信号,往第一个DataNode上传Block【先从磁盘读取数据(有一个一个与chunk大小相同的缓存ByteBuffer,读满或者强制flush后会计算出一个chunksum(校验码)】放到一个本地内存缓存中【chunk(512byte数据 )+chunksum (4byte校验位)】,从内存中读取chunk组成一个Packet【chunk + chunksum = 516byte,组合成一个packet(64k)】放入一个缓冲队列中,然后以Packet为单位,从缓冲队列中取出数据往DataNode上传(生产者消费者模式),第一个DataNode收到一个Packet就会传给后面的节点,每传一个Packet会放入一个ACK队列(缓冲队列)等待所有需要存储这个数据的DataNode节点全部应答成功后,在ACK队列中将这个数据删除。
    6.1数据缓存说明:做了三层缓存chunk、packet、packetBufferQueue;
    6.2数据安全:使用了一个ACK队列记录要上传的packet,防止传输过程中传输失败或异常导致数据丢失;
    6.3使用了生产者消费者模式,来从packetBufferQueue中添加或取出数据,阻塞生产者的条件是packetBufferQueue+ACK之和超过一个Block的packet上限。

  7. 细节:
    1.请求和应答是使用RPC的方式,客户端通过ClientProtocol与namenode:通信,namenode和datanode之间使用DatanodeProtocol交互。在设计上,namenode不会主动发起RPC,而是响应来自客户端或datanode的RPC请求。客户端和datanode之间是使用socket进行数据传输,和namenode之间的交互采用nio封装的RPC。
    2.HDFS有自己的序列化协议。
    3.在数据块传输成功后但客户端没有告诉namenode之前如果namenode宕机那么这个数据块就会丢失。
    4.在流式复制时,逐级传输和响应采用响应队列来等待传输结果。队列响应完成后返回给客户瑞
    5.在流式复制时如果有一台或两台(不是全部)没有复制成功,不影响最后结果,只不过datanode会定期向namenode汇报自身信息。如果发现异常namenode会指挥datanode删除残余数据和完善副本。如果副本数量少于某个最小值就会进入安全模式。

节点距离:两个节点到达最近的共同服务器的距离总和。

机架感知:

查看代码:hdfs dfsadmin -printTopology
官网说明:对于常见情况,当复制因子为三个时,HDFS的位置策略是在dataNode上,在本地计算机上放置一个副本,否则在随机datanode上,在其他(远程)机架中的节点上的另一个副本, ,以及同一远程机架中不同节点上的最后一个。该策略削减了机间写入流量,通常会改善写作绩效。机架故障的机会远低于节点故障。该策略不会影响数据可靠性和可用性保证。但是,由于仅将块放置在两个唯一的机架中,而不是三个。通过此策略,文件的复制品不会在机架上均匀分布。三分之一的复制品是在一个节点上,三分之二的复制品在一个架子上,另一个副本均匀分布在其余的架子上。该策略可改善读写性能,而不会损害数据可靠性或读写性能。
存储节点的选择
第一个保证读写效率,第二个保证可靠性,第三个在保证可靠性的条件下兼顾效率。

HDFS读数据

读数据流程图

  1. Client创建DistributedFileSystem ----发送读请求(读取文件的路径)----> NameNode
  2. NameNode对请求信息进行检查(文件是否存在,访问权限等),可以读 -----返回文件的元数据(文件元数据信息,文件块位置信息等)----->Client
  3. Client创建FSDataOutputStream数据流系统,然后根据NameNode回复的信息(构成文件的文件块顺序、文件块位置等)串行读取数据(DataNode以chunk为单位输出,Client以Packet为单位接收,先在本地缓存,然后写入目标文件)。读取数据时存在多个副本,读取节点根据节点距离和负载情况进行选择。

NameNode和SecondaryNameNode工作机制

 NameNode和SecondaryNameNode工作机制
NameNode工作:

  1. 第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载Fsimage和Edits文件到内存(将Fsimage文件读入内存,加载Edits里面的更新操作)。保证内存中的元数据是最新的、同步的。
    中的元数据信息是最新的、同步的。
  2. seen_txid,保存的是一个事务ID,这个事务ID是EditLog最新的一个结束事务id,当NameNode重启时,会顺序遍历从edits_0000000000000000001到seen_txid所记录的txid所在的日志文件,进行元数据恢复,如果该文件丢失或记录的事务ID有问题,会造成数据块信息的丢失;
  3. clent对元数据进行增删改的请求。
  4. NameNode中的Edits文件记录操作日志,更新滚动日志(往后追加不能修改)。
  5. 在内存中对元数据进行增删改。

Secondary NameNode工作:

  1. Secondary NameNode询问NameNode是否需要CheckPoint。触发条件:周期时间(默认一小时)到了,Edits数据(默认一百万条)满了。
  2. Secondary NameNode请求执行CheckPoint。
  3. NameNode保存当前的Edits文件,并生成一个新的Edits文件NewEdits,之后的操作记录到NewEdits中。
  4. 将滚动前的Fsimage和Edits文件拷贝到Secondary NameNode。
  5. Secondary NameNode加载Fsimage和Edits文件到内存,并合并。
  6. 生成新的镜像文件fsimage.chkpoint,并将fsimage.chkpoint通过RPC传回NameNode。
  7. NameNode将fsimage.chkpoint重新命名成fsimage。
  8. 之后NameNode将fsimage和NewEdits文件加载到内存就可以得到最新的元数据。

NameNode和Secondary NameNode相差最新的Edits,如果使用Secondary NameNode恢复NameNode数据,这部分的数据更新操作会丢失。

负载均衡

  1. 解决的问题:DataNode节点之间容易出现数据存储不平衡(数据倾斜)的情况,例如:当集群内新增、删除节点、某个节点的数据块损坏、或者某个节点的存储量达到饱和值时都会导致数据倾斜的情况。当存在数据倾斜时,使用MapReduce进行分布式运算时,如果运算任务如果分配到存储数据很少的节点上,会导致网络带宽的消耗,分配到存储数据很多的节点时,会导致得到运算结果所需要的时长增加。
  2. 原则:当HDFS负载不均衡时,需要对HDFS进行数据的负载均衡调整,即对各DataNode节点上数据的存储分布进行调整。从而,让数据均匀的分布在各个DataNode上,均衡IO性能。它应该满足以下几个原则:
    1.数据平衡不能导致数据块减少,数据块备份丢失;
    2.管理员可以中止数据平衡进程;
    3.每次移动的数据量以及占用的网络资源,必须是可控的(不影响Hadoop使用);
    4.数据均衡过程,不能影响namenode的正常工作;
  3. 运行步骤:
    在这里插入图片描述
    (1)数据均衡服务(Rebalancing Server)首先要求 NameNode 生成 DataNode 数据分布分析报告,获取每个DataNode磁盘使用情况;
    (2)Rebalancing Server汇总需要移动的数据分布情况;
    ——2.1 HDFS会把当前的DataNode节点,根据设定的阈值和当前集群的平均值,将其划分到Over(高于阈值,数据过多)、Above(高于平均值)、Below(低于平均值)、Under(低于阈值,数据过少)四个组中。在移动数据块的时候,Over组、Above组中的块向Below组、Under组移动。
    (3)计算具体数据块迁移路线图。数据块迁移路线图,确保网络内最短路径(节点距离最近,提高数据传输效率);
    (4)开始数据块迁移任务,Proxy Source Data Node复制一块需要移动数据块;
    (5)将复制的数据块复制到目标DataNode上(通过校验码保证数据的准确性);
    (6)删除原始数据块;
    (7)目标DataNode向Proxy Source Data Node确认该数据块迁移完成;
    (8)Proxy Source Data Node向Rebalancing Server确认本次数据块迁移完成。然后继续执行这个过程,直至集群达到数据均衡标准;
  4. 运行
    4.1 启动start-balancer.sh
    -threshold:判断集群是否平衡的阈值,可以不指定,默认为10。
    4.2 停止 stop-balancer.sh
    4.3 在hdfs-site.xml文件中可以设置数据均衡占用的网络带宽限制(确保hadoop可以正常使用):
<property>
    <name>dfs.balance.bandwidthPerSec</name>
    <value>1048576</value>
    </property>

4.5 定时任务

00 22 * * 5 hdfs balancer -Threshold 5 >>/home/logs/balancer_`date +"\%Y\%m\%d"`.log 

安全模式

  1. 安全模式指在不加载第三方设备驱动情况下启动机器,便于检测与修复
  2. 应用场景:①启动或者重新启动hdfs时;②HDFS维护升级时
  3. 操作:
    退出安全模式:hdfs dfsadmin -safemode leave
    进入安全模式 :hdfs dfsadmin -safemode enter
    查看安全模式状态:hdfs dfsadmin -safemode get
    等待,直到安全模式结束:hdfs dfsadmin -safemode wait

文件系统检查

hdfs fsck 【文件路径】
	-move: 移动损坏的文件到/lost+found目录下
	-delete: 删除损坏的文件
	-files: 输出正在被检测的文件
	-openforwrite: 输出检测中的正在被写的文件
	-includeSnapshots: 检测的文件包括系统snapShot快照目录下的
	-list-corruptfileblocks: 输出损坏的块及其所属的文件
	-blocks: 输出block的详细报告
	-locations: 输出block的位置信息
	-racks: 输出block的网络拓扑结构信息
	-storagepolicies: 输出block的存储策略信息
	-blockId: 输出指定blockId所属块的状况,位置等信息
API实现步骤和源码(参考

部分配置设置

  1. Secondary NameNode和NameNode,CheckPoint条件设置(hdfs-site.xml):
    1.1 时间:< name > dfs.namenode.checkpoint.period< /name >
    1.2 操作次数:< name > dfs.namenode.checkpoint.txns < /name >
    1.3 检查一次操作次数间隔时长:< name > dfs.namenode.checkpoint.check.period< /name>
  2. DataNode向NameNode汇报节点信息周期时间和扫描自己节点块信息列表的时间设置:
    2.1汇报节点信息周期时间:< name> dfs.blockreport.intervalMsec < /name>
    2.2扫描自己节点块信息列表的周期时间:< name>dfs.datanode.directoryscan.interval< /name>
  3. DataNode掉线时限参数设置:
    3.1超时时长(毫秒): < name>dfs.namenode.heartbeat.recheck-interval< /name>
    3.2心跳时长(秒)< name>dfs.heartbeat.interval</ name>

基本Shell命令和API操作

基本文件系统Shell命令(官方文档):

hadoop fs == hdfs dfs

  1. 上传
    1.1 从本地剪切:hadoop fs -moveFromLocal 【本地文件路径】 【HDFS路径】
    1.2 从本地拷贝:hadoop fs -copyFromLocal 【本地文件路径】 【HDFS路径】
    1.3 从本地拷贝:hadoop fs put 【本地文件路径】 【HDFS路径】
    1.4 追加一个文件到另一个文件末尾:hadoop fs -appendToFile 【追加文件路径】 【待追加文件路径】
  2. 下载
    2.1:hadoop fs -copuToLocal 【HDFS文件路径】 【本地路径】
    2.2:hadoop fs -get 【HDFS文件路径】 【本地路径】
  3. 显示目录信息:hadoop fs -ls 【查看目录路径】
  4. 查看文件内容:hadoop fs -cat 【文件路径】
  5. 显示文件末尾1kb数据:hadoop fs -tail 【文件路径】
  6. 创建路径:hadoop fs -mkdir 【目录路径】
  7. 拷贝文件:hadoop fs -cp 【原文件路径】【文件路径】
  8. 移动文件:hadoop fs -mv 【文件路径】 【移动到(路径)】
  9. 删除文件或文件夹:hadoop fs -rm 【文件路径】
    9.1 hadoop fs -rm -r【文件路径】(递归删除)
  10. 统计文件大小:hadoop fs -du 【文件目录路径】
  11. 查询某一个文件所占用块数及相关的数据信息:hdfs fsck 【文件路径】 -files -locations -includeSnapshots -blocks -racks -storagepolicies
  12. 设置HDFS中的文件副本数量: hadoop fs -setrep 【副本数量】 【修改文件的路径】
  13. 文件权限操作:
    12.1 权限设置:hadoop fs -chmod 666 【文件路径】
    12.2 文件所属者设置:hadoop fs -chown xrl:xrl 【文件路径】
  14. 查看Fsimage和Edits,hadoop-3.3.1/data/tmp/dfs/name/current目录下:
    13.1 hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径
    13.1.1 hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-3.3.1/fsimage.xml
    13.1.2 cat /opt/module/hadoop-3.3.1/fsimage.xml
    13.2 hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径
    13.2.1 hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-3.3.1/edits.xml
    13.2.2 cat /opt/module/hadoop-3.3.1/edits.xml
  15. version查看版本:hadoop version
  16. classpath查看类路径: hadoop classpath

HDFS命令 (参考)(官方文档

  1. 格式化、启动、停止参考上文中VM集群配置的基本步骤中的基本测试;
  2. hdfs dfsadmin 命令集
  3. hdfs fsck 运行HDFS文件系统检查工具
  4. hdfs getconf 命令集
  5. hdfs jar 运行jar文件。用户可以把他们的Map Reduce代码捆绑到jar文件中,使用这个命令执行。
  6. hdfs job 用于和Map Reduce作业交互和命令。
  7. hdfs balancer

API操作:

HA(High Available)机制

解决问题

只有一个NameNode节点时,如果NameNode挂掉时,集群基本不可用。(单点故障)
NameNode的内存有限(内存受限)	

NameNode高可用(HA)

架构图
  1. 使用了两个NameNode架构,解决了单点故障问题;
  2. 借助了共享存储系统(JournalNode集群)来保证元数据的同步,共享存储系统类型一般有几类,如:Shared NAS+NFS、BookKeeper、BackupNode 和 Quorum Journal Manager(QJM)
  3. 使用了zookeeper来进行选举active节点;
    在这里插入图片描述
QJM(Quorum Journal Manager)共享存储机制和主备切换机制(参考
配置修改
配置zookeeper集群
  1. 进入conf目录,修改zoo_sample.cfg并重命名zoo.cfg:mv zoo_sample.cfg zoo.cfg;
  2. 修改zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
# 数据存储地址,提前创建这个目录(注意目录权限)
dataDir=/opt/module/zookeeper-3.7.0/zkData
# 配置zookeeper集群的服务器编号以及对应的主机名、通信端口号(心跳端口号)和选举端口号
server.1=hadoop102:2888:3888
server.2=hadoop103:2888:3888
server.3=hadoop104:2888:3888
clientPort=2181
  1. 在dataDir=/opt/module/zookeeper-3.7.0/zkData这个目录下创建myir文件,haoop102设置1,103设置2,以此类推;
  2. 修改环境变量/etc/profile.d/my_env.sh
export ZK_HOME=/opt/module/zookeeper-3.7.0
export PATH=$PATH:$ZK_HOME/bin
  1. 编写启动、停止脚本
#!/bin/bash
case $1 in
        "start"){
                for i in hadoop102 hadoop103 hadoop104
                do
                         echo ---------- zookeeper $i 启动 ------------
                         ssh $i "/opt/module/zookeeper-3.7.0/bin/zkServer.sh start"
                 done
         };;
 "stop"){
         for i in hadoop102 hadoop103 hadoop104
         do
                  echo ---------- zookeeper $i 停止 ------------
                  ssh $i "/opt/module/zookeeper-3.7.0/bin/zkServer.sh stop"
          done
  };;
  "status"){
          for i in hadoop102 hadoop103 hadoop104
          do
                   echo ---------- zookeeper $i 状态 ------------
                   ssh $i "/opt/module/zookeeper-3.7.0/bin/zkServer.sh status"
           done
   };;
   esac
  1. 运行
配置文件修改
  1. core-site.xml
<configuration>
 <!-- 指定NameNode:的地址 -->
 <property>
         <name>fs.defaultFS</name>
         <value>hdfs://xrlhadoop</value>
</property>
<!-- 指定hadoop数据的存储目录 -->
<property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-3.3.1/data</value>
</property>
<!-- 配置HDFS网页登录使用的静态用户为xrl-->
<property>
        <name>hadoop.http.staticuser.user</name>
        <value>xrl</value>
</property>
<!--zookeeper集群地址,集群以逗号进行分隔-->
<property>
        <name>ha.zookeeper.quorum</name>
        <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!-- hadoop链接zookeeper的超时时长设置 -->
<property>
        <name>ha.zookeeper.session-timeout.ms</name>
        <value>2000</value>
        <description>ms</description>
</property>
</configuration>

  1. hdfs-site.xml
<configuration>
<property>
	<name>dfs.replication</name>
	<value>3</value>
</property>

<!--权限配置, 可以控制各用户之间的权限,这里先关掉 -->
<property>
	<name>dfs.permissions</name>
	<value>false</value> 
</property>
<property>
	<name>dfs.permissions.enabled</name>
	<value>false</value> 
</property>

 <!--指定hdfs的nameservice为cluster1,需要和core-site.xml中的保持一致
 dfs.ha.namenodes.[nameservice id]为在nameservice中的每一个NameNode设置唯一标示符。
	配置一个逗号分隔的NameNode ID列表。这将是被DataNode识别为所有的NameNode。
        例如,如果使用"cluster1"作为nameservice ID,并且使用"nn1""nn2"作为NameNodes标示符-->
<property>
	<name>dfs.nameservices</name>
	<value>xrlhadoop</value>
</property>
<!-- xrlhadoop下面有2NameNode,分别是nn1,nn2-->
<property>
	<name>dfs.ha.namenodes.xrlhadoop</name>
	<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
	<name>dfs.namenode.rpc-address.xrlhadoop.nn1</name>
	<value>hadoop102:8020</value>
</property>
<!-- nn1的http通信地址 -->
<property>
	<name>dfs.namenode.http-address.xrlhadoop.nn1</name>
	<value>hadoop102:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
	<name>dfs.namenode.rpc-address.xrlhadoop.nn2</name>
	<value>hadoop104:8020</value>
</property>
<!-- nn2的http通信地址 -->
<property>
	<name>dfs.namenode.http-address.xrlhadoop.nn2</name>
	<value>hadoop104:50070</value>
</property>
<!-- 指定NameNode的edits元数据的共享存储位置。也就是JournalNode列表
该url的配置格式:qjournal://host1:port1;host2:port2;host3:port3/journalId
journalId推荐使用nameservice,默认端口号是:8485 -->
 <property>
	 <name>dfs.namenode.shared.edits.dir</name>
	 <value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/xrlhadoop</value>
 </property>
<!-- 指定JournalNode在本地磁H的位置 -->
 <property>
       <name>dfs.journalnode.edits.dir</name>
       <value>/opt/journal/node/local/data</value>
 </property>
<!-- 开启NameNode失败自动切换 -->
<property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
</property>
<!-- 配置失败自动切换实现方式 -->
<property>
       <name>dfs.client.failover.proxy.provider.xrlhadoop</name>
       <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行 -->
 <property>
	 <name>dfs.ha.fencing.methods</name>
	 <value>sshfence
		 shell(/bin/true)
	 </value>
</property>
<!-- 使用sshfence隔离机制时需要ssh免登陆 -->
<property>
	<name>dfs.ha.fencing.ssh.private-key-files</name>
	<value>/root/.ssh/id_rsa</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>30000</value>
</property>
<property>
        <name>ha.failover-controller.cli-check.rpc-timeout.ms</name>
        <value>60000</value>
</property>    
</configuration>
启动步骤
  1. Hadoop处于关闭状态;
  2. 安装系统插件:yum -y install psmisc;
  3. 启动zookeeper;
  4. 删除所有节点的$HADOOP_HOME下的:rm -rf data/ logs/ ;
  5. 启动JN:hadoop-daemon.sh start journalnode
  6. 格式化NameNode:在一台namenode( namenode1或namenode2)中执行格式化命令:hdfs namenode -format
  7. 在另一台namenode同步数据前先要启动 第10步中格式化的 namenode:hadoop-daemon.sh start namenode
  8. 在其它没有格式化的namenode上执行:hdfs namenode -bootstrapStandby
  9. 在一台namenode上执行格式化zookeeper:hdfs zkfc -formatZK
  10. 测试zk是否成功格式,且启动 :zkCli.sh -server hadoop102:2181
  11. 脚本启动zk集群和Hadoop集群:zk.sh start / myhadoop.sh start
  12. 用jpsall脚本查看各个服务启动情况:DFSZKFailoverController
    (故障恢复,它与namenode在一个节点上,当一个节点失败时,自动恢复)
  13. 查看:http://hadoop102:50070,http://hadoop104:50070 一个为Active一个为Standby
  14. 关闭为Active的NameNode节点:hadoop-daemon.sh stop namenode,观察Standby是否转为Active;

YARN高可用(HA)

修改配置文件yarn-site.xml
<configuration>

<!-- Site specific YARN configuration properties -->
<!-- 环境变量的继承 -->
<!--<property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
<!-- 开启日志聚集功能 -->
<property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property>
        <name>yarn.log.server.url</name>
        <value>http://hadoop102:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为7天 -->
<property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>604800</value>
</property>
<property>
        <name>yarn.application.classpath</name>
        <value>/opt/module/hadoop-3.3.1/etc/hadoop:/opt/module/hadoop-3.3.1/share/hadoop/common/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/common/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/*:/opt/module/hadoop-3.3.1/share/hadoop/mapreduce/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn:/opt/module/hadoop-3.3.1/share/hadoop/yarn/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn/*</value>
</property>
<!--开启高可用-->
<property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>xrlyarn</value>
</property>

<!-- 指定RM的名字 -->
<property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址 -->
<property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop103</value>
</property>
<property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop104</value>
</property>
<!-- 指定zk集群地址 -->
<property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!--Reducer获取数据的方式-->
<property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
</property>
<!-- 启用自动恢复 -->
<property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
</property>
<!-- 制定resourcemanager的状态信息存储在zookeeper集群上 -->
<property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!-- 解决hadoop执行MapReduce程序时Ha和yarn的冲突 YarnRuntimeException: java.lang.NullPointerException -->
<property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>hadoop103:8088</value>
</property>
<property>
         <name>yarn.resourcemanager.webapp.address.rm2</name>
         <value>hadoop104:8088</value>
</property>

</configuration>

解决hadoop执行MapReduce程序时Ha和yarn的冲突 YarnRuntimeException: java.lang.NullPointerException

启动步骤
  1. 关闭集群
  2. 删除删除所有节点的$HADOOP_HOME下的:rm -rf data/ logs/ ;
  3. 删除journalnode的数据:/opt/journal/node/local/data/下的xrlhadoop;
  4. 启动所有节点上的JND;
  5. 格式化一个NameNode:hadoop namenode -format
  6. 启动namenode:hadoop-daemon start namenode
  7. 在另一个NameNode上同步格式好的NameNode:hdfs namenode -bootstrapStandby
  8. 启动所有节点:myhadoop.sh start
  9. http://hadoop104:8088/ 访问 ResourceManager;注意观察进入的时哪个节点;
  10. 关闭网页所访问的那个节点的 ResourceManager,yarn-daemon.sh stop resourcemanager;刷新网页,无法访问到网页;改用另一个节点访问http://hadoop103:8088/成功访问,说明配置成功。

最终的集群规划

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值