HDFS集群管理与运维

HDFS数据迁移解决方案

数据迁移指的是一种大规模量级的数据转移,转移的过程中往往会跨机房、跨集群 ,数据迁移规模的不同会导致整个数据迁移的周期也不尽相同 。

在HDFS中,同样有许多需要数据迁移的场景,比如冷热数据集群之间的数据转化, 或者HDFS数据的双机房备份等等 。因为涉及跨机房 、跨集群,所以数据迁移不会是一个简单的操作。

数据迁移使用场景

  • 冷热集群数据同步、分类存储
  • 集群数据整体搬迁

当公司的业务迅速的发展,导致当前的服务器数量资源出现临时紧张的时候,为了更高效的利用资源,会将原A机房数据整体迁移到B机房的,原因可能是B机房机器多,而且B机房本身开销较A机房成本低些等;

  • 数据的准实时同步

数据准实时同步的目的在于数据的双备份可用,比如某天A集群突然宣告不允许再使用了,此时可以将线上使用集群直接切向B的同步集群,因为B集群实时同步A集群数据,拥有完全一致的真实数据和元数据信息,所以对于业务方使用而言是不会受到任何影响的。

数据迁移要素考量

  • Bandwidth-带宽

带宽用的多了,会影响到线上业务的任务运行,带宽用的少了又会导致数据同步过慢的问题。

  • Performance-性能

是采用简单的单机程序?还是多线程的性能更佳的分布式程序?

  • Data-Increment-增量同步

当TB,PB级别的数据需要同步的时候,如果每次以全量的方式去同步数据,结果一定是非常糟糕。如果仅针对变化的增量数据进行同步将会是不错的选择。可以配合HDFS快照等技术实现增量数据同步。

  • Syncable-数据迁移的同步性

数据迁移的过程中需要保证周期内数据是一定能够同步完的,不能差距太大.比如A集群7天内的增量数据,我只要花半天就可以完全同步到B集群,然后我又可以等到下周再次进行同步.最可怕的事情在于A集群的7天内的数据,我的程序花了7天还同步不完,然后下一个周期又来了,这样就无法做到准实时的一致性.其实7天还是一个比较大的时间,最好是能达到按天同步.

HDFS分布式拷贝工具:DistCp

DistCp介绍

DistCp是Apache Hadoop中的一种流行工具,在hadoop-tools工程下,作为独立子工程存在。其定位就是用于数据迁移的,定期在集群之间和集群内部备份数据。(在备份过程中,每次运行DistCp都称为一个备份周期。)尽管性能相对较慢,但它的普及程度已经越来越高。

image-20211109213611347

DistCp底层使用MapReduce在集群之间或并行在同一集群内复制文件。执行复制的MapReduce只有mapper阶段。它涉及两个步骤:

  • 构建要复制的文件列表(称为复制列表)
  • 运行MapReduce作业以复制文件,并以复制列表为输入。

DistCp优势特性

  • 带宽限流

DistCp可以通过命令参数 bandwidth 来为程序进行带宽限流。

  • 增量数据同步

在DistCp中可以通过updateappenddiff 这3个参数实现增量同步。

参数 作用
Append 追加写目标路径下己存在的文件。
Diff 通过快照的diff对比信息来同步源端路径与目标路径。
Update 只拷贝不存在的文件或者目录 。

Update解决了新增文件、目录的同步。Append解决己存在文件的增量更新同步。 Diff解决删除或重命名类型文件的同步。

  • 高效的性能:分布式特性

DistCp底层使用MapReduce执行数据同步,MapReduce本身是一类分布式程序。

DistCp命令

image-20211109213933022

$ hadoop distcp
usage: distcp OPTIONS [source_path...] <target_path>
             
 -append                   //拷贝文件时支持对现有文件进行追加写操作
 -async                	//异步执行distcp拷贝任务
 -bandwidth <arg>      	//对每个Map任务的带宽限速
 -delete               	//删除相对于源端,目标端多出来的文件
 -diff <arg>           	//通过快照diff信息进行数据的同步                  
 -overwrite            	//以覆盖的方式进行拷贝,如果目标端文件已经存在,则直接覆盖
 -p <arg>              	//拷贝数据时,扩展属性信息的保留,包括权限信息、块大小信息等等
 -skipcrccheck             //拷贝数据时是否跳过cheacksum的校验
 -update               	//拷贝数据时,只拷贝相对于源端 ,目标端不存在的文件数据

其中 source_path 、target_path 需要带上地址前缀以区分不同的集群

例如 :hadoop distcp hdfs://nnl:8020/foo/a hdfs://nn2:8020/bar/foo

上面的命令表示从nnl集群拷贝/foo/a 路径下的数据到nn2集群的/bar/foo 路径下。

HDFS NAMENODE 安全模式

场景:安全模式探究

HDFS集群在停机状态下,使用hdfs –daemon命令逐个进程启动集群,观察现象。

首先启动namenode: hdfs —daemon start namenode。然后依次执行浏览文件系统和创建文件夹操作,现象如下,发现集群可以查看目录结构但是无法新增目录。

image-20211109214053433

打开HDFS集群web页面可以发现如下提示

image-20211109214133718

提示说:已经汇报的数据块的比例没有达到阈值。阈值为总数量块的0.999。

接下来,启动第一台机器上的Datanode进程:hdfs —daemon start datanode。继续查看页面提示信息。

image-20211109214147947

image-20211109214151725

此时执行创建文件夹操作,发现可以创建成功了。

image-20211109214200355

可以发现在安全模式下,我们可以浏览文件系统目录层次结构,但是却无法创建文件夹,安全模式下的文件系统似乎处于一种可读不可下的特殊状态。

安全模式概述

Hadoop中的安全模式safe mode是NameNode的维护状态,在此状态下NameNode不允许对文件系统进行任何更改,可以接受读数据请求。

在NameNode启动过程中,首先会从fsimage和edits日志文件加载文件系统状态。然后,等待DataNodes汇报可用的block信息。在此期间,NameNode保持在安全模式。随着DataNode的block汇报持续进行,当整个系统达到安全标准时,HDFS自动离开安全模式。在NameNode Web主页上会显示安全模式是打开还是关闭。

如果HDFS处于安全模式下,不允许HDFS客户端进行任何修改文件的操作,包括上传文件,删除文件,重命名,创建文件夹,修改副本数等操作。

安全模式自动进入离开

自动进入时间

HDFS集群启动时,当NameNode启动成功之后,此时集群就会自动进入安全模式。

自动离开条件

