hdfs balance命令(hdfs总结),本文通过数据整理汇集了hdfs balance命令(hdfs总结)相关信息,下面一起看看。

平衡过程是将多余的块从存储利用率超过集群平均利用率的datanode移动到存储利用率低于集群平均利用率的datanode,最终达到平衡标准。过度利用-利用不足过度利用低于平均水平高于平均水平利用不足

1.过度使用:datanode 2。高于平均值,利用率超过阈值:datanode 3。低于平均值,利用率超过平均值但低于阈值:datanode 4。利用率低于平均值但高于阈值的未充分利用:利用率低于阈值的datanode。

平衡标准:每个参与平衡的datanode的利用率与所有参与平衡的全局利用率之差接近给定的阈值。

平衡的过程是在几次迭代中完成的。在每次迭代开始时,平衡器按照上述规则对所有参与平衡的datanode进行分类和配对,形成一组源和目标,一个源和目标意味着源datanode上的某个块迁移到目标datanode上。

每个源、目标对应一个线程。该线程的主要功能如下:1 .从namenode中随机抽取一定数量的块(一次最多2G,共20G),过滤后保存在src_block列表中。触发拉取的条件之一:src_block列表中未迁移的块数小于5(固定值,无法匹配)。2.将src_block列表中的块提交到线程池(线程池大小:dfs.balancer.moverThreads,默认为1000)进行迁移。

迁移过程由多个线程(线程数:dfs.balancer.moverThreads)完成,每个线程一次迁移一个块。迁移过程:步骤1:从src_block列表中选择一个块。第2步:检查在第2步中块的所有副本所在的datanode中,是否存在与目标相同的机架中的datanode。如果有,选择它作为代理,否则,随机选择一个datanode作为代理。步骤3:平衡器通知目标将块的副本从代理复制到本地机器。步骤4:如果复制成功,目标请求namenode从源中删除该块,并反馈给平衡器。1在步骤2中选择block时会检查目标,在步骤2中选择proxy时会检查备选datanode,包括:1、当前执行复制的线程数是否超过最大线程数(DFS . datanode . balance . max . concurrent . moves);2、是否处于禁用期。每次复制失败都会导致datanode在10秒钟内被禁止充当代理和目标。

核心方法和流程:

Balancer.runOneIteration() //启动一轮dispatcher . init();//选择参与平衡的datanode balancer . init();//群组平衡器。ChooseStorageGroups()//构建源,目标先匹配同一个机架,再随机匹配dispatcher。DispatchandCheckContinue()//以源为单位分发块移动任务dispatcher . dispatchblock moves();//为每个源启动一个线程source . dispatch blocks();source . get block list();//拉blocksource。从NameNode//中选择总大小为2G的NextMove(),一次选择一个块,放入线程池中移动pendingmove。ChooseBlockandProxy();//选择一个块和代理挂起移动。markmovedifgoodblock();pending move . isgoodblockscandidate();//是否是合适的块pending move . chooseproxysource()//为所选块选择合适的代理datanode分类:

