数据迁移的使用场景:
冷热集群数据同步、分类存储
集群数据整体搬迁
当公司的业务迅速的发展,导致当前的服务器数量资源出现临时紧张的时候,为了更高效的利用资源,会将原A机房数据整体迁移到B机房的,原因可能是B机房机器多,而且B机房本身开销较A机房成本低些等;
数据准实时同步的目的在于数据的双备份可用,比如某天A集群突然宣告不允许再使用了,此时可以将线上使用集群直接切向B的同步集群,因为B集群实时同步A集群数据,拥有完全一致的真实数据和元数据信息,所以对于业务方使用而言是不会受到任何影响的。
数据迁移要素考量:
带宽用的多了,会影响到线上业务的任务运行,带宽用的少了又会导致数据同步过慢的问题。
是采用简单的单机程序?还是多线程的性能更佳的分布式程序?
当TB,PB级别的数据需要同步的时候,如果每次以全量的方式去同步数据,结果一定是非常糟糕。如果仅针对变化的增量数据进行同步将会是不错的选择。可以配合HDFS快照等技术实现增量数据同步。
数据迁移的过程中需要保证周期内数据是一定能够同步完的,不能差距太大.比如A集群7天内的增量数据,我只要花半天就可以完全同步到B集群,然后我又可以等到下周再次进行同步.最可怕的事情在于A集群的7天内的数据,我的程序花了7天还同步不完,然后下一个周期又来了,这样就无法做到准实时的一致性.其实7天还是一个比较大的时间,最好是能达到按天同步.
优势:
DistCp可以通过命令参数 bandwidth 来为程序进行带宽限流。
在DistCp中可以通过update 、append 和diff 这3个参数实现增量同步。
Update 只拷贝不存在的文件或者目录。
Append 追加写目标路径下己存在的文件。
Diff 通过快照的diff对比信息来同步源端路径与目标路径。
Update解决了新增文件、目录的同步。Append解决己存在文件的增量更新同步。 Diff解决删除或重命名类型文件的同步。
DistCp底层使用MapReduce执行数据同步,MapReduce本身是一类分布式程序。
命令:
$ hadoop distcp
usage: distcp OPTIONS [source_path...]
-append //拷贝文件时支持对现有文件进行追加写操作
-async //异步执行distcp拷贝任务
-bandwidth //对每个Map任务的带宽限速
-delete //删除相对于源端,目标端多出来的文件
-diff //通过快照diff信息进行数据的同步
-overwrite //以覆盖的方式进行拷贝,如果目标端文件已经存在,则直接覆盖
-p //拷贝数据时,扩展属性信息的保留,包括权限信息,块大小信息等等
-skipcrccheck //拷贝数据时是否跳过cheacksum的校验
-update //拷贝数据时,只拷贝相对于源端 ,目标端不存在的文件数据
其中 source_path 、target_path 需要带上地址前缀以区分不同的集群
例如 :hadoop distcphdfs://nnl:8020/foo/a hdfs://nn2:8020/bar/foo
上面的命令表示从nnl集群拷贝/foo/a 路径下的数据到nn2集群的/bar/foo 路径下。
概述:
安全模式自动进入:HDFS集群启动时,当NameNode启动成功之后,此时集群就会自动进入安全模式。
安全模式自动离开:自动离开条件(hdfs-site.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上的数据是只读的。
hdfs dfsadmin -safemode leave
概述:
老版本实现:
安全性改进版设计实现:
配置:
因为Java不能直接操作Unix Domain Socket,所以需要安装Hadoop的native包libhadoop.so。在编译Hadoop源码的时候可以通过编译native模块获取。可以用如下命令来检查native包是否安装好。
hadoop checknative
ldfs.client.read.shortcircuit 是打开短路本地读取功能的开关
ldfs.domain.socket.path 是Datanode和DFSClient之间沟通的Socket的本地路径。
dfs.client.read.shortcircuit
true
dfs.domain.socket.path
/var/lib/hadoop-hdfs/dn_socket
还要确保Socket本地路径提前创建好
mkdir -p /var/lib/hadoop-hdfs
注意:这里创建的是文件夹hadoop-hdfs,而上述配置中的dn_socket是datanode自己创建的,不是文件夹
确认配置生效:
背景:
命令行:
hdfs balancer []
-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(100M)
默认参数运行:hdfs balancer
指定阈值运行:hdfs balancer -threshold 5 Balancer将以阈值5%运行(默认值10%)。
这意味着程序将确保每个DataNode上的磁盘使用量与群集中的总体使用量相差不超过5%。例如,如果集群中所有DataNode的总体使用率是集群磁盘总存储容量的40%,则程序将确保每个DataNode的磁盘使用率在该DataNode磁盘存储容量的35%至45%之间。
背景:
概述:HDFS disk balancer是Hadoop 3中引入的命令行工具,用于平衡DataNode中的数据在磁盘之间分布不均匀问题。 这里要特别注意,HDFS diskbalancer与HDFS Balancer是不同的:
功能1-数据传播报告
计算方式:
volumeData Density的正值表示磁盘未充分利用,而负值表示磁盘相对于当前理想存储目标的利用率过高。
假设有一台具有四个卷/磁盘的计算机-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%理想存储容量。
Volume Data Density = Ideal Storage – dfs Used Ratio
比如Disk1的卷数据密度 = 0.70 - 0.50 = 0.20。其他以此类推。
Node Data Density(节点数据密度)= 该节点上所有volume data density卷(磁盘)数据密度绝对值的总和。
上述例子中的节点数据密度=|0.20|+|0.45|+|-0.15|+|-0.24|=1.04
较低的node Data Density值表示该机器节点具有较好的扩展性,而较高的值表示节点具有更倾斜的数据分布。
一旦有了volume Data Density和nodeData Density,就可以找到集群中数据分布倾斜的节点和机器上数据分步倾斜的磁盘。
功能2-磁盘平衡
当指定某个DataNode节点进行disk数据平衡,就可以先计算或读取当前的volume Data Density(磁卷数据密度)。
有了这些信息,我们可以轻松地确定哪些卷已超量配置,哪些卷已不足。
为了将数据从一个卷移动到DataNode中的另一个卷,Hadoop开发实现了基于RPC协议的Disk Balancer。
HDFS Disk Balancer开启:
HDFS Disk Balancer相关命令:
hdfs diskbalancer -plan
-out #控制计划文件的输出位置
-bandwidth #设置用于运行Disk Balancer的最大带宽.默认带宽10 MB/s.
-thresholdPercentage #定义磁盘开始参与数据重新分配或平衡操作的值.默认的thresholdPercentage值为10%,
#这意味着仅当磁盘包含的数据比理想存储值多10%或更少时,磁盘才用于平衡操作.
-maxerror #它允许用户在中止移动步骤之前为两个磁盘之间的移动操作指定要忽略的错误数.
-v #详细模式,指定此选项将强制plan命令在stdout上显示计划的摘要.
-fs #此选项指定要使用的NameNode.如果未指定,则Disk Balancer将使用配置中的默认NameNode
命令:hdfs diskbalancer -execute
execute命令针对为其生成计划的DataNode执行计划。
命令:hdfs diskbalancer -query
query命令从运行计划的DataNode获取HDFS磁盘平衡器的当前状态。
命令:hdfs diskbalancer -cancel
hdfs diskbalancer -cancel planID node
cancel命令取消运行计划。
命令:hdfs diskbalancer -fs hdfs://nn_host:8020 -report
背景:3副本策略弊端
概述:
为了支持纠删码,HDFS体系结构进行了一些更改调整。
条带化的HDFS文件在逻辑上由block group(块组)组成,每个块组包含一定数量的内部块。这允许在块组级别而不是块级别进行文件管理。
客户端的读写路径得到了增强,可以并行处理块组中的多个内部块。
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文件,用户可以参考该文件。
英特尔ISA-L代表英特尔智能存储加速库。 ISA-L是针对存储应用程序而优化的低级功能的开源集合。它包括针对Intel AVX和AVX2指令集优化的快速块Reed-Solomon类型擦除代码。 HDFS纠删码可以利用ISA-L加速编码和解码计算。
编码和解码工作会消耗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 ]命令启用策略集。
默认RS编解码器的HDFS本机实现利用Intel ISA-L库来改善编码和解码计算。要启用和使用Intel ISA-L,需要执行三个步骤。
hdfs ec
[-setPolicy -path [-policy ] [-replicate]]
#在指定路径的目录上设置擦除编码策略。
#path: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集群容量已不能满足存储数据的需求,需要在原有集群基础上动态添加新的DataNode节点。俗称动态扩容、节点服役。
step1:新机器基础环境准备:
主机名、IP
Hosts映射
防火墙、时间同步
SSH免密登录
JDK环境
Step2:Hadoop配置
Step3:手动启动DataNode进程
Step4:Web页面查看情况
Step5:DataNode负载均衡服务
节点下线:服务器需要进行退役更换,需要在当下的集群中停止某些机器上datanode的服务.俗称动态缩容、节点退役。
Step1:添加退役节点
dfs.hosts.exclude
/export/server/hadoop-3.1.4/etc/hadoop/excludes
Step2:刷新集群
Step3:手动关闭DataNode进程
hdfs --daemon stop datanode
Step4:DataNode负载均衡服务
如果需要可以对已有的HDFS集群进行负载均衡服务。
hdfs balancer -threshold 5
白名单
黑名单
单点故障:(英语:single point of failure,缩写SPOF)是指系统中某一点一旦失效,就会让整个系统无法运作,换句话说,单点故障即会整体故障。
如何解决单点故障:
主备集群角色:
高可用:
集群可用性评判标准(x个9):
在系统的高可用性里有个衡量其可靠性的标准——X个9,这个X是代表数字3-5。
X个9表示在系统1年时间的使用过程中,系统可以正常使用时间与总时间(1年)之比。
可以看出,9越多,系统的可靠性越强,能够容忍的业务中断时间越少,但是要付出的成本更高。
HA系统设计核心问题:
脑裂(split-brain)是指“大脑分裂”,本是医学名词。
在HA集群中,脑裂指的是当联系主备节点的"心跳线"断开时(即两个节点断开联系时),本来为一个整体、动作协调的HA系统,就分裂成为两个独立的节点。由于相互失去了联系,主备节点之间像"裂脑人"一样,使得整个集群处于混乱状态。
脑裂的严重后果:
1)集群无主:都认为对方是状态好的,自己是备份角色,后果是无服务;
2)集群多主:都认为对方是故障的,自己是主角色。相互争抢共享资源,结果会导致系统混乱,数据损坏。此外对于客户端访问也是一头雾水,找谁呢?
避免脑裂问题的核心是:保持任意时刻系统有且只有一个主角色提供服务。
主备切换保证服务持续可用性的前提是主备节点之间的状态、数据是一致的,或者说准一致的。如果说备用的节点和主节点之间的数据差距过大,即使完成了主备切换的动作,那也是没有意义的。
数据同步常见做法是:通过日志重演操作记录。主角色正常提供服务,发生的事务性操作通过日志记录,备用角色读取日志重演操作。
概述:
解决:
Quorum Journal Manager介绍:
主备切换、脑裂问题解决:
ZK FailoverController(ZKFC)是一个ZooKeeper客户端。主要职责:
ZKFC通过命令监视的NameNode节点及机器的健康状态。
如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,它将自己尝试获取该锁。如果成功,则表明它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于Active状态。如果已经有其他节点持有锁,zkfc选举失败,则会对该节点注册监听,等待下次继续选举。
sshfence是指通过ssh登陆目标节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid,该方法比jps命令更准确);
shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。
主备数据状态同步问题解决:
5.4 HA集群搭建
Step1:集群基础环境准备
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之间的互相免密登录
Step2:HA集群规划
机器 | 运行角色 |
---|---|
node1.itcast.cn | namenode zkfc datanode zookeeper journal node |
node2.itcast.cn | namenode zkfc datanode zookeeper journal node |
node3.itcast.cn | datanode zookeeper journal node |
Step3:上传安装包、配置环境变量(node1)
Step4:修改Hadoop配置文件
Step5:集群同步安装包
Step6:HA集群初始化
Step7:HA集群启动
当前的HDFS架构有两个主要的层:
由文件,块和目录组成的统一抽象的目录树结构。由namenode根据用户操作实时维护树结构。
局限性:
概述:
好处
命名空间可伸缩性
使用Federation,可以水平扩展名称空间。这对大型群集或包含太多小文件的群集有利,因为向群集添加了更多的NameNode。
性能
由于文件系统操作不受单个NameNode吞吐量的限制,因此可以提高文件系统的性能。
隔离
由于有多个名称空间,它可以为使用群集的占用者组织提供隔离。
概述:
假设有两个名称节点NN1和NN2,其中NN1和NN2分别处于Active和StandBy状态。
#创建一个新的fsimage文件用于回滚
hdfs dfsadmin -rollingUpgrade prepare
#不断运行下面命令检查回滚fsimage是否创建完毕。
#如果显示Proceeding with Rolling Upgrade表示已经完成。
hdfs dfsadmin -rollingUpgrade query
#关闭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
#选择整体中的一小部分DataNode节点进行升级(比如按照DataNode所在的不同机架来筛选)。
#关闭升级所选的DN 其中IPC_PORT由参数dfs.datanode.ipc.address指定,默认9867。
hdfs dfsadmin -shutdownDatanode upgrade
#检查下线DataNode是否已经停止服务.如果还能得到节点信息,意味着此节点还未真正被关闭。
hdfs dfsadmin -getDatanodeInfo
#启动DN节点。
hdfs --daemon start datanode
#对选中的所有DN节点执行以上步骤。
#重复上述步骤,直到升级群集中的所有DN节点。
#完成滚动升级
hdfs dfsadmin -rollingUpgrade finalize
#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、做一次failover切换,使得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由参数dfs.datanode.ipc.address指定,默认9867。
hdfs dfsadmin -shutdownDatanode upgrade
#3.2、检查下线DataNode是否已经停止服务.如果还能得到节点信息,意味着此节点还未真正被关闭。
hdfs dfsadmin -getDatanodeInfo
#3.3、启动DN节点。
hdfs --daemon start datanode
#4、升级过程执行完毕,在每个namespace下执行finalize确认命令.
hdfs dfsadmin -rollingUpgrade finalize
7.1.3 停机滚动升级–非HA集群
#Step1:滚动升级准备
#Step2:升级NN和SNN
#1、关闭NN
hdfs --daemon stop namenode
#2、升级启动NN
hdfs --daemon start namenode -rollingUpgrade started
#3、停止SNN
hdfs --daemon stop secondarynamenode
#4、升级启动SNN
hdfs --daemon start secondarynamenode -rollingUpgrade started
#Step3:升级DN
#Step4:完成滚动升级
hdfs dfsadmin -rollingUpgrade finalize
降级和回滚区别:
共同点:
都会将版本退回到升级前的版本;
在升级的finalize动作执行之后,将不允许再执行降级和回滚。
不同点:
降级能支持rollling的方式,可以滚动降级,而回滚需要停止服务一段时间.
降级过程只会将软件版本还原成升级前的,会保留用户现有的数据状态;
而回滚则会将用户数据还原成升级前的状态模式,现有的数据状态不保存。
友情提示:升级慎重,降级、回滚更要慎重。
HA集群降级(downgrade)操作:
#1.选中部分集合DataNode节点(可以按照机架进行区分)
#执行降级操作,其中IPC_PORT由参数dfs.datanode.ipc.address指定,默认9867。
hdfs dfsadmin -shutdownDatanode upgrade
#执行命令检查节点是否完全停止
hdfs dfsadmin -getDatanodeInfo
#在选中集合内的其他DataNode节点上重复执行上述操作.
#2.在集群中所有的DataNode节点上重复执行1.的操作.
#停止并降级Standby NameNode.
#正常启动Standby NameNode.
#触发failover切换,使得主备角色对调
#停止并降级之前属于Active(现属于Standby的NameNode)
#正常启动作为Standby节点.
#完成降级操作
hdfs dfsadmin -rollingUpgrade finalize
HA集群降级(downgrade)注意事项:
在操作NameNode时,都是先从Standby节点开始操作,等Standby节点升/降结束,做一次切换,使另外一个节点得以进行升/降操作.在全程中,始终保持一个Active节点对外提供服务。
新版本一般在协议、API是兼容老版本的,如果先降级NN,那么则会造成DN是新版,NN是旧版。
新版DN中的许多协议将会在旧版NN中可能不兼容。
所以这里必须要先降级DN,然后再把服务端NN进行降级.看似简单的一次顺序颠倒,背后其实是有更深层的原因的.
集群回滚(rollback)操作:
注意事项:
Rollback不支持滚动操作的方式,在操作期间,它需要集群对外停止提供服务.
Rollback操作不仅会将软件版本退回到升级前的版本,还会将用户数据退回到升级前的状态.
回滚步骤:
#1.停止所有的NameNode和DataNode节点.
#2.在所有的节点机器上恢复升级前的软件版本.
#3.在NN1节点上执行-rollingUpgrade rollback命令来启动NN1,将NN1作为Active节点.
#4.在NN2上执行-bootstrapStandby命令并正常启动NN2,将NN2作为Standby节点.
#5.以-rollback参数启动所有的DataNode.
-------------------------根据黑马程序员学习总结