安全模式相关的配置属性参数都在hdfs-default.xml中定义,如果需要覆盖任何值,请在hdfs-site.xml文件中重新覆盖定义。

  • dfs.replication

    hdfs block的副本数据,默认3

  • dfs.replication.max

    最大块副本数,默认512

  • dfs.namenode.replication.min

    最小块副本数,默认1

  • dfs.namenode.safemode.threshold-pct

    已汇报可用数据块数量占整体块数量的百分比阈值。默认0.999f。

    小于或等于0,则表示退出安全模式之前,不要等待特定百分比的块。大于1的值将使安全模式永久生效。

  • dfs.namenode.safemode.min.datanodes

    指在退出安全模式之前必须存活的DataNode数量,默认0

  • dfs.namenode.safemode.extension

    达到阈值条件后持续扩展的时间。倒计时结束如果依然满足阈值条件,自动离开安全模式。默认30000毫秒

安全模式手动进入离开

手动获取安全模式状态信息

hdfs dfsadmin -safemode get

image-20211109214746625

手动进入命令

hdfs dfsadmin -safemode enter

手动进入安全模式对于集群维护或者升级的时候非常有用,因为这时候HDFS上的数据是只读的。

image-20211109214814371

image-20211109214818844

手动离开命令

hdfs dfsadmin -safemode leave

image-20211109214838590

HDFS优化方案

短路本地读取:Short Circuit Local Reads

背景

在HDFS中,不管是Local Reads(DFSClient和Datanode在同一个节点)还是Remote Reads(DFSClient和Datanode不在同一个节点),底层处理方式都是一样的,都是先由Datanode读取数据,然后再通过RPC(基于TCP)把数据传给DFSClient。这样处理是比较简单的,但是性能会受到一些影响,因为需要Datanode在中间做一次中转。

尤其Local Reads的时候,既然DFSClient和数据是在一个机器上面,那么很自然的想法,就是让DFSClient绕开Datanode自己去读取数据。

image-20211109214929626

所谓的“短路”读取绕过了DataNode,从而允许客户端直接读取文件。显然,这仅在客户端与数据位于同一机器的情况下才可行。短路读取为许多应用提供了显着的性能提升。

短路本地读取

HDFS-2246这个JIRA中,工程师们的想法是既然读取数据DFSClient和数据在同一台机器上,那么Datanode就把数据在文件系统中的路径,从什么地方开始读(offset)和需要读取多少(length)等信息告诉DFSClient,然后DFSClient去打开文件自己读取。想法很好,问题在于配置复杂以及安全问题。

image-20211109215014978

首先是配置问题,因为是让DFSClient自己打开文件读取数据,那么就需要配置一个白名单,定义哪些用户拥有访问Datanode的数据目录权限。如果有新用户加入,那么就得修改白名单。需要注意的是,这里是允许客户端访问Datanode的数据目录,也就意味着,任何用户拥有了这个权限,就可以访问目录下其他数据,从而导致了安全漏洞。因此,这个实现已经不建议使用了

image-20211109215025212

短路本地读取安全性改进

HDFS-347中,提出了一种新的解决方案,让短路本地读取数据更加安全。

image-20211109215043445

在Linux中,有个技术叫做Unix Domain Socket。Unix Domain Socket是一种进程间的通讯方式,它使得同一个机器上的两个进程能以Socket的方式通讯。它带来的另一大好处是,利用它两个进程除了可以传递普通数据外,还可以在进程间传递文件描述符。

假设机器上的两个用户A和B,A拥有访问某个文件的权限而B没有,而B又需要访问这个文件。借助Unix Domain Socket,可以让A打开文件得到一个文件描述符,然后把文件描述符传递给B,B就能读取文件里面的内容了即使它没有相应的权限。在HDFS的场景里面,A就是Datanode,B就是DFSClient,需要读取的文件就是Datanode数据目录中的某个文件。

image-20211109215052930

这个方案在安全上就比上一个方案上好一些,至少它只允许DFSClient读取它需要的文件。

短路本地读取配置

libhadoop.so

因为Java不能直接操作Unix Domain Socket,所以需要安装Hadoop的native包libhadoop.so。在编译Hadoop源码的时候可以通过编译native模块获取。可以用如下命令来检查native包是否安装好。

hadoop checknative

image-20211109215151100

hdfs-site.xml

<property>
    <name>dfs.client.read.shortcircuit</name>
    <value>true</value> 
  </property>
  <property>
    <name>dfs.domain.socket.path</name>
    <value>/var/lib/hadoop-hdfs/dn_socket</value>
  </property>

其中:

dfs.client.read.shortcircuit是打开短路本地读取功能的开关,dfs.domain.socket.path是Datanode和DFSClient之间沟通的Socket的本地路径。

HDFS Block负载平衡器:Balancer

背景

HDFS数据可能并不总是在DataNode之间均匀分布。一个常见的原因是向现有集群中添加了新的DataNode。HDFS提供了一个Balancer程序,分析block放置信息并且在整个DataNode节点之间平衡数据,直到被视为平衡为止。

所谓的平衡指的是每个DataNode的利用率(节点上已用空间与节点总容量之比)与集群的利用率(集群上已用空间与集群总容量的比)相差不超过给定阈值百分比。 平衡器无法在单个DataNode上的各个卷之间进行平衡。

image-20211109215251680

命令行配置和运行

image-20211109215304447

-threshold  10                 	//集群平衡的条件,datanode间磁盘使用率相差阈值,区间选择:0~100
-policy datanode               	//平衡策略,默认为datanode, 如果datanode平衡,则集群已平衡。
-exclude  -f  /tmp/ip1.txt     //默认为空,指定该部分ip不参与balance, -f:指定输入为文件
-include  -f  /tmp/ip2.txt     //默认为空,只允许该部分ip参与balance,-f:指定输入为文件
-idleiterations  5             	//迭代 5

设置平衡数据传输带宽

命令:hdfs dfsadmin -setBalancerBandwidth newbandwidth

其中newbandwidth是每个DataNode在平衡操作期间可以使用的最大网络带宽量,以每秒字节数为单位。

比如:hdfs dfsadmin -setBalancerBandwidth 104857600

默认运行balancer

命令:hdfs balancer

此时将会以默认参数进行数据块的平衡操作。

修改阈值运行balancer

命令:hdfs balancer -threshold 5

Balancer将以阈值5%运行(默认值10%),这意味着程序将确保每个DataNode上的磁盘使用量与群集中的总体使用量相差不超过5%。例如,如果集群中所有DataNode的总体使用率是集群磁盘总存储容量的40%,则程序将确保每个DataNode的磁盘使用率在该DataNode磁盘存储容量的35%至45%之间。

磁盘均衡器:HDFS Disk Balancer

背景

相比较于个人PC,服务器一般可以通过挂载多块磁盘来扩大单机的存储能力。

image-20211109215602331

在Hadoop HDFS中,DataNode负责最终数据block的存储,在所在机器上的磁盘之间分配数据块。当写入新block时,DataNodes将根据选择策略(循环策略可用空间策略)来选择block的磁盘(卷)。

循环策略:它将新block均匀分布在可用磁盘上。默认此策略。

可用空间策略:此策略将数据写入具有更多可用空间(按百分比)的磁盘。

image-20211109215617173

