HDFS的数据迁移解决方案:
1,理解HDFS数据迁移方案及工具DistCp(分布式拷贝工具)的使用:
数据迁移的场景:
冷热集群数据同步,分类存储
集群数据整体搬迁(业务增长,需要将数据整体迁移到新的集群)
数据的准实时同步(数据准实时同步的目的在于数据的双备份可用,比如某天A集群突然宣告不允许再使用了,此时可以将线上使用集群直接切向B的同步集群
, 因为B集群实时同步A集群数据,拥有完全一 致的真实数据和元数据信息,所以对于业务方使用而言是不会受到任何影响的。)
数据迁移要素考量:
●Bandwidth-带宽:带宽用多了会影响线上的业务,带宽少了有会导致同步数据过慢的问题
●Performance-性能:采用简单的单机程序还是多线程的性能更佳的分布式程序?
●Data-Increment-增量同步:可以针对变化的增量数据进行同步。可以配合HDFS快照等技术实现增量数据的同步
●Syncable-数据迁移的同步性:数据迁移的过程中需要保证周期内数据是一定能够同步完的. 不能差距太大.比如A集群7天内的增量数据,我只要花半天就可以完全同步
到B集群,然后我又可以等到下周再次进行同步.最可怕的事情在于A集群的7天内的数据,我的程序花了7天还同步不完,然后下一一个周期又
来,这样就无法做到准实时的一致性.其实7天还是一个比较大的时间, 最好是能达到按天同步.
HDFS分布式拷贝工具:DistCp
DistCp是hadoop中的一种工具,在hadoop-tools工程下,作为独立子工程存在。
定位用于数据迁移,定期在集群之间和集群内部备份数据。
在备份过程中,每次运行DistCp都称为一个备份周期。尽管性能相对较慢,但是普及成都已经是越来越高。
DistCp底层使用mapreduce在集群之间活并行在同意集群内复制文件,执行复制的mapreduce只有mapper阶段。
●DistCp的优势:
带宽限流:可以通过参数来bandwidth来为程序进行带宽限流。
增量数据同步:可以使用三个参数实现增量的同步:
updata:只拷贝不存在的文件或者目录
Append:追加写目标路径下已存在的文件
diff: 通过快照的diff对比信息来同步源端路径于目标路径
updata解决了新增文件、目录的同步。append解决了已存在文件的增量更新同步。diff解决了删除或者重命名类型文件的同步
高性能性:分布式的特性
DistCp底层使用mapreduce执行数据同步,mapreduce本身一类分布式的程序。
●DistCp命令:
distcp options [source_path …] <target_path>
-append :拷贝文件时支持对现有文件进行追加写操作
-async :异步执行distcp拷贝任务
-bandwidth :对每个map任务的带宽限速
-delete :删除相对于源端,目标端多出的文件
-diff :通过快照diff信息进行数据的同步
-overwrite:已覆盖的方式进行拷贝,如果目标端已经就存在,则直接覆盖
-p :拷贝数据时,扩展属性信息的保留,包括权限信息,块大小信息等
-skipcrcccheck :拷贝文件时是否跳过cheacksum的校验
-updata:拷贝数据时,只拷贝相对于源端,目标端不存在的文件数据
其中 source_path、target_path需要【带上地址前缀以区分不通的集群】
例:hadoop distcp hdfs://nn1:8020/foo/a hdfs://nn2:8020/bar/foo
表示:从nn1集群拷贝/foo/a路径下的数据到nn2集群的/bar/foo路径下
HDFS namenode的安全模式:
●安全模式:只读,不可写和删除(是namenode的维护状态)
●在NameNode启动过程中 ,首先会从fsimage和edits日志文件加载文件系统状态。然后,等待DataNodes汇 报可用的block信息。在此期间, NameNode保持在安全模式。
随着DataNode的block汇 报持续进行,当整个系统达到安全标准时, HDFS自动离开安全模式。在NameNode Web主页上会显显安全模式是打开还是关闭。
HDFS的安全模式原理,进入离开的条件:
自动进入安全模式的时间:hdfs集群启动时,当namenode启动成功后,此时集群会自动进入安全模式
安全模式自动离开:条件由(hdfs-aite.xml、hdfs-default.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
手动进入安全模式:
hdfs dfsadmin -safemode enter
手动离开安全模式:
hdfs dfsadmin -safemode leave
HDFS高阶优化方案:
1,短路本地读取
●客户端读取数据的顺序:dfsclient->datanodes->data directores->datanodes->dfsclient ##读取数据要经过datanode中转,效率不高
理解:在HDFS中,不管是Local Reads ( DFSClient和Datanode在同一个节点)还是Remote Reads ( DFSClient和Datanode不在同一个节点) , 底层处理方式都是一样的,都是先由Datanode读取数据,然后再通过RPC (基于TCP )把数据传
给DFSClient。这样处理是比较简单的,但是性能会受到一些影响,因为需要Datanode在中间做一次中转。尤其Local Reads的时候,既然DFSClient和数据是在一个机器 上面,那么很自然的想法,就是让DFSC1 ient绕开
Datanode自己去读取数据。所谓的“短路”读取绕过了DataNode,从而允许客户端直接读取文件。显然,这仅在客户端与数据位于同一机器的情况下才可行。短路读取为许多应用提供了显着的性能提升。
实现:
在HDFS–347中,提出了一种新的解决方案 ,让短路本地读取数据更加安全。
在Linux中,有个技术叫做Unix Domain Socket。 Unix Domain Socket 是一种进程间的通讯方式,它使得同一个机器上的两个进程能以Socket的方式通讯。
它带来的另一大好处是,利用它两个进程除了可以传递普通数据外,还可以在进程间传递文件描述符。
●客户端获取数据的描述信息:dfsclient->datanodes->data directores->datanodes->(open)dfsclient ##客户端获取到数据描述符
●客户端读取数据的顺序:dfsclient->(read)file descriptor ###根据描述信息在本地找到数据
●配置:
需要安装:libhadoop.so
检查是否安装: hadoop checknative
配置hdfs-site.xml:
添加:dfs.client.read.shortcircuit–“true”
####打开短路读取本地功能的开关
dfs.domain.socket.path–"/var/lib/hadoop-hdfs/dn_socket"
###datanode和dfsclient之间沟通的socket的本地路径,需要先创建好"/var/lib/hadoop-hdfs"。dn_socket是文件,是系统之间生成的。
确认配置生效:配置修改完成启动集群,打开hadoop datanade的日志,查找“more /usr/local/hadoop/logs/hadoop-hadoop-datanode-master.log |grep domain”
[hadoop@master ~]$ more /usr/local/hadoop/logs/hadoop-hadoop-datanode-master.log |grep domain
2021-06-04 18:56:09,254 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Listening on UNIX domain socket: /var/lib/hadoop-hdfs/dn_socket
方式2:读取一个文件到本地
hdfs dfs -get /tmp/hadoop-yarn/staging/hadoop/.staging/job_1617001022520_0001 .
查看日志:[hadoop@master ~]$ more /usr/local/hadoop/logs/hadoop-hadoop-datanode-master.log |grep SHORT_CIRCUIT
2021-06-04 19:06:48,450 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: cliID: DFSClient_NONMAPREDUCE_-754604018_1, src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_SHM, shmId: 6586ba296ba797be3e7d0e6b93370ffa, srvID: b9d1d200-1bfb-499b-9b5b-07677a4dfbc9, success: true
2021-06-04 19:06:48,484 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS, blockid: 1073741826, srvID: b9d1d200-1bfb-499b-9b5b-07677a4dfbc9, success: true
2021-06-04 19:06:48,553 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS, blockid: 1073741827, srvID: b9d1d200-1bfb-499b-9b5b-07677a4dfbc9, success: true
2021-06-04 19:06:48,559 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS, blockid: 1073741828, srvID: b9d1d200-1bfb-499b-9b5b-07677a4dfbc9, success: true
2,负载均衡
●HDFS数据可能并不总 是在DataNode之间均匀分布。一个常见的原因是向现有群集中添加了新的DataNode。HDFS提供
了一个Balancer程序,分析block放置信息并且在整个DataNode节点之间平衡数据,直到被视为平衡为止。
●所谓的平衡指的是每个DataNode的利用率(本机已用空间与本机总容量之比)与集群的利用率( HDFS整体已用空间
与HDFS集群总容量的比)之间相差不超过给定阈值百分比。
●平衡器无法在单个DatalNode.上的各个卷(磁盘)之间进行平衡。
●命令行:
hdfs balancer --help ##查看参数
-threshold 10 ##集群平衡的条件,datanode间磁盘使用率相差阈值,区间:0-100
-policy datanode ##平衡策略,默认为datanode,若datanode平衡,则集群已平衡
-ecxclude -f /tmp/ip1.txt ##默认为空,指定该部分IP不参与balance,-f 指定输入为文件
-iclude -f /tmp/ip2.txt ##默认为空,只允许这部分ip参与balance,-f指定输入为文件
-idleiteation 5 ###迭代5
●如何运行
设置平衡数据传输带宽
hdfs dfsadmin -setBalancerBandwidth new_bandwidth
其中new_bandwidth是每个datanode在平衡操作期间可以使用的最大网络带宽,以每秒字节数为单位。
例如:hdfs dfsadmin -setBalancerBandwidth 104857600(100M)
运行balancer:
默认参数运行:hdfs balancer
例:指定阈值运行:hdfs balancer -threshold 5 ##balancer将以阈值5%运行(默认10%)
3,磁盘均衡器(HDFS Disk Balancer)[hadoop3.0引入的]:
作用:均衡单个datanode中各个磁盘的存储数据平衡
单机中的存储策略:
●循环策略:它将新block均匀分布在可用磁盘上。默认此策略。
●可用空间策略:此策略将数据写入具有更多可用空间(按百分比)的磁盘。
功能:
1,数据传播报告:
为了衡量集群中哪些计算机遭受数据分布不均的影响,磁盘平衡器定义了Volume Data Density metric (卷/磁盘数据密度度量标准)
和Node Data Density metric (节点数据密度度量标准)。
●卷/磁盘数据密度度量标准:比较同台机器上不通卷之间的数据分布情况
●节点数据密度度量标准:比较的是不同机器之间的
2,磁盘平衡
hdfs disk balancer开启:
默认情况下,hadoop集群上已经启用了disk balancer功能。通过hdfs-site.xml中调整
dfs.disk.balancer.enabled参数值,选择在hadoop中是否启用磁盘均衡器
相关命令:
1,plan计划:
命令:hdfs diskbalancer -plan
-out ###控制计划文件的输出位置
-bandwidth ##设置用于disk balancer的最大带宽。默认是10M/s
-thresholdPercentage #定义磁盘开始参与数据重新分配或平衡操作的值默认的thresholdPercentage值为10%,
#这意味着仅当磁盘包含的数据比理想存储值多10%或更少时,磁盘才用于平衡操作.
-maxerror ###它允许用户在中止移动步骤之前为两个磁盘之间的移动操作指定要忽略的错误数.
-V #详细模式,指定此选项将强制plan命令在stdout上显示计划的摘要.
-fs #此选项指定要使用的NameNode如果未指定则Disk Balancer将使用配置中的默认NameNode.
2,Execute执行:
hdfs diskbalancer -execute
execute命令针对为其生成计划的datanode执行计划
Query查询:
hdfs diskbalancer -query
query命令从运行计划的datanode获取hdfs磁盘均衡器的当前状态
3,Canel取消:
hdfs diskbalancer -canel
hdfs diskbalancer -canel planID node
canel 命令取消运行计划
Report汇报:
hdfs diskbalancer -fs hdfs://nn_host:8020 -report ###这里的端口是8020/9000
4,纠删码存储技术(EC):
●纠删码技术 ( Erasure coding )简称EC ,是一种编码容错技术。最早用于通信行业,数据传输中的数据恢复。它通
过对数据进行分块,然后计算出校验数据,使得各个部分的数据产生关联性。当-部分数据块丢失时,可以通过剩
余的数据块和校验块计算出丢失的数据块。
Reed-Solomon(RS)码是常用的一种纠删码,他有两个参数k,m 。记为RS(k,m)。
k个数据块组成一个向量被乘上一个生成矩阵( Generator Matrix ) GT从而得到一个码字(codeword)向量,该向量由k个数据块( d0, d1. . d3 )和m个校验块(c0,c1 )构成。
如果数据块失,可以用GT逆矩阵乘以码字向量来恢复出丢失的数据块。
hadoop EC架构:
node扩展:
条带化的hdfs文件在逻辑上由block group(块组)组成,每个块组包含一定量的内部块,这允许在块组级别而不是快级别进行文件管理。
客户端扩展:
客户端的读写路径得到增强,可以并行处理块组中的多个内部块
Datanode扩展:
DataNode运行一个附加的ErasureCodingWorker ( ECorker )任务,以对失败的纠删编码块进行后台恢复。NameNode检测到失败的
EC块,然后NameNode选择一个DataNode进行恢复 工作。
EC集群的部署方式:
●Stepl :集群和硬件配置
编码和解码二工作会消耗HDFS客户端和DataNode.上的额外CPU。
纠删码文件也分布在整个机架上,以实现机架容错。这意味着在读写条带化文件时,大多数操作都是在机架上进行的。因此,网络带宽也非常重要。
对于机架容错,拥有足够数量的机架也很重要,每个机架所容纳的块数不超过EC奇偶校验块的数。机架数量= ( 数据块+奇偶校验块) /奇偶校验块后取整。
比如对于EC策略RS (6,3) , 这意味着最少3个机架(由(6 + 3)/ 3 = 3计算) , 理想情况下为9个或更多,以处理计划内和计划
外的停机。对于机架数少于奇偶校验单元数的群集, HDPS无法维持机架容错能力,但仍将尝试在多个节点之间分布条带化文件以保留节
点级容错能力。因此,建议设置具有类似数量的DataNode的机架。
●Step2 :纠删码策略设置
纠删码策略由参数dfs. namenode. ec. system. default. policy指定,默认是RS- 6-3-1024k
(RS表示编码器算法Reed- Solomon, 6、3中表示数据块和奇偶校验块的数量, 1024k表示条带化单元的大小。),其他策略默认是禁用的。
可以通过hdfs ec [-enablePolicy -policy ]命令启用策略集。
●Step3 :启用英特尔ISA-L (智能存储加速库)
默认RS编解码器的HDFS本机实现利用Intel ISA-L库来改善编码和解码计算。要启用和使用Intel ISA-L ,需要执行三个步骤。
1)建立ISA-L库;
2)使用ISA-.支持构建Hadoop ;
3)使用Dbundle.isal将isal.lib目录的内容复制到最终的tar文件中。使用tar文件部署Hadoop。确保ISA-L在HDFS客户端和DataNode上可用。
●Step4 : hdfs ec
[-setPolicy -path
#在指定路径的目录上设置擦除编码策略。
#ath: HDFS中的目录。这是必填参数。设置策略仅影响新创建的文件, 而不影响现有文件。
#policy:用于此目录下文件的擦除编码策略。默认RS-6-3-1024k策略。
#replicate在目录上应用默认的REPLICATION方案,强制目录采用3x复制方案。replicate 和-policy 是可选参数。不能同时指定它们。
[-getPolicy -path < path >]
#获取指定路径下文件或目录的擦除编码策略的详细信息。
[-unsetPolicy -path < path >]
#取消设置先前对日录上的setPolicy的调用所设置的擦除编码策略。如果该日录从祖先日录继承了擦除编码策略,则unsetPolicy是no-op。在没有显式策略集的目录上取消策略将不会返回错误。
[-listPolicies]
#列出在HDFS中注册的所有(启用,禁用和删除)擦除编码策略。只有启用的策略才适合与setPolicy命令-起使用。
[-addPolicies -policyFile <文件>]
#添加用户定义的擦除编码策略列表。。
[-listCodecs]
#获取系统中支持的擦除编码编解码器和编码器的列表。
[-removePolicy -policy ]
#删除用户定义的擦除编码策略。
[-enablePolicy -policy ]
#启用擦除编码策略。
[-disablePolicy -policy ]
#禁用擦除编码策略。
注释:需要先创建好编码策略,然后启用才可以
HDFS动态节点管理:
动态扩容(节点上线):
step1 :新机器基础环境准备:
●主机名、ip
●hosts映射
●防火墙,时间同步
●ssh免密登录
●jdk环境
step2 :hadoop配置:
●修改namenode节点workers配置文件,增加节点主机名,便于后续一键启停
●从namenode节点复制hadoop安装包到新节点。注意不包括hadoop.tmp.dir指定的数据存储目录
scp -r /usr/local/hadoop hadoop@slave3:/usr/local/
或者 cd /usr/local/ ;scp -r /usr/local/hadoop hadoop@slave3:$PWD
注:要事先在新机器中建好目录(不是root用户的话),要不然会报scp没权限问题
●新机器上配置Hadoop环境变量
step3 :手动启动datanode进程:
●hadoop-daemon.sh start datanode 或者 hdfs --daemon start datanode
报错:ERROR: Cannot set priority of datanode process 4217
看日志:Too many failed volumes - current valid volumes: 0, volumes configured: 1, volumes failed: 1, volume failures tolerated: 0
原因:存放数据的路径dfs属性是root的,需要改为hadoop
解决:root操作:chown -R hadoop:hadoop hadoop
●yarn-daemon.sh start nodemanager 或者 yarn --daemon start nodemanager
step4 :datanode的负载均衡(主节点操作):
新加的机器没有数据,需要和旧的datanode做一个负载均衡:
设置负载均衡的数据传输带宽:hdfs dfsadmin -setBalancerBandwidth 104857600
然后启动balancer,等待集群自均衡完成即可:hdfs balancer -threshold 5
动态缩容(节点下线):
step1 :添加退役节点:
在namenode机器hdfs-site.xml配置文件中需要提前配置dfs.hosts.exclude属性,该属性指向的文件就是所谓的黑名单列表,
会被namenode排除在集群外。如果文件内容为空,则意味着不禁止任何机器
这个配置具有前瞻性,建集群时提前加进去,否则需要重启集群加载
dfs.hosts.exclude
/usr/local/hadoop/etc/hadoop/excludes
datanode黑名单
注意:如果副本数是3,服役的节点数小于等于3,是不能退役成功的,需要修改副本数后才可以成功退役
step1 :刷新集群
在namanode所在集群刷新节点:hdfs dfsadmin -refreshNodes
等待退役节点服务器状态为decommissioned(所有块已经复制完成)
例:[hadoop@master local]$ hdfs dfsadmin -refreshNodes
Refresh nodes successful
白名单:
●所谓的白名单指的是允许哪些机器加入到当前的HDFS集群中,是一种准入机制。
●名单由dfs.hosts参数指定,该参数位于hdfs-site.xml。默认值为空。
●dfs.hosts指向文件,文件包含允许连接到namenode的主机列表。必须指定文件的完整路径名。如果该值为空则允许所有主机准入。
黑名单:
●所谓的黑名单指的是禁止哪些机器加入到当前的HDFS集群中。是一种禁入机制。
●黑名单由dfs. hosts. exclude参数指定,该参数位于hdfs -site. xml。默认值为空。
●dfs. hosts. exc lude指向文件。该文件包含不允许连接到名称节点的主机列表。必须指定文件的完整路径名。如果该值为空,则不禁上任何主机加入。
HDFS 的HA高可用机制:
HA系统设计核心问题( 1 )
●脑裂问题:
脑裂(split-brain)是指”大脑分裂”, 本是医学名词。
在HA集群中,脑裂指的是当联系主备节点的"心跳线”断开时(即两个节点断开联系时) ,本来为一个整体、动作协调的HA系统,就分
裂成为两个独立的节点。由于相互失去了联系,主备节点之间像裂脑人"-样,使得整个集群处于混乱状态。脑裂的严重后果:
1 )集群无主:都认为对方是状态好的,自己是备份角色,后果是无服务;
2)集群多主:都认为对方是故障的,自己是主角色。相互争抢共享资源,结果会导致系统混乱,数据损坏。此外对于客户端访问也是一头雾水,找谁呢?
避免脑裂问题的核心是:保持任意时刻系统有且只有一个主角色提供服务。
HA系统设计核心问题( 2)
●数据状态同步问题
备切换保证服务持续可用性的前提是主备节点之间的状态数据是一致的 ,或者说准一致的。 如果说备用的节点和主节点之间的数据差距过大,即使完成了主备切换的动作,那也是没有意义的。
数据同步常见做法是:通过日志重演操作记录。主角色正常提供服务,发生的事务性操作通过日志记录,备用角色读取日志重演操作。
解决:
●在同一群集中运行两个(从3.0. 0起.支持超过两个)冗余NameNode. 形成主备架构。
●这样可以在机器崩溃的情况 下快速故障转移到新的NameNode ,或者出于计划维护的目的由管理员发起的正常故障转移。
Quorum Journal Manager介绍
●QJM全称Quorum Journal Manager (仲裁日志管理器), Hadoop官方推荐的HDFS HA解决方案之一。
●使用zookeeper中ZKFC来实现主备切换 ;
●使用Journal Node(JN )集群实现edits_log的共享以达到数据同步的目的。
主备切换、脑裂问题解决–ZKFai loverController ( zkfc )
ZKFailoverController ( ZKFC )是一个ZooKeeper客户端。主要职责:
1)监视和管理NameNode健康状态
ZKFC通过命令监视的NameNode节点及机器的健康状态。
2)维持和ZK集群联系
如果本地NameNode运行状况良好,粗ZKFC看到当前没有其他节点持有锁znode ,它将自己尝试获取该锁。如果成功,则表明它"赢得了选举”,
复责运行故障转移以使其本地NameNode处于Active状态。如果已经有其他节点持有锁,zkfc选举失败,则会对该节点注册监听,等待下次继续选举。
主备切换、脑裂问题解决–Fencing( 隔离)机制
●故障转移过程也就是俗称的主备角色切换的过程 .切换过程中最怕的就是脑裂的发生。因此需要Fencing机制来避免,将先前的Active节点隔离,然后将Standby转换为Active状态。
●Hadoop公共库中对外提供了两种Fenching实现,分别是sshfence和shellfence (缺省实现)。
sshfence是指通过ssh登陆目标节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid ,该方法比ips命令更准确);
shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。
主备数据状态同步问题解决
●Journal Node ( JN)集群是轻量级分布式系统,主要用于高速读写数据、存储数据。
●通常使用2N+1台JournalNode存储共享edits Log (编辑日志)。–底层类似于zk的分布式一致性算法。
●任何修改操作在 Active NN 上执行时, JournalNode进程同时也会记录edits log到至少半数以上的JN中,这时
Standby NN监测到JN里面的同步log发生变化了会读取JN里面的edits log ,然后重演操作记录同步到自己的目录镜像树里面。
HA hdfs配置:
strp1:基础环境的准备:
1,修改linux主机名 /etc/hostanme
2,修改ip vim /etc/sysconfig/network-scripts/ifcfg-enp0s3
3,修改主机名和hosts的映射关系
4,关闭防火墙
5,ssh免密登陆
6,安装JDK,配置环境变量 /etc/profile
7,集群时间同步
8,配置准备NN之间的互相免密登陆
step2: HA集群规划
机器 运行角色
master namenode、zkfc、datannode、zookeeper、journal node(共享编辑日志,edits log)
slave1 namenode、zkfc、datannode、zookeeper、journal node
slave2 datannode、zookeeper、journal node
操作:
上传安装包
解压缩:tar -zxvf /usr/local/hadoop-3.2.2.tar.gz -C /usr/local/
mv /usr/local/hadoop-3.2.2 /usr/local/hadoop
配置hadoop环境变量:
#hadoop
export HADOOP_HOME=/usr/local/hadoop
export PATH=
H
A
D
O
O
P
H
O
M
E
/
b
i
n
:
HADOOP_HOME/bin:
HADOOPHOME/bin:HADOOP_HOME/sbin:$PATH
修改hadoop-env.sh
vim /usr/local/hadoop/etc/hadoop/hadoop-env.sh
export JAVA_HOME=/usr/local/jdk-16 ###找到修改
export HDFS_NAMENODE_USER=hadoop ##添加
export HDFS_JOURNALNODE_USER=hadoop ##添加
export HDFS_DATANODE_USER=hadoop ##添加
export HDFS_ZAKC_USER=hadoop ##添加
修改core-site.xml:
vim /usr/local/hadoop/etc/hadoop/core-site.xml
fs.defaultFS
hdfs://mycluster
hadoop.tmp.dir
/tmp/data/ha-hadoop
ha.zookeeper.quorum
master:2181,slave1:2181,slave2:2181
修改hdfs-site.xml:
dfs.nameservices
mycluster
<!--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>master:8020</value>
</property>
<!--nn1的http通信地址-->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>master:9870</value>
</property>
<!--nn2的rpc通信地址-->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>slave1:8020</value>
</property>
<!--nn2的http通信地址-->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>slave1:9870</value>
</property>
<!--指定namenode的edits元数据在journalnode上的存放位置-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://master:8485;slave1:8485;slave2:8485/mycluster</value>
</property>
<!--指定journalnode在本地磁盘存放数据的位置-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/tmp/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>/home/hadoop/.ssh/id_rsa</value>
</property>
<!--配置sshfence隔离机制超时时间-->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
修改mapred-site.xml:
vim /usr/local/hadoop/etc/hadoop/mapred-site.xml
<!--指定mr框架为yarn方式-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
yarn-HA的配置
官方文档:https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
修改yarn-site.xml:
vim /usr/local/hadoop/etc/hadoop/yarn-site.xml
<!--开启mr高可用-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!--指定rm的cluster id-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</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>master</value>
</property>
<!--分别指定rm的地址-->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>slave1</value>
</property>
<!--指定zk集群地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>master:2181,slave1:2181,slave2:2181</value>
</property>
<!--指定shuffle-->
<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>
修改workers文件:
vim /usr/local/hadoop/etc/hadoop/workers
master
slave1
slave2
集群同步安装包:
master上操作:
chown -R hadoop:hadoop /usr/local/hadoop
chown -R hadoop:hadoop /tmp
scp -r /usr/local/hadoop slave1:/usr/local/
scp -r /usr/local/hadoop slave2:/usr/local/
在slave1,slave2上操作:
chown -R hadoop:hadoop /usr/local/hadoop
chown -R hadoop:hadoop /tmp
HA集群初始化:
启动zk集群:
su - hadoop
启动方式1:每台集群都去操作:zookeepers.sh
启动方式2:自写脚本 zoo_start.sh start
脚本为:
#!/bin/bash
case $1 in
"start"){
for i in master slave1 slave2
do
ssh $i "/usr/local/zookeeper/bin/zkServer.sh start"
done
};;
"restart"){
for i in master slave1 slave2
do
ssh $i "/usr/local/zookeeper/bin/zkServer.sh stop"
ssh $i "/usr/local/zookeeper/bin/zkServer.sh start"
done
};;
"stop"){
for i in master slave1 slave2
do
ssh $i "/usr/local/zookeeper/bin/zkServer.sh stop"
done
};;
esac
手动启动JN集群(3台机器):
启动方式1:每台集群都去操作:hdfs --daemon start journalnode
启动方式2:自写脚本 jn.sh start
脚本为:
#!/bin/bash
case $1 in
"start"){
for i in master slave1 slave2
do
ssh $i "/usr/local/hadoop/bin/hdfs --daemon start journalnode"
done
};;
"restart"){
for i in master slave1 slave2
do
ssh $i "/usr/local/hadoop/bin/hdfs --daemon start journalnode"
ssh $i "/usr/local/hadoop/bin/hdfs --daemon stop journalnode"
done
};;
"stop"){
for i in master slave1 slave2
do
ssh $i "/usr/local/hadoop/bin/hdfs --daemon stop journalnode"
done
};;
esac
格式化namonode:
在master上执行:
格式化:hdfs namenode -format ##格式化后会根据在core-site.xml中的hadoop.tmp.dir配置的目录下生成hdfs初始化文件
启动namenode进程:hdfs --daemon start namenode
在slave1上进行元数据同步:
hdfs namenode -bootstrapStandby
格式化ZKFC(在active的namenode机器上执行[在哪个机器上执行,哪个机器就是active]):
hdfs zkfc -formatZK ##手动敲,避免复制的时候格式啥的出错【格式化】
hdfs --daemon start zkfc ###启动zkfc
启动HDFS(在active的namenode机器上执行)
start-dfs.sh
启动yarn:
start-yarn.sh
错误:可能主动切换namenode不成功,出现nn1节点的namenode挂掉后nn2还是standby状态,再启动nn1时,nn1也是standby状态的情况。这是由于centos7最小化安装导致系统中没有
fuser导致的,使用yum -y install psmisc安装即可【两个namenode都要操作】
旧集群的启动:
1,hdfs --daemon start namenode
2,hdfs --daemon start zkfc
3,hdfs --daemon start journalnode
4,start-dfs.sh 或者hdfs --daemon start datanode
5,start-yarn.sh 或者yarn --daemon start resourcemanager
HDFS Federation联邦机制:
当前的HDFS架构有两个主要的层:
●命名空间( namespace )
由文件,块和目录组成的统一抽象的目录树结构。 由namenode根据用户操作实时维护树结构。
●块存储层 ( Block Storage )
包括两个部分:
➢块管理: NameNode执行块管理。 块管理通过处理注册和定期心跳来提供DataNode群集成员身份。它处理块报告并支持与块相关的操作,如创建,删除,修改或获取块位置。它还维护块的位置,副本位置。为未复制的块管理块复制,并在已复制的块中删除。
➢存储: DataNode通过在本地文件系统上存储块并提供读(写访问权限来管理存储空间。
当前HDFS体系架构–局限性:
当下的HDFS体系结构仅允许单个NameNode维护文件系统名称空间。这种体系目前存在着一些弊端和局限性 :
●DataNode磁盘存储空间不够增加节点, NameNode内存不够是否可以无限扩容。思考一下: 一种是DataNode横向扩展机器增加节点, 一种是纵向扩展单机加内存。
●由于名称空间和存储层的紧密耦合, NameNode的替代实现很困难。这限制了其他服务直接使用块存储。NameNode成了唯一入口。
●文件系统的操作还限于NameNode一次处理的任务数。因此,群集的性能取决于NameNode吞吐量。
●同样,由于使用单个名称空间,因此使用群集的占用者组织之间没有隔离。
联邦Federation架构–简介:
●Federation中文意思为联邦,联盟,是NameNode之间的Federat ion,也就是集群中会有多个NameNode。多个NameNode的情况意味着有多个namespace。注意,这区别于HA模式下的多NameNode , HA中它们是拥有着同一个namespace.
●Federation体系中多个namenode之间相互独立且不需要互相协调,各自分工,管理自己的区域。每个DataNode要向集群中所有的namenode注册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。
联邦Federation架构–好处:
●命名空间可伸缩性
使用Federation ,可以水平扩展名称空间。这对大型群集或包含太多文件的群集有利,因为向群集添加了更多的NameNode。
●性能
由于文件系统操作不受单个NameNode吞吐量的限制,因此可以提高文件系统的性能。
●隔离
由于有多个名称空间,它可以为使用群集的占用者组织提供隔离。
HDFS集群滚动升级:
介绍:
●在Hadoop v2中, HDFS支持NameNode高可用( HA)。使得不停机升级HDFS变得可行。请注意,仅从Hadoop-2. 4. 0起才支持滚动升级。
●因此为了在不停机的情况下升级HDFS群集,必须使用HA设置群集。
●在HA群集中,有两个或多个NameNode ( NN) ,许多DataNode ( DN), 一些JournalNode ( JN )和一些ZooKeeperNode( ZKN)。
●JN相对稳定,在大多数情况下,升级HDFS时不需要升级。
●滚动升级过程中,仅针对NNs和DNs , JNS和ZKNs都没有。升级JN和ZKN可能会导致群集停机。
不停机滚动升级–非联邦HA集群:
假设有两个名称节点NN1和NN2 ,其中NN1和NN2分别处于Active和StandBy状态。
●Stepl :滚动升级准备
#创建一个新的tsimage文件用于回滚:
hdfs dfsadmin -ollingUpgrade prepare
#不断运行下面命令检查回滚fsimage是否创建完毕。
#如果显示Proceeding with Rolling Upgrade表示已经完成。
hdfs dfsadmin -ollingUpgrade query
●Step2:升级Active N和Standbys NN
#关闭NN2 :
hdfs --daemon stop namenode
#升级启动NN2:
hdfs --daemon start namenode -rollingUpgrade started
#做一次failover切换, 使得NN2成为Active节点NN1变为Standby节点
#关闭NN1:
hdfs - daemon stop namenode
#升级启动NN1 :
hdfs --daemon start namenode -rollingUpgrade started
有两个名称节点WI和M2 ,经过升级自前12:ire状志。
●Step3: 升级DN
#选择整体中的一小部分DataNode 节点进行升级(比如按照DataNode所在的不同机架来筛选)。
#关闭开级所选的DN其中IPC_PORT由参数dfs.datanode.ipc.address指定,默认9867.
hdfs dfsadmin -shutdownDatanode <DATANODE_HOST:IPC_PORT> upgrade
#检查下线DataNode是否已经停止服务如果还能得到节点信息,意味着此节点还未真正被关闭。
hdfs dfsadmin -getDatanodelnfo <DATANODE_HOST:IPC_PORT>
#启动DN节点。
hdfs --daemon start datanode
#对选中的所有DN节点执行以上步骤。
#重复上述步骤,直到升级群集中的所有DN节点。
●Step4:完成滚动升级
#完成滚动升级
hdfs dfsadmin -rollingUpgrade finalize
不停机滚动升级–联邦HA集群:
●联邦集群 ( federation )是拥有多namespace的集群。每个namespace对应一对主备NameNode节点。
●上述这套 集群就是俗称的联邦+HA集群。
联邦集群的升级过程与非联邦集群的升级过程比较相似,没有什么本质区别,只是需要为不同的namespace多重复执行几遍升级操作而已。
操作步骤:
#1、在每个namespace下执行升级级准备
hdfs dfsadmin -rollingUpgrade prepare
#2、升级每个namespace下的Active/Standby节点
#2.1、关闭NN2:
hdfs --daemon stop namenode
#2.2、升级启动NN2:
hdfs --daemon start namenode -rollingUpgrade started
#2.3、做一次tailover切换,使得NN2成为Active节点NN1变为Standby节点。
#2.4、关闭NN1:
hdfs --daemon stop namenode
#2.5、升级启动NN1:
hdfs --daemon start namenode -rollingUpgrade started
#3、升级每个DataNode节点
#3.1、关闭升级所选的DN其中IPC_PORT由参数dts.datanode.ipc.address指定,默认9867。
hdfs dfsadmin -shutdownDatanode <DATANODE_HOST:IPC_PORT> upgrade
#3.2、检查下线DataNode是否已经停止服务.如果还能得到节点信息,意味着此节点还未真正被关闭。
hdfs dfsadmin -getDatanodelnfo <DATANODE_HOST:IPC_PORT>
#3.3.启动DN节点。
hdfs --daemon start datanode
#4、升级过程执行完毕在每个namespace下执行finalize确认命令.
hdfs dfsadmin -rollingUpgrade finalize
停机升级–非HA集群
●在升级的过程中, 势必会存在服务短暂停止的时间,因为NameNode需要重启,而这段时间并没有备用节点可选.
●整体过程同非联邦HA模式的4个步骤类似。 过步骤二的过程要略微修改 :
#Step1:滚动升级准备
hdfs dfsadmin -rollingUpgrade prepare
#Step2:升级NN和SNN
#1、关闭NN
hdfs --daemon stop namenode
#、升级启动NN 1
hdfs --daemon start namenode -ollingUpgrade started
#3、停止SNN
hdfs --daemon stop secondarynamenode
#4、开级启动SNN
hdfs -daemon start secondarynamenode -ollingUpgrade started
#Step3:升级DN
#3.1、关闭升级所选的DN其中IPC_PORT由参数dts.datanode.ipc.address指定,默认9867。
hdfs dfsadmin -shutdownDatanode <DATANODE_HOST:IPC_PORT> upgrade
#3.2、检查下线DataNode是否已经停止服务.如果还能得到节点信息,意味着此节点还未真正被关闭。
hdfs dfsadmin -getDatanodelnfo <DATANODE_HOST:IPC_PORT>
#3.3.启动DN节点。
hdfs --daemon start datanode
#Step4:完成滚动升级
hdfs dfsadmin -rollingUpgrade finalize
HDFS集群降级和回滚:
降级( downgrade )和回滚( rollback)区别
●共同点:
都会将版本退回到升级前的版本;
在升级的finalize动作执行之后,将不允许再执行降级和回滚。
●不同点:
降级能支持ro1lling的方式,可以滚动降级,而回滚需要停止服务-段时间,
降级过程只会将软件版本还原成升级前的,会保留用户现有的数据状态;
而回滚则会将用户数据还原成升级前的状态模式,现有的数据状态不保存。
降级( downgrade )和回滚( rollback )
●友情提示: 升级慎重,降级、回滚更要慎重。
生产环境中,集群升级之前必须进行科学调研,评估升级后的版本跟现有业务的兼容性。
在测试环境下完整模拟升级流程,且针升级前集群状态进行备份,避免意外发生导致集群中断。
不要奢求升级失败时,通过回滚、降级等操作挽救集群。
HA集群降级( downgrade ):
●Stepl :降级DataNode
#1.选中部分集合DataNode节点(可以按照机架进行区分)
#执行降级操作,其中IPC PORT由参数dfs. datanode.ipc.address指定,默认9867.
hdfs dfsadmin -shutdownDatanode <DATANODE_HOST:IPC_PORT> upgrade
#执行命令检查节点是否完全停止
hdfs dfsadmin -getDatanodelnfo <DATANODE_HOST:IPC_PORT>
并在选中集合内的其他DataNode节点上重复执行上述操作.
#2.在集群中所有的DataNode节点上重复执行1.的操作.
●Step2 :降级Active NameNode和Standby NameNode
#停止并降级Standby NameNode.
#正常启动Standby NameNode.
#触发failovert切换,使得主备角色对调
#停止并降级之前属于Active (现属于Standby的NameNode)
#正常启动作为Standby节点
●Step3 :降级操作的确认
##完成降级操作
hdfs dfsadmin -rollingUpgrade finalize
HA集群降级( downgrade )注意事项:
●降级与升级在HA模式下有一个共同点
在操作NameNode时,都是先从Standby节点开始操作,等Standby节点升/降结束,做一次切换使另外一个节点得以进行升/降操作.在全程中,始终保持一个Active节 点对外提供服务。
●降级过程NameNode与DataNode的操作和在升级时操作顺序正好相反
新版本一般在协议、API是兼容老版本的,如果先降级NN,那么则会造成DN是新版,NN是旧版。
新DN中的许多协议将会在旧版NN中可能不兼容。
所以这里必须要先降级DN,然后再把服务端NN进行降级.看似简单的一次顺序颠倒,背后其实是有更深层的原因的.
●联邦集群和非HA集群的降级操作与升级操作相对应,进行相应操作命令的替换即可。
集群回滚( rollback )操作
●回滚注意事项:
Rollback不支持滚动操作的方式,在操作期间,它需要集群对外停止提供服务.
Rollback操作不仅会将软件版本退回到升级前的版本,还会将用户数据退回到升级前的状态
●回滚步骤
#1.停止所有的NameNode利DataNode节点
#2.在所有的节点机器上恢复升级前的软件版本
#3.在NN1节点上执行-rollingUpgrade rollback命令来启动NN1,将NN1作为Active节点
#4.在NN2上执行-bootstrapStandby命令并正常启动NN2,将NN2作为Standby节点
#5.以-rollback参数启动所有的DataNode.