设为首页 收藏本站
查看: 1025|回复: 0

[经验分享] 关于hadoop中datanode节点不同的dfs.data.dir之间数据均衡问题

[复制链接]
YunVN网友  发表于 2018-10-31 13:07:00 |阅读模式
  问题:集群中的存储数据增大,导致datanode的空间都快占满了(以前的dfs.data.dir=/data/hdfs/dfs/data),机器的硬盘监控程序不停的报警 。
  给每台机器加了一倍的存储硬盘(新的dfs.data.dir=/data/hdfs/dfs/data,/data/hdfs/dfs/data2    新的硬盘挂载在/data/hdfs/dfs/data2),但是现在的问题来了,以前装数据的那块盘还是满的,仍然在报警,怎么把数据均衡到这两块盘上面 ??
  解决:移动其中一个文件夹的数据(其实也就是block)到另外一个文件加 。
  原理:hdfs中文件的inode文件树信息以及每个文件对应的block信息存储在NN中的,每个block存储在那几台DN机器上是在集群启动时候,由每台datanode根据自身所拥有的block上报上去的。 datanode在启动时候,也是扫描自身dfs.data.dir的各个文件夹下的current(前提是这个目录的VERSION等必要信息文件时存在的,这个目录是合法的)目录,然后将下面存在block信息(有哪些block,存在那个文件夹下)上报到NN (详细参见DataNode的FSDataset代码)。
  操作:
  1、停止集群 。
  2、修改dfs.data.dir的配置 。
  3、启动集群(先只启动hdfs),该步的目的是:让DataNode去格式化/data/hdfs/dfs/data2,填充其中的一些系统信息文件(例如:current  ,current/VERSION,detach ,storage等)。
  5、使用http://namenodeAddress:50070/fsck来检查文件系统,并记录下结果,以便与修改后进行fsck比较,看文件系统是否健全 。
  4、停止集群 。
  5、进入/data/hdfs/dfs/data/current 目录,将其中一些较大的子文件夹(如果是系统生成的名字一般是subdir**)mv到/data/hdfs/dfs/data2/current 下 。
  6、启动集群 (先是hdfs,好做检查) 。
  7、再次执行http://namenodeAddress:50070/fsck命令,将结果与前一次比较,没出问题的话,应该是一样的 。
  PS:在dev机器上做了相应的实验,做之前将dev的数据文件备份,现在启动dev的集群,已经跑了一段时间,并没有出现问题 。
  源代码部分:
  在DataNode中,每个dfs.data.dir的文件夹对应的是一个FSDir类,而其文件下的每一个子文件夹对应一个FSDir ,每次DataNode启动时,会对每一个dfs.data.dir的文件启动一个FSDir对象,让后其在构造函数中会统计该FSDir下存储哪些block ,也既是每个block存在那个文件夹只有在DataNode启动时扫描自己的dfs.data.dir是才知道,这也是本次修改的原理 。
public FSDir(File dir)       throws IOException {      this.dir = dir;      this.children = null;      //文件夹不存在则创建文件夹      //不会覆盖或删除已经存在的文件夹,为手工移动block提供了便利性if (!dir.exists()) {                                                                                                                                                                                                        if (!dir.mkdirs()) {          thrownew IOException("Mkdirs failed to create " +                                 dir.toString());        }      } else {        File[] files = dir.listFiles();        int numChildren = 0;        //自检查文件夹个数(子FSDir的个数)和文件(block个数)for (int>  其往FSDir中添加block的代码:
/**     * //所作的事情:将在tmp中的block文件以及其meta文件mv(重命名)到current中     * 第一次调用的形式是:先调用 File file = addBlock(b, src, false, false) ,再调用addBlock(b, src, true, true)           * boolean createOk :  是否需要在子FSDir中创建子子FSDir,先不创建的添加,若是不行(子目录存放的block也满了),再允许子目录创建子子目录 。     * boolean resetIdx : 当存储需要在子目录中时候,每次存储完都有一个lastChildIdx表明上次存在哪个文件夹下:设置为true表示下次会在随机选一个,false表示下次还接着上次的来存     */private File addBlock(Block b, File src, boolean createOk,                           boolean resetIdx) throws IOException {      //本层目录未满,这直接将block添加在本目录if (numBlocks < maxBlocksPerDir) {        File dest = new File(dir, b.getBlockName());        File metaData= getMetaFile( src, b );        File newmeta = getMetaFile(dest, b);        if ( ! metaData.renameTo( newmeta ) ||            ! src.renameTo( dest ) ) {          thrownew IOException( "could not move files for " + b +  
" from tmp to " +                                  dest.getAbsolutePath() );        }        if (DataNode.LOG.isDebugEnabled()) {          DataNode.LOG.debug(&quot;addBlock: Moved &quot; + metaData + &quot; to &quot; + newmeta);          DataNode.LOG.debug("addBlock: Moved " + src + " to " + dest);        }        numBlocks += 1;        return dest;      }      //需要存到子目录下 ,随即从新选择一个开始子目录      //通过这个resetIdx来平均各个子FSDir的存储不均衡 。if (lastChildIdx < 0 && resetIdx) {        //reset so that all children will be checked

  
lastChildIdx = random.nextInt(children.length);                    }      //从上面随即的lastChildIdx开始找一个能添加if (lastChildIdx >= 0 && children != null) {        //Check if any child-tree has room for a block.for (int i=0; i < children.length; i++) {          int>
  
File file = children[idx].addBlock(b, src, false, resetIdx);          if (file != null) {            lastChildIdx =>  //若是没有手工成分,DataNode会一次性建立maxBlocksPerDir个子文件夹 。
  //maxBlocksPerDir由dfs.datanode.numblocks确定,默认是64 ,含义是每个FSDir中最多存储多少个block ,最多存储多少个子FSDir
if (children == null || children.length == 0) { children = new FSDir[maxBlocksPerDir]; for (int>maxBlocksPerDir由dfs.datanode.numblocks确定,默认是64 ,含义是每个FSDir中最多存储多少个block ,最多存储多少个子FSDir  贴出以上代码主要是刚开始怕DataNode有一套自己的机制,会把你添加进去的文件(夹)清除掉,或者是把不符合规则的子文件夹(一般的是当建立子文件夹是会一次性建立subdir0--subdir63 这64个文件夹,代码见第二部分代码)清除掉 ,但是后来看过代码后发现也没这些逻辑 。
  转载:http://music.573114.com/Blog/Html/394B/200880.html
  附件为hadoop权威指南



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-629006-1-1.html 上篇帖子: Hadoop全分布式集群配置文档 下篇帖子: Hadoop集群Hadoop安装配置详细说明+SSH+KEY登陆
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表