但是,在长期运行的群集中采用循环策略时,DataNode有时会不均匀地填充其存储目录(磁盘/卷),从而导致某些磁盘已满而其他磁盘却很少使用的情况。发生这种情况的原因可能是由于大量的写入和删除操作,也可能是由于更换了磁盘。

另外,如果我们使用基于可用空间的选择策略,则每个新写入将进入新添加的空磁盘,从而使该期间的其他磁盘处于空闲状态。这将在新磁盘上创建瓶颈。

因此,需要一种Intra DataNode Balancing(DataNode内数据块的均匀分布)来解决Intra-DataNode偏斜(磁盘上块的不均匀分布),这种偏斜是由于磁盘更换或随机写入和删除而发生的。

因此,Hadoop 3.0中引入了一个名为Disk Balancer的工具,该工具专注于在DataNode内分发数据。

HDFS Disk Balancer简介

HDFS disk balancer是Hadoop 3中引入的命令行工具,用于平衡DataNode中的数据在磁盘之间分布不均匀问题。 这里要特别注意,HDFS disk balancer与HDFS Balancer是不同的:

HDFS disk balancer针对给定的DataNode进行操作,并将块从一个磁盘移动到另一个磁盘,是DataNode内部数据在不同磁盘间平衡;

HDFS Balancer平衡了DataNode节点之间的分布。

HDFS Disk Balancer功能

HDFS Disk balancer支持两个主要功能,即报告平衡

数据传播报告

为了定义一种方法来衡量集群中哪些计算机遭受数据分布不均的影响,HDFS磁盘平衡器定义了HDFS Volume Data Density metric(卷/磁盘数据密度度量标准)和Node Data Density metric(节点数据密度度量标准)。

HDFS卷数据密度度量标准能够比较数据在给定节点的不同卷上的分布情况。

节点数据密度度量允许在节点之间进行比较。

  • Volume data density metric计算过程

假设有一台具有四个卷/磁盘的计算机-Disk1,Disk2,Disk3,Disk4,各个磁盘使用情况:

Disk1 Disk2 Disk3 Disk4
capacity 200 GB 300 GB 350 GB 500 GB
dfsUsed 100 GB 76 GB 300 GB 475 GB
dfsUsedRatio 0.5 0.25 0.85 0.95
volumeDataDensity 0.20 0.45 -0.15 -0.24

Total capacity= 200 + 300 + 350 + 500 = 1350 GB

Total Used= 100 + 76 + 300 + 475 = 951 GB

因此,每个卷/磁盘上的理想存储为:

Ideal storage = total Used ÷ total capacity= 951÷1350 = 0.70

也就是每个磁盘应该保持在 70%理想存储容量。

VolumeDataDensity = idealStorage – dfs Used Ratio

比如Disk1的卷数据密度= 0.70-0.50 = 0.20。其他Disk以此类推。

volumeDataDensity的正值表示磁盘未充分利用,而负值表示磁盘相对于当前理想存储目标的利用率过高。

  • Node Data Density计算过程

Node Data Density(节点数据密度)= 该节点上所有卷/磁盘volume data density绝对值的总和。

上述例子中的节点数据密度=|0.20|+|0.45|+|-0.15|+|-0.24| =1.04

较低的node Data Density值表示该机器节点具有较好的扩展性,而较高的值表示节点具有更倾斜的数据分布。

一旦有了volumeDataDensity和nodeDataDensity,就可以找到集群中数据分布倾斜的节点,或者可以获取给定节点的volumeDataDensity。

磁盘平衡

当指定某个DataNode节点进行disk数据平衡,就可以先计算或读取当前的volumeDataDensity(磁盘数据密度)。有了这些信息,我们可以轻松地确定哪些卷已超量配置,哪些卷已不足。为了将数据从一个卷移动到DataNode中的另一个卷,Hadoop开发实现了基于RPC协议的Disk Balancer。

HDFS Disk Balancer开启

HDFS Disk Balancer通过创建计划进行操作,该计划是一组语句,描述应在两个磁盘之间移动多少数据,然后在DataNode上执行该组语句。计划包含多个移动步骤。计划中的每个移动步骤都具有目标磁盘,源磁盘的地址。移动步骤还具有要移动的字节数。该计划是针对可操作的DataNode执行的。

默认情况下,Hadoop群集上已经启用了Disk Balancer功能。通过在hdfs-site.xml中调整dfs.disk.balancer.enabled参数值,选择在Hadoop中是否启用磁盘平衡器。

HDFS Disk Balancer相关命令

Plan计划

命令:hdfs diskbalancer -plan <datanode>

-out	//控制计划文件的输出位置
-bandwidth	//设置用于运行Disk Balancer的最大带宽。默认带宽10 MB/s。
–thresholdPercentage  //定义磁盘开始参与数据重新分配或平衡操作的值。默认的thresholdPercentage值为10%,这意味着仅当磁盘包含的数据比理想存储值多10%或更少时,磁盘才用于平衡操作。
-maxerror	//它允许用户在中止移动步骤之前为两个磁盘之间的移动操作指定要忽略的错误数。
-v	//详细模式,指定此选项将强制plan命令在stdout上显示计划的摘要。
-fs	//此选项指定要使用的NameNode。如果未指定,则Disk Balancer将使用配置中的默认NameNode。

image-20211109220052702

Execute执行

命令:hdfs diskbalancer -execute <JSON file path>

execute命令针对为其生成计划的DataNode执行计划。

Query查询

命令:hdfs diskbalancer -query <datanode>

query命令从运行计划的DataNode获取HDFS磁盘平衡器的当前状态。

Cancel取消

命令:hdfs diskbalancer -cancel <JSON file path>

hdfs diskbalancer -cancel planID node <nodename>

cancel命令取消运行计划。

Report汇报

命令:hdfs diskbalancer -fs https://namenode.uri -report <file://>

纠删码技术:Erasure Coding

背景:3副本策略弊端

为了提供容错能力,HDFS会根据replication factor(复制因子)在不同的DataNode上复制文件块。默认复制因子为3(注意这里的3指的是1+2=3,不是额外3个),则原始块除外,还将有额外两个副本。每个副本使用100%的存储开销,因此导致200%的存储开销。这些副本也消耗其他资源,例如网络带宽。

image-20211109220239772

复制因子为N时,存在N-1个容错能力,但存储效率仅为1/N

这种复制增加了存储开销,并且似乎很昂贵。因此,HDFS使用Erasure Coding(纠删码)代替复制,以提供相同级别的容错能力,并且存储开销不超过50%。

Erasure Coding文件的复制因子始终为1,用户无法对其进行更改。

Erasure Coding(EC)简介

纠删码技术(Erasure coding)简称EC,是一种编码容错技术。最早用于通信行业,数据传输中的数据恢复。它通过对数据进行分块,然后计算出校验数据,使得各个部分的数据产生关联性。当一部分数据块丢失时,可以通过剩余的数据块和校验块计算出丢失的数据块。