专用长初始化(ListDatanodeStorageReport报告){//计算(数据节点存储报告r:报告){策略。累积空间的平均利用率;}政策。initavgutilization();//创建网络拓扑并对利用率集合进行分类://过度利用、高于平均水平、低于平均水平和利用不足long overLoadedBytes=0L,under loaded bytes=0L for(DatanodeStorageReport r:reports){ final DDatanode dn=dispatcher。新建datanode(r . getdatanodeinfo());for(存储类型t:存储类型。getmovabletypes()){//所有参与平衡的节点[住且包含在包括中的节点]的使用率(已使用的存储/总的存储)最终双倍利用率=policy.getUtilization(r,t);if(utilization==null){//datanode没有这样的存储类型继续;}最终长容量=getCapacity(r,t);最终双倍利用率差异=利用率-策略。getavgoutilization(t);//thresholdDiff越小说明该datanode越理想最终双阈值diff=数学。ABS(利用率差异)-阈值;最终long maxsize 2 move=computemaxsize 2 move(capacity,getRemaining(r,t),utilizationDiff,threshold);最终存储组g;if(利用率差异0){最终来源s=dn。添加源(t,maxSize2Move,dispatcher);if (thresholdDiff=0) { //在阈值内高于avgutilized。添加;} else { overLoadedBytes=百分比2字节(thresholdDiff,capacity);过度使用。添加;} g=s;} else { g=dn.addTarget(t,maxsize 2 move);if (thresholdDiff=0) { //在阈值之内低于wavgutilized。添加(g);} else {欠载字节=2字节百分比(thresholdDiff,capacity);未充分利用. } }调度员。getstoragegroupmap().放(g)和:} } logUtilizationCollections();预测词典。checkstate(调度程序。getstoragegroupmap().size()==过度利用。大小()未被充分利用。大小()高于avgutilized。大小()低于wavgutilized。size(),'存储组数量不匹配');//返回为了使集群均衡而要移动的字节数返回Math.max(overLoadedBytes,欠载字节);} 选择代理:

private boolean chooseProxySource(){ final DatanodeInfo targetDN=target。getdatanodeinfo();//如果源和目标是相同的节点,则不需要代理if (source.getDatanodeInfo().equals(targetDN)addTo(source)){ return true;} //如果支持节点组,首先尝试在同一个节点组中添加节点如果(集群。isnodegrouaware()){ for(存储组位置:块。get locations()){ if(cluster。isosamenodegroup(loc。getdatanodeinfo()、targetDN)addTo(loc)){ return true;} } } //检查是否存在与目标在同一机架上的副本//优选选择副本所在机器跟目标在相同行李架的(同向下)向下的作为代理人,同时需要改(同向下)向下的当前处理余额[发送block]的线程数量是否超标for(存储组位置:块。get locations()){ if(cluster。isosamerack(loc。getdatanodeinfo()、targetDN)addTo(loc)){ return true;} } //找出一个不忙的副本//如果以上都没有选择出合适的代理人,那么就选一个不忙的(同向下)向下的作为的代理(存储组位置:块。get locations()){ if(addTo(loc)){ return true;} }返回false}块迁移:

第一步:平衡器插座连接目标,发起替换块请求,请求目标从代理人上复制一个街区副本到本地来替换掉来源上的副本。

第二步:目标向代理人发起复制块请求,从代理人上将街区副本复制到本地,复制完成后目标通过notifyNamenodeReceivedBlock方法生成一个ReceivedDeletedBlockInfo对象并缓存在队列,下一次发起心跳的时候会据此对象通知namenode将目标上新加的街区副本存入区块图,并将来源上对应的街区副本删除

私有void dispatch(){ if(log。isdebugenabled()){ log。调试(“启动移动”这个);} Socket sock=new Socket();data output stream out=nullDataInputStream in=null试试{//平衡器建立跟目标的连接袜子。连接(网络工具。createsocketaddr(目标。getdatanodeinfo().getXferAddr()),HdfsServerConstants .READ _ time out);袜子。setkeepalive(true);输出流un buout=sock。获取输出流();InputStream un buin=sock。getinputstream();扩展块EB=新的扩展块(NNC。获取block poolid()、block。get block());最终密钥管理器km=NNC。getkey manager();TokenBlockTokenIdentifier访问令牌=km。getaccessstoken(EB);iostream对SAS lstreams=sasl客户端。socket send(sock,unbufOut,unbufIn,km,accessToken,target。getdatanodeinfo());unbufOut=sasl streams . out un bufin=sasl streams。在;out=新数据输出流(new BufferedOutputStream(unbufOut,HdfsConstants .IO _ FILE _ BUFFER _ SIZE));in=新数据输入流(new BufferedInputStream(un bufin,HdfsConstants .IO _ FILE _ BUFFER _ SIZE));//向目标发请求,命令其复制街区副本sendRequest(out,eb,访问令牌);接收响应(在);nnc.getBytesMoved().addAndGet(块。getnumbytes());LOG.info('成功移动这个);} catch (IOException e) { LOG.warn('未能移动this ':' e . getmessage());target.getDDatanode().setHasFailure();//代理或目标可能会有一些问题,请在使用这些节点之前//进一步延迟,以避免当调度程序与数据节点中正在进行的工作//不同步时,出现潜在的"线程配额//超出"警告风暴。//迁移失败,可能是因为代理、目标当前过于繁忙(同时处理块替换的操作太多),所以延迟其参与平衡代理源。激活延迟(delayAfterErrors);target.getDDatanode().激活延迟(delayAfterErrors);}最后{ iou tils。关闭流(出);欠条。关闭流(入);欠条。关闭插座(袜子);//不管迁移成功还是失败,都将当前街区从队列中删除代理源。removependingblock(this);target.getDDatanode().removePendingBlock(this);同步(this){ reset();}同步(调度程序。这个){调度员。这个。notify all();} } }私有void发送请求(数据输出stream out,ExtendedBlock eb,TokenBlockTokenIdentifier访问令牌)抛出IOException {新发件人(出站).replaceBlock(eb,target.storageType,accessToken,source.getDatanodeInfo().getDatanodeUuid(),代理源。datanode);//第4个参数是来源的uuid(在名字上唯一标示一个datanode),用于通知namenode删来源上的副本}目标复制完成后的日志:

2019-07-03 10:15:41319信息组织。阿帕奇。Hadoop。HDFS。服务器。datanode。datanode:已移动BP-691805646-10。116 .100 .3-1498296722300:blk _ 2306375028 _ 1234536481 from/10。1116 .100 .149:36481常见异常:

目标异常:警告平衡器。调度程序:无法将大小为12178的blk_10818540065_9759022625从10.116.100.126:50010:磁盘移动到10.116.100.143:50010:磁盘,通过10.116.102.93:50010:出现错误,状态消息无法接收块10818540065,块移动失败代理异常:警告平衡器。调度程序:无法将大小为412的blk _ 13904085291 _ 12851796248从10.116.101.126:50010:磁盘移动到10.116.101.227:50010:磁盘并通过10.116.100.51:50010:获得错误,状态消息opReplaceBlock BP-691805646-10,从/10.116.100.51:50010复制块BP-691805646-10。116 .100 .3-1498296722300:blk _ 13904085291 _ 12851796248,块移动失败,超过了线程配额说明datanode上(目标、代理)上当前正在参与平衡进行块替换(目标)和块拷贝(代理)的线程数量超过阀值(DFS。datanode。平衡。最大值并发。移动),所以街区迁移失败。

如果大量出现此类异常,那么平衡的速度会很慢:

直接原因:阻止迁移失败;

间接原因:目标和代理人会进入禁用期,导致可选代理人减少,进而src_block中的街区不能及时被消费,也不能拉取新的blcok

平衡慢的解决办法: 1、将datanode的迁移线程数最大并发移动数增大。增大之后超过了线程配额的问题会缓解,平衡速度会加快。修改此参数需重启数据节点.2、将平衡器的最大并发移动数增大平衡器上此值应该比datanode上的值稍微小一点,因为两个股进程存在状态不同步的可能。 3、将-阈值增大。增大之后可以优先迁移使用率最高的数据节点,待使用率将下来之后,再将阈值降低。 4、如果是多命名空间的情况,则可以将-政策由默认datanode改为泳池,在迁移时应根据命名空间对应区块池的使用率来评估datanode是否要平衡.

更多hdfs balance命令(hdfs总结)相关信息请关注本站,本文仅仅做为展示!