Hadoop 3.0 之后引入了纠删码技术(Erasure Coding),它可以提高50%以上的存储利用率,并且保证数据的可靠性。

存储系统RAID使用纠删码。RAID通过striping(条带化)实现纠删码,也就是说,将逻辑上连续的数据(例如文件)划分为较小的单位(bit, byte, or block),并将连续的单位存储在不同的磁盘上。

对于原始数据集的每个条带,都会根据纠删码算法来计算并存储一定数量的奇偶校验单元,该过程称为编码

任何条带化单元中的错误都可以根据剩余数据和奇偶校验单元从计算中恢复,此过程称为解码

image-20211109220303988

Reed-Solomon(RS)码

RS码介绍

Reed-Solomon(RS)码是存储系统较为常用的一种纠删码,它有两个参数k和m,记为RS(k,m)。如下图所示,k个数据块组成一个向量被乘上一个生成矩阵(Generator Matrix)GT从而得到一个码字(codeword)向量,该向量由k个数据块和m个校验块构成。如果一个数据块丢失,可以用(GT)-1乘以码字向量来恢复出丢失的数据块。RS(k,m)最多可容忍m个块(包括数据块和校验块)丢失。

image-20211109220344305

RS码通俗解释

比如有 7、8、9 三个原始数据,通过矩阵乘法,计算出来两个校验数据 50、122。这时原始数据加上校验数据,一共五个数据:7、8、9、50、122,可以任意丢两个,然后通过算法进行恢复。

image-20211109220408326

Hadoop EC架构

为了支持纠删码,HDFS体系结构进行了一些更改调整。

  • Namenode扩展

条带化的HDFS文件在逻辑上由block group(块组)组成,每个块组包含一定数量的内部块。这允许在块组级别而不是块级别进行文件管理。

  • 客户端扩展

客户端的读写路径得到了增强,可以并行处理块组中的多个内部块。

  • Datanode扩展

DataNode运行一个附加的ErasureCodingWorker(ECWorker)任务,以对失败的纠删编码块进行后台恢复。 NameNode检测到失败的EC块,然后NameNode选择一个DataNode进行恢复工作。

  • 纠删编码策略

为了适应异构的工作负载,允许HDFS群集中的文件和目录具有不同的复制和纠删码策略。纠删码策略封装了如何对文件进行编码/解码。默认情况下启用RS-6-3-1024k策略, RS表示编码器算法Reed-Solomon,6 、3中表示数据块和奇偶校验块的数量,1024k表示条带化单元的大小。

目录上还支持默认的REPLICATION方案。它只能在目录上设置,以强制目录采用3倍复制方案,而不继承其祖先的纠删码策略。此策略可以使3x复制方案目录与纠删码目录交错。REPLICATION始终处于启用状态。

此外也支持用户通过XML文件定义自己的EC策略,Hadoop conf目录中有一个名为user_ec_policies.xml.template的示例EC策略XML文件,用户可以参考该文件。

  • Intel ISA-L

英特尔ISA-L代表英特尔智能存储加速库。 ISA-L是针对存储应用程序而优化的低级功能的开源集合。它包括针对Intel AVX和AVX2指令集优化的快速块Reed-Solomon类型擦除代码。 HDFS纠删码可以利用ISA-L加速编码和解码计算。

Erasure Coding部署方式

集群和硬件配置

编码和解码工作会消耗HDFS客户端和DataNode上的额外CPU

纠删码文件也分布在整个机架上,以实现机架容错。这意味着在读写条带化文件时,大多数操作都是在机架上进行的。因此,网络带宽也非常重要。

对于机架容错,拥有足够数量的机架也很重要,每个机架所容纳的块数不超过EC奇偶校验块的数。

机架数量=(数据块+奇偶校验块)/奇偶校验块后取整。比如对于EC策略RS(6,3),这意味着最少3个机架(由(6 + 3)/ 3 = 3计算),理想情况下为9个或更多,以处理计划内和计划外的停机。对于机架数少于奇偶校验单元数的群集,HDFS无法维持机架容错能力,但仍将尝试在多个节点之间分布条带化文件以保留节点级容错能力。因此,建议设置具有类似数量的DataNode的机架。

纠删码策略设置

纠删码策略由参数dfs.namenode.ec.system.default.policy指定,默认是RS-6-3-1024k,其他策略默认是禁用的。可以通过hdfs ec [-enablePolicy -policy <policyName>]命令启用策略集。

启用英特尔ISA-L

默认RS编解码器的HDFS本机实现利用Intel ISA-L库来改善编码和解码计算。要启用和使用Intel ISA-L,需要执行三个步骤。

建立ISA-L库;

使用ISA-L支持构建Hadoop;

使用-Dbundle.isal将isal.lib目录的内容复制到最终的tar文件中。使用tar文件部署Hadoop。确保ISA-L在HDFS客户端和DataNode上可用。

EC命令

HDFS提供了一个ec子命令来执行与纠删码有关的管理命令。

image-20211109220650226

  • [-setPolicy -path <path> [-policy <policy>] [-replicate]]

    在指定路径的目录上设置擦除编码策略。

    path:HDFS中的目录。这是必填参数。设置策略仅影响新创建的文件,而不影响现有文件

    policy:用于此目录下文件的擦除编码策略。默认RS-6-3-1024k策略。

    -replicate在目录上应用默认的REPLICATION方案,强制目录采用3x复制方案。

    -replicate和-policy <policy>是可选参数。不能同时指定它们。

  • [-getPolicy -path < path >]

    获取指定路径下文件或目录的擦除编码策略的详细信息。

  • [-unsetPolicy -path < path >]

    取消设置先前对目录上的setPolicy的调用所设置的擦除编码策略。如果该目录从祖先目录继承了擦除编码策略,则unsetPolicy是no-op。在没有显式策略集的目录上取消策略将不会返回错误。

  • [-listPolicies]

    列出在HDFS中注册的所有(启用,禁用和删除)擦除编码策略。只有启用的策略才适合与setPolicy命令一起使用。

  • [-addPolicies -policyFile <文件>]

    添加用户定义的擦除编码策略列表。

  • [-listCodecs]

    获取系统中支持的擦除编码编解码器和编码器的列表。

  • [-removePolicy -policy <policyName>]

    删除用户定义的擦除编码策略。

  • [-enablePolicy -policy <policyName>]

    启用擦除编码策略。

  • [-disablePolicy -policy <policyName>]

    禁用擦除编码策略。

HDFS动态节点管理

背景

已有HDFS集群容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的DataNode节点。就是俗称的动态扩容

旧的服务器需要进行退役更换,暂停服务,需要在当下的集群中停止某些机器上HDFS的服务,俗称动态缩容

动态扩容、节点上线

新机器基础环境准备

主机名、IP

确保新机器IP和已有HDFS集群所属同一网段

image-20211109221233431

新机器系统hostname

image-20211109221244520

Hosts映射

image-20211109221256931

集群所有节点保持hosts文件统一

防火墙、时间同步

关闭防火墙

image-20211109221318957

集群时间同步

image-20211109221335629

SSH免密登录

为了后续脚本一键启动关闭集群方便,设置NameNode到新机器的免密登录

image-20211109221353917

JDK环境配置

image-20211109221406397

Hadoop配置

NameNode节点配置

修改namenode节点workers配置文件,增加新节点主机名,便于后续一键启停。

image-20211109221431723

新机器配置

从namenode节点复制hadoop安装包到新节点,注意不包括hadoop.tmp.dir指定的数据存储目录

image-20211109221452834

新机器上配置hadoop环境变量

vim /etc/profile

export HADOOP_HOME=/export/server/hadoop-3.1.4
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

source /etc/profile

手动启动DataNode进程

image-20211109221535753

Hadoop Web页面查看

image-20211109221548169

DataNode负载均衡服务

新加入的节点,没有数据块的存储,使得集群整体来看负载不均衡。因此最后还需要对hdfs负载设置均衡。首先设置数据传输带宽。

hdfs dfsadmin -setBalancerBandwidth 104857600

然后启动Balancer,等待集群自均衡完成即可。

hdfs balancer -threshold 5

image-20211109221608650

动态缩容、节点下线

添加退役节点

在namenode机器的hdfs-site.xml配置文件中需要提前配置dfs.hosts.exclude属性,该属性指向的文件就是所谓的黑名单列表,会被namenode排除在集群之外。如果文件内容为空,则意味着不禁止任何机器。

提前配置好的目的是让namenode启动的时候就能加载到该属性,只不过还没有指定任何机器。否则就需要重启namenode才能加载,因此这样的操作我们称之为具有前瞻性的操作

<property>
        <name>dfs.hosts.exclude</name>
        <value>/export/server/hadoop-3.1.4/etc/hadoop/excludes</value>
</property>

编辑dfs.hosts.exclude属性指向的excludes文件,添加需要退役的主机名称。

image-20211109221647280

注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役。

刷新集群

在namenode所在的机器刷新节点:hdfs dfsadmin -refreshNodes

image-20211109221714197

等待退役节点状态为decommissioned(所有块已经复制完成)

image-20211109221754116

image-20211109221757554

image-20211109221801508

手动关闭DataNode进程

hdfs --daemon stop datanode

image-20211109221818553

DataNode负载均衡服务

如果需要可以对已有的HDFS集群进行负载均衡服务。

hdfs balancer -threshold 5

黑白名单机制

白名单

所谓的白名单指的是允许哪些机器加入到当前的HDFS集群中,是一种准入机制。

白名单由dfs.hosts参数指定,该参数位于hdfs-site.xml。默认值为空。

dfs.hosts指向文件,该文件包含允许连接到namenode的主机列表。必须指定文件的完整路径名。如果该值为空,则允许所有主机准入

黑名单

所谓的黑名单指的是禁止哪些机器加入到当前的HDFS集群中,是一种禁入机制。

黑名单由dfs.hosts.exclude参数指定,该参数位于hdfs-site.xml。默认值为空。

dfs.hosts.exclude指向文件,该文件包含不允许连接到名称节点的主机列表。必须指定文件的完整路径名。如果该值为空,则不禁止任何主机加入

image-20211109221916891

HDFS High Availability(HA)高可用

High Availability背景知识

单点故障、高可用

单点故障(英语:single point of failure,缩写SPOF)是指系统中某一点一旦失效,就会让整个系统无法运作,换句话说,单点故障即会整体故障。

image-20211109221949651

高可用性(英语:high availability,缩写为 HA),IT术语,指系统无中断地执行其功能的能力,代表系统的可用性程度。是进行系统设计时的准则之一。高可用性系统意味着系统服务可以更长时间运行,通常通过提高系统的容错能力来实现。

高可用性或者高可靠度的系统不会希望有单点故障造成整体故障的情形。一般可以透过冗余的方式增加多个相同机能的部件,只要这些部件没有同时失效,系统(或至少部分系统)仍可运作,这会让可靠度提高。

image-20211109222000598

高可用如何实现

主备集群

解决单点故障,实现系统服务高可用的核心并不是让故障永不发生,而是让故障的发生对业务的影响降到最小。因为软硬件故障是难以避免的问题。

当下企业中成熟的做法就是给单点故障的位置设置备份,形成主备架构。通俗描述就是当主挂掉,备份顶上,短暂的中断之后继续提供服务。

常见的是一主一备架构,当然也可以一主多备。备份越多,容错能力越强,与此同时,冗余也越大,浪费资源。

image-20211109222038957

Active、Standby

Active:主角色。活跃的角色,代表正在对外提供服务的角色服务。任意时间有且只有一个active对外提供服务。

Standby:备份角色。需要和主角色保持数据、状态同步,并且时刻准备切换成主角色(当主角色挂掉或者出现故障时),对外提供服务,保持服务的可用性。

可用性评判标准—x个9

在系统的高可用性里有个衡量其可靠性的标准——X个9,这个X是代表数字3-5。X个9表示在系统1年时间的使用过程中,系统可以正常使用时间与总时间(1年)之比。

  • 3个9:(1-99.9%)36524=8.76小时,表示该系统在连续运行1年时间里最多可能的业务中断时间是8.76小时。
  • 4个9:(1-99.99%)36524=0.876小时=52.6分钟,表示该系统在连续运行1年时间里最多可能的业务中断时间是52.6分钟。
  • 5个9:(1-99.999%)36524*60=5.26分钟,表示该系统在连续运行1年时间里最多可能的业务中断时间是5.26分钟。

可以看出,9越多,系统的可靠性越强,能够容忍的业务中断时间越少,但是要付出的成本更高。

image-20211109222148957

HA系统设计核心问题

脑裂问题

脑裂(split-brain)是指“大脑分裂”,本是医学名词。在HA集群中,脑裂指的是当联系主备节点的”心跳线”断开时(即两个节点断开联系时),本来为一个整体、动作协调的HA系统,就分裂成为两个独立的节点。由于相互失去了联系,主备节点之间像”裂脑人”一样,使得整个集群处于混乱状态。脑裂的严重后果:

1)集群无主:都认为对方是状态好的,自己是备份角色,后果是无服务;

2)集群多主:都认为对方是故障的,自己是主角色。相互争抢共享资源,结果会导致系统混乱,数据损坏。此外对于客户端访问也是一头雾水,找谁呢?

避免脑裂问题的核心是:保持任意时刻系统有且只有一个主角色提供服务。

数据同步问题

主备切换保证服务持续可用性的前提是主备节点之间的状态、数据是一致的,或者说准一致的。如果说备用的节点和主节点之间的数据差距过大,即使完成了主备切换的动作,那也是没有意义的。

数据同步常见做法是:通过日志重演操作记录。主角色正常提供服务,发生的事务性操作通过日志记录,备用角色读取日志重演操作。

HDFS NAMENODE单点故障问题

在Hadoop 2.0.0之前,NameNode是HDFS集群中的单点故障(SPOF)。每个群集只有一个NameNode,如果该计算机或进程不可用,则整个群集在整个NameNode重新启动或在另一台计算机上启动之前将不可用。

NameNode的单点故障从两个方面影响了HDFS群集的总可用性:

  • 如果发生意外事件(例如机器崩溃),则在重新启动NameNode之前,集群将不可用。
  • 计划内的维护事件,例如NameNode计算机上的软件或硬件升级,将导致集群停机时间的延长。

HDFS高可用性解决方案:在同一群集中运行两个(从3.0.0起,超过两个)冗余NameNode。这样可以在机器崩溃的情况下快速故障转移到新的NameNode,或者出于计划维护的目的由管理员发起的正常故障转移。

image-20211109222251077

image-20211109222255352

HDFS HA解决方案—QJM

QJM全称Quorum Journal Manager,由cloudera公司提出,是Hadoop官方推荐的HDFS HA解决方案之一。

QJM中,使用zookeeper中ZKFC来实现主备切换;使用Journal Node(JN)集群实现edits log的共享以达到数据同步的目的。

image-20211109222314734

QJM—主备切换、脑裂问题解决

ZKFailoverController(zkfc)

Apache ZooKeeper是一款高可用分布式协调服务软件,用于维护少量的协调数据。 Zookeeper的下列特性功能参与了HDFS的HA解决方案中:

  • 临时znode

    如果一个znode节点是临时的,那么该znode的生命周期将和创建它的客户端的session绑定。客户端断开连接session结束,znode将会被自动删除。

  • Path路径唯一性

    zookeeper中维持了一份类似目录树的数据结构。每个节点称之为Znode。Znode具有唯一性,不会重名。也可以理解为排他性。

  • 监听机制

    客户端可以针对znode上发生的事件设置监听,当事件发生触发条件,zk服务会把事件通知给设置监听的客户端。

ZKFailoverController(ZKFC)是一个新组件,它是一个ZooKeeper客户端。运行NameNode的每台计算机也都运行ZKFC,ZKFC的主要职责:

  • 监视和管理NameNode健康状态

    ZKFC通过命令定期ping本地负责监视的NameNode节点。

  • 维持和ZooKeeper集群联系

    如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,它将自己尝试获取该锁。如果成功,则表明它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于Active状态。如果已经有其他节点持有锁,zkfc选举失败,则会对该节点注册监听,等待下次继续选举。

Fencing隔离机制

故障转移过程也就是俗称的主备角色切换的过程,切换过程中最怕的就是脑裂的发生。因此需要Fencing机制来避免,将先前的Active节点隔离,然后将本地NameNode转换为Active状态。

Hadoop公共库中对外提供了两种fenching实现,分别是sshfence和shellfence(缺省实现),其中sshfence是指通过ssh登陆目标节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid,该方法比jps命令更准确),shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。

QJM—主备数据同步问题解决

Journal Node(JN)集群是轻量级分布式系统,主要用于高速读写数据、存储数据。通常使用2N+1台JournalNode存储共享Edits Log(编辑日志)。

image-20211109222654752

任何修改操作在 Active NN上执行时,JournalNode进程同时也会记录edits log到至少半数以上的JN中,这时 Standby NN 监测到JN 里面的同步log发生变化了会读取JN里面的edits log,然后重演操作记录同步到自己的目录镜像树里面,

当发生故障Active NN挂掉后,Standby NN 会在它成为Active NN 前,读取所有的JN里面的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。

HDFS HA环境搭建

HA集群搭建的难度主要在于配置文件的编写,心细,心细,心细

集群基础环境准备

1.修改Linux主机名 /etc/hostname

2.修改IP /etc/sysconfig/network-scripts/ifcfg-ens33

3.修改主机名和IP的映射关系 /etc/hosts

4.关闭防火墙

5.ssh免登陆

6.安装JDK,配置环境变量等 /etc/profile

7.集群时间同步

8.配置主备NN之间的互相免密登录

HA集群规划

node1 namenode zkfc datanode zookeeper journal node

node2 namenode zkfc datanode zookeeper journal node

node3 datanode zookeeper journal node

上传解压Hadoop安装包

hadoop-3.1.4-bin-snappy-CentOS7.tar.gz

tar zxvf hadoop-3.1.4-bin-snappy-CentOS7.tar.gz -C /export/server/

配置Hadoop环境变量

export HADOOP_HOME=/export/server/hadoop-3.1.4

export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

修改Hadoop配置文件

hadoop-env.sh

cd /export/server/hadoop-3.1.4/etc/hadoop

vim hadoop-env.sh

export JAVA_HOME=/export/server/jdk1.8.0_65
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root

core-site.xml

vim core-site.xml

<configuration>
	<!-- HA集群名称,该值要和hdfs-site.xml中的配置保持一致 -->
	<property>
		<name>fs.defaultFS</name>
		<value>hdfs://mycluster</value>
	</property>

	<!-- hadoop本地磁盘存放数据的公共目录 -->
	<property>
		<name>hadoop.tmp.dir</name>
		<value>/export/data/ha-hadoop</value>
	</property>

	<!-- ZooKeeper集群的地址和端口-->
	<property>
		<name>ha.zookeeper.quorum</name>
		<value>node1.itcast.cn:2181,node2.itcast.cn:2181,node3.itcast.cn:2181</value>
	</property>
</configuration>

hdfs-site.xml

<configuration>
	<!--指定hdfs的nameservice为mycluster,需要和core-site.xml中的保持一致 -->
	<property>
		<name>dfs.nameservices</name>
		<value>mycluster</value>
	</property>
	
	<!-- mycluster下面有两个NameNode,分别是nn1,nn2 -->
	<property>
		<name>dfs.ha.namenodes.mycluster</name>
		<value>nn1,nn2</value>
	</property>

	<!-- nn1的RPC通信地址 -->
	<property>
		<name>dfs.namenode.rpc-address.mycluster.nn1</name>
		<value>node1.itcast.cn:8020</value>
	</property>

	<!-- nn1的http通信地址 -->
	<property>
		<name>dfs.namenode.http-address.mycluster.nn1</name>
		<value>node1.itcast.cn:9870</value>
	</property>

	<!-- nn2的RPC通信地址 -->
	<property>
		<name>dfs.namenode.rpc-address.mycluster.nn2</name>
		<value>node2.itcast.cn:8020</value>
	</property>
	
	<!-- nn2的http通信地址 -->
	<property>
		<name>dfs.namenode.http-address.mycluster.nn2</name>
		<value>node2.itcast.cn:9870</value>
	</property>

	<!-- 指定NameNode的edits元数据在JournalNode上的存放位置 -->
	<property>
		<name>dfs.namenode.shared.edits.dir</name>
		<value>qjournal://node1.itcast.cn:8485;node2.itcast.cn:8485;node3.itcast.cn:8485/mycluster</value>
	</property>
	
	<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
	<property>
		<name>dfs.journalnode.edits.dir</name>
		<value>/export/data/journaldata</value>
	</property>

	<!-- 开启NameNode失败自动切换 -->
	<property>
		<name>dfs.ha.automatic-failover.enabled</name>
		<value>true</value>
	</property>

	<!-- 指定该集群出故障时,哪个实现类负责执行故障切换 -->
	<property>
	  <name>dfs.client.failover.proxy.provider.mycluster</name>
	  <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
	</property>

	<!-- 配置隔离机制方法-->
	<property>
      <name>dfs.ha.fencing.methods</name>
      <value>sshfence</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>
</configuration>

workers

node1.itcast.cn
node2.itcast.cn
node3.itcast.cn

集群同步安装包

在node1上:

cd /export/server
scp -r hadoop-3.1.4 root@node2:$PWD
scp -r hadoop-3.1.4 root@node3:$PWD

HA集群初始化

启动zk集群

/export/server/zookeeper-3.4.6/bin/zkServer.sh start

手动启动JN集群

hdfs --daemon start journalnode

Format namenode

在node1执行格式化namenode

hdfs namenode –format

在node1启动namenode进程

hdfs --daemon start namenode

在node2上进行namenode元数据同步

hdfs namenode –bootstrapStandby

image-20211109223329517

格式化zkfc

注意,在哪台机器上执行,哪台机器就将成为第一次的Active NN

hdfs zkfc –formatZK

image-20211109223350497

HA集群启动

在node1上启动HDFS集群

image-20211109223408843

HDFS HA效果演示

在node1上,显示namenode是active状态

image-20211109223432165

在node2上,显示namenode是standby状态

image-20211109223441022

正常操作

image-20211109223454714

image-20211109223459244

Node2无法浏览,想一想为什么?

image-20211109223507186

模拟故障出现

在node1,手动kill杀死namenode进程。

image-20211109223523796

此时发现node2上的namenode切换成为Active状态 hdfs服务正常可用。

HA切换失败—错误解决

使用kill -9模拟JVM崩溃。或者重新启动计算机电源或拔出其网络接口以模拟另一种故障。另一个NameNode应在几秒钟内自动变为活动状态。检测故障并触发故障转移所需的时间取决于ha.zookeeper.session-timeout.ms的配置,但默认值为5秒。

如果测试不成功,检查zkfc守护程序以及NameNode守护程序的日志,以便进一步诊断问题。如果错误信息如下:

image-20211109223552745

提示未找到fuser程序,导致无法进行fence,所以可以通过如下命令来安装,Psmisc软件包中包含了fuser程序(两个NN机器上都需要进行安装)

yum install psmisc -y

HDFS Federation联邦机制

当前HDFS体系架构

简介

image-20211109223624551

当前的HDFS架构有两个主要的层:

  • 命名空间(namespace)

HDFS体系结构中的命名空间层由文件,块和目录组成。该层支持与名称空间相关的文件系统操作,例如创建,删除,修改和列出文件和目录。

  • 块存储层(Block Storage)

块存储层包括两个部分:

块管理: NameNode执行块管理。块管理通过处理注册和定期心跳来提供DataNode群集成员身份。它处理块报告并支持与块相关的操作,如创建,删除,修改或获取块位置。它还维护块的位置,副本位置。为未复制的块管理块复制,并在已复制的块中删除。

存储: DataNode通过在本地文件系统上存储块并提供读/写访问权限来管理存储空间。

局限性

当下的HDFS体系结构仅允许单个NameNode维护文件系统名称空间。注意HA体系中虽然说允许多个NameNode,但是他们所维护的是同一套文件系统名称空间。这种体系目前存在着一些弊端和局限性:

  • DataNode磁盘存储空间不够增加节点,NameNode内存不够是否可以无限扩容。一种是DataNode横向扩展机器增加节点,一种是纵向扩展单机加内存。
  • 由于名称空间和存储层的紧密耦合,NameNode的替代实现很困难。这限制了其他服务直接使用块存储。唯一的NameNode成了唯一入口。
  • 文件系统的操作还限于NameNode一次处理的任务数。因此,群集的性能取决于NameNode吞吐量。
  • 同样,由于使用单个名称空间,因此使用群集的占用者组织之间没有隔离。

HDFS Federation架构

简介

Federation中文意思为联邦,联盟,是NameNode之间的Federation,也就是集群中会有多个NameNode。多个NameNode的情况意味着有多个namespace。注意,这区别于HA模式下的多NameNode,HA中它们是拥有着同一个namespace。

Federation体系中多个namenode之间相互独立且不需要互相协调,各自分工,管理自己的区域。每个DataNode要向集群中所有的namenode注册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。

image-20211109223744029

上图中,有多个NameNode,分别表示为NN1,NN2,.. NNn。NS1,NS2等是由它们各自的NameNode管理的多个名称空间。

每个名称空间都有其自己的块池(block pool)(NS1具有Pool1,NS2具有Pool2,依此类推)。每个DataNode存储集群中所有块池的块。

HDFS Federation体系结构中的块池是属于单个名称空间的块的集合。每个块池彼此独立地进行管理。在删除NameNode或名称空间时,DataNode中存在的相应块池也将被删除。在升级群集时,每个名称空间卷都作为一个单元进行升级。

好处

  • 命名空间可伸缩性

使用Federation,可以水平扩展名称空间。这对大型群集或包含太多小文件的群集有利,因为向群集添加了更多的NameNode。

  • 性能

由于文件系统操作不受单个NameNode吞吐量的限制,因此可以提高文件系统的性能。

  • 隔离

由于有多个名称空间,它可以为使用群集的占用者组织提供隔离。

HDFS Federation配置示例

<configuration>
  <property>
    <name>dfs.nameservices</name>
    <value>ns1,ns2</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.ns1</name>
    <value>nn-host1:rpc-port</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.ns1</name>
    <value>nn-host1:http-port</value>
  </property>
  <property>
    <name>dfs.namenode.secondary.http-address.ns1</name>
    <value>snn-host1:http-port</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.ns2</name>
    <value>nn-host2:rpc-port</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.ns2</name>
    <value>nn-host2:http-port</value>
  </property>
  <property>
    <name>dfs.namenode.secondary.http-address.ns2</name>
    <value>snn-host2:http-port</value>
  </property>

  .... Other common configuration ...
</configuration>

HDFS集群滚动升级

介绍

HDFS滚动升级允许升级单个HDFS守护程序。例如,可以独立于NameNodes升级DataNodes。也可以独立于其他NameNodes升级单独NameNode。也可以独立于DataNodes和journal nodes升级NameNodes。

升级

在Hadoop v2中,HDFS支持NameNode高可用(HA)和线路兼容性(wire compatibility)。这两个功能使升级HDFS变得可行,且不会导致HDFS停机。为了在不停机的情况下升级HDFS群集,必须使用HA设置群集

如果新软件版本中启用了任何新功能,则升级后可能无法与旧软件版本一起使用。在这种情况下,应按照以下步骤进行升级。

禁用新功能、升级集群、启用新功能。

请注意,仅从Hadoop-2.4.0起才支持滚动升级。

不停机升级

在HA群集中,有两个或多个NameNode(NN),许多DataNode(DN),一些JournalNode(JN)和一些ZooKeeperNode(ZKN)。JN相对稳定,在大多数情况下,升级HDFS时不需要升级。滚动升级过程中,仅针对NNs和DNs,JNS和ZKNs都没有。升级JN和ZKN可能会导致群集停机。

升级非联邦集群

假设有两个名称节点NN1和NN2,其中NN1和NN2分别处于Active和StandBy状态。以下是升级HA群集的步骤:

  • 准备滚动升级

运行hdfs dfsadmin -rollingUpgrade prepare 以创建用于回滚的fsimage

运行hdfs dfsadmin -rollingUpgrade query 以检查回滚fsimage的状态。等待并重新运行命令,直到显示Proceeding with Rolling Upgrade信息。

  • 升级Active和StandBy NN

关闭并升级NN2。

启动NN2成为StandBy状态通过-rollingUpgrade started选项。

从NN1到NN2的故障转移,以便NN2变为活动状态,而NN1变为待机状态。

关闭并升级NN1。

启动NN1成为StandBy状态通过-rollingUpgrade started选项。

  • 升级DN

选择一小部分DN节点(例如,特定机架下的所有数据节点)。

运行hdfs dfsadmin -shutdownDatanode upgrade以关闭所选的DN。

运行hdfs dfsadmin -getDatanodeInfo 进行检查,然后等待DN关闭。

升级并重启DN节点。

对子集中的所有选定DN节点并行执行以上步骤。

重复上述步骤,直到升级群集中的所有DN节点。

  • 完成滚动升级

运行hdfs dfsadmin -rollingUpgrade finalize完成滚动升级。

升级联邦集群

在联邦集群中,有多个名称空间以及每个名称空间的一对Active和StandBy NN。升级联合群集的过程类似于升级非联邦群集的过程,不同之处在于为每个命名空间准备滚动升级。升级每个命名空间的Active和StandBy NN。升级DN,完成每个命名空间的滚动升级。

停机升级

对于非HA群集,无法在没有停机的情况下升级HDFS,因为它需要重新启动NN。但是,DN仍可以滚动方式升级。

升级非HA集群

在非HA群集中,有一个NameNode(NN),SecondaryNameNode(SNN)和许多DataNodes(DN)。升级非HA群集的过程与升级HA群集的过程类似,不同之处在于,将升级非HA集群中的第2步“升级活动和备用NN升级”更改为以下内容:

升级NN和SNN

关闭SNN。

关闭并升级NN。

使用-rollingUpgrade started 选项启动NN。

升级并重新启动SNN

降级和回滚

如果不希望使用升级版本,或者在某些不太可能的情况下,升级失败(由于较新版本中的错误),管理员可以选择将HDFS降级到升级前版本,或将HDFS回滚到升级前版本和升级前的状态。

请注意,降级可以滚动方式进行,但不能回滚。回滚要求集群停机。

还请注意,只有在开始滚动升级之后且终止升级之前,才可以进行降级和回滚。可以通过完成,降级或回滚来终止升级。因此,可能无法在完成或降级之后执行回滚,或者在完成后无法执行降级。

降级

降级会将软件还原回升级前的版本,并保留用户数据。假设时间T是滚动升级开始时间,并且升级通过降级终止。然后,在T之前或之后创建的文件在HDFS中仍然可用。在T之前或之后删除的文件在HDFS中仍然被删除。

仅当两个版本之间的namenode布局版本和datanode布局版本均未更改时,才可以将较新的版本降级为升级前的版本。

在高可用性集群中,当正在进行从旧软件版本到新软件版本的滚动升级时,可以滚动方式将升级后的计算机降级到旧软件版本。与之前相同,假设NN1和NN2分别处于活动状态和待机状态。以下是在不停机的情况下进行降级的步骤:

降级DN

选择一小部分数据节点(例如,特定机架下的所有数据节点)。

运行“ hdfs dfsadmin -shutdownDatanode upgrade ”以关闭所选的数据节点之一。

运行“ hdfs dfsadmin -getDatanodeInfo ”进行检查,然后等待数据节点关闭。

降级并重新启动datanode。

对子集中的所有选定数据节点并行执行以上步骤。

重复上述步骤,直到集群中所有升级的数据节点降级。

降级活动和备用NN

关闭和降级NN2。

正常启动NN2作为待机。

从NN1到NN2的故障转移,以便NN2变为活动状态,而NN1变为待机状态。

关闭并降级NN1。

正常启动NN1作为待机。

完成滚动降级

运行“ hdfs dfsadmin -rollingUpgrade finalize ”以完成滚动降级。

请注意,在降级名称节点之前,必须先降级数据节点,因为协议可以以向后兼容的方式更改,但不能向前兼容,即,旧的数据节点可以与新的名称节点对话,反之则不行。

回滚

回滚将软件还原到升级前的版本,但也将用户数据还原到升级前的状态。假设时间T是滚动升级开始时间,并且升级通过回滚终止。T之前创建的文件在HDFS中仍然可用,但T之后创建的文件不可用。T之前删除的文件在HDFS中仍然被删除,但是T之后删除的文件被恢复。

始终支持从较新版本回滚到升级前版本。但是,这不能以滚动方式完成。它需要集群停机。假设NN1和NN2分别处于活动状态和待机状态。以下是回滚的步骤:

回滚HDFS

关闭所有NN和DN。

在所有计算机上还原升级前的版本。

开始NN1为活动的“ -rollingUpgrade回滚”选项。

在NN2上运行-bootstrapStandby并以待机状态正常启动。

使用“ -rollback ”选项启动DN。

滚动升级相关命令

dfsadmin –rollingUpgrade

hdfs dfsadmin -rollingUpgrade <query|prepare|finalize>

image-20211109224302655

dfsadmin –getDatanodeInfo

hdfs dfsadmin -getDatanodeInfo <DATANODE_HOST:IPC_PORT>

获取有关给定datanode的信息。该命令可以像Unix ping命令一样用于检查数据节点是否处于活动状态。

dfsadmin –shutdownDatanode

hdfs dfsadmin -shutdownDatanode <DATANODE_HOST:IPC_PORT> [upgrade]

提交给定datanode的关闭请求。如果指定了可选的升级参数,则建议访问数据节点的客户端等待其重启,然后启用快速启动模式。如果重启不及时,客户端将超时并忽略数据节点。在这种情况下,快速启动模式也将被禁用。

请注意,该命令不会等待数据节点关闭完成。dfsadmin -getDatanodeInfo命令可用于检查数据节点关闭是否完成。

namenode –rollingUpgrade

hdfs namenode -rollingUpgrade <rollback|started>

image-20211109224405086