• hadoop手工移块


    1.关于磁盘使用策略,介绍参考http://www.it165.net/admin/html/201410/3860.html

    在hadoop2.0中,datanode数据副本存放磁盘选择策略有两种方式:

    第一种是沿用hadoop1.0的磁盘目录轮询方式,实现类:RoundRobinVolumeChoosingPolicy.java

    第二种是选择可用空间足够多的磁盘方式存储,实现类:AvailableSpaceVolumeChoosingPolicy.java

    选择策略对应的配置项是:

      <property>
        <name>dfs.datanode.fsdataset.volume.choosing.policy</name>
        <value>org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy</value>
      </property>

    如果不配置,默认使用第一种方式,既轮询选择磁盘来存储数据副本,但是轮询的方式虽然能够保证所有磁盘都能够被使用,但是经常会出现各个磁盘直接数据存储不均衡问题,有的磁盘存储得很满了,而有的磁盘可能还有很多存储空间没有得到利用,所有在hadoop2.0集群中,最好将磁盘选择策略配置成第二种,根据磁盘空间剩余量来选择磁盘存储数据副本,这样一样能保证所有磁盘都能得到利用,还能保证所有磁盘都被利用均衡。

    在采用第二种方式时还有另外两个参数会用到:

    dfs.datanode.available-space-volume-choosing-policy.balanced-space-threshold

    默认值是10737418240,既10G,一般使用默认值就行,以下是该选项的官方解释:

    This setting controls how much DN volumes are allowed to differ in terms of bytes of free disk space before they are considered imbalanced. If the free space of all the volumes are within this range of each other, the volumes will be considered balanced and block assignments will be done on a pure round robin basis.

    意思是首先计算出两个值,一个是所有磁盘中最大可用空间,另外一个值是所有磁盘中最小可用空间,如果这两个值相差小于该配置项指定的阀值时,则就用轮询方式的磁盘选择策略选择磁盘存储数据副本。源代码如下:

    public boolean areAllVolumesWithinFreeSpaceThreshold() {
          long leastAvailable = Long.MAX_VALUE;
          long mostAvailable = 0;
          for (AvailableSpaceVolumePair volume : volumes) {
            leastAvailable = Math.min(leastAvailable, volume.getAvailable());
            mostAvailable = Math.max(mostAvailable, volume.getAvailable());
          }
          return (mostAvailable - leastAvailable) < balancedSpaceThreshold;
        }

    dfs.datanode.available-space-volume-choosing-policy.balanced-space-preference-fraction

    默认值是0.75f,一般使用默认值就行,以下是该选项的官方解释:
    This setting controls what percentage of new block allocations will be sent to volumes with more available disk space than others. This setting should be in the range 0.0 - 1.0, though in practice 0.5 - 1.0, since there should be no reason to prefer that volumes with

    意思是有多少比例的数据副本应该存储到剩余空间足够多的磁盘上。该配置项取值范围是0.0-1.0,一般取0.5-1.0,如果配置太小,会导致剩余空间足够的磁盘实际上没分配足够的数据副本,而剩余空间不足的磁盘取需要存储更多的数据副本,导致磁盘数据存储不均衡。

    该配置需要重启生效,因为磁盘选择策略是datanode启动后在加载本地磁盘信息后加载的。

    2.如果没有配置该策略,很容易造成节点内部磁盘使用不均,如果有磁盘的使用率超过了90%,则需要手工干预——手工移块

       手工移块需要注意的问题:需要停datanode,移块完成后重启

       原因:不停datanode,会导致datanode内存中block存储路径和实际存储路径不符,当dfs.datanode.scan连续两次检查到为坏块后,就会向namenode报告,namenode收到报告后会安排删除坏块

        注意:①directoryscanner无法检测出磁盘间移动的块的健康性,

                 ②data.block.scanner的作用是周期性的对block进行校验,以检测datanode所管理的所有副本的一致性。因此,对datanode上每一个block,datablockscanner每隔scanperiod会利用block对应的校验和文件来检测该block一次,来查看该block都否已损坏。因为datanode节点上的每个block扫描一遍要消耗不少系统资源,所以scan period默认值一般比较大,是504小时(21天),这也可能带来另一个问题——一个扫描周期内可能会出现datanode重启,为了避免datanode在启动后对还没有过期的block又扫描一遍,datablockscanner在其内部使用了日志记录器来持久化保存每一个block上一次扫描的时间,如此,datanode在启动后通过日志文件来恢复之前所有block的有效时间。另外,datanode为了节约系统资源,它对block的验证不仅仅只依赖于datablockscanner后台现成(verification_scan方式),还会在向某一个客户端传送block的时候来进行该block的扫描(remote_read方式),这是因为datanode向客户端传送一个block的时候必须要检验该数据块。这也就是datanode在线移块后,datablocksanner扫描前,虽然hdfs fsck还是healthy,hfs dfs get会报错的原因。但是,这是的日志记录器并不会马上把该数据块的扫描信息写到日志,因为频繁的磁盘io会导致性能下降,那么什么时候对该block的最新扫描时间写日志又一个判断条件:①如果是verification_scan方式的block验证,必须记日志;②如果是remote_read方式的block验证,那么该block上一次的记录日志到现在的时间超过24小时或者超过scanperiod/3的话,记日志。

                  ③在我自己的测试中,移块后接着重启是也是不会出现坏块,但是在生产中执行时还是出现了坏块,后来反思,自己的测试也没有完全考虑到生产的情况,在生产中移块时间会比测试长很多(因为需要移动的块多呀),在此期间应用一直在执行,不停的有新块在增加,当然,我不认为这是造成伪坏块出现的原因,影响了测试结果的原因是,测试块的设定就不对,我是新上传了一个文件,然后手工移动该文件的某个块,这有个问题,就是它的第一个scan period还么有到,紧接着重启是不会造成坏块(标黄的带确认。。。。这东西真不是研究一次两次就能搞明白的,还是自己太笨了。。。哎。。。。),比如,测试中的块可能时间间隔大,scan period不会紧挨着,即使时候重启datanode,被移动的块可能也不会在生产中操作时还是要采用慎重最保险的方法。原因应该是:虽然scan period有一个周期,但是每个块的检测时间点是不一样的,在任何时间不停datanode都可能处于某一被移动block的检查点,所以不停datanode移块很容易造成该检查点block的伪坏块(块只是被移动了位置,并没有丢失,但是hdfs fsck就会显示corrupt)。

         手工移块过程:

         ①停datanode;

         ②mv(使用hadoop用户执行,执行后要记得确认移动到新目录的文件权限属主是否正确,我就是用root执行了脚本,结果datanode自己shutdown了,报权限问题)

         ③启datanode;

  • 相关阅读:
    阶段3 1.Mybatis_10.JNDI扩展知识_2 补充-JNDI搭建maven的war工程
    阶段3 1.Mybatis_10.JNDI扩展知识_1 补充-JNDI概述和原理
    阶段3 1.Mybatis_09.Mybatis的多表操作_9 mybatis多对多操作-查询用户获取用户所包含的角色信息
    阶段3 1.Mybatis_09.Mybatis的多表操作_8 mybatis多对多操作-查询角色获取角色下所属用户信息
    阶段3 1.Mybatis_09.Mybatis的多表操作_7 mybatis多对多准备角色表的实体类和映射配置
    阶段3 1.Mybatis_09.Mybatis的多表操作_6 分析mybatis多对多的步骤并搭建环境
    阶段3 1.Mybatis_09.Mybatis的多表操作_5 完成user的一对多查询操作
    阶段3 1.Mybatis_09.Mybatis的多表操作_4 完成account一对一操作-建立实体类关系的方式
    inline函数不能在for循环中使用的原因
    Linux 内核死锁
  • 原文地址:https://www.cnblogs.com/roger888/p/5613146.html
Copyright © 2020-2023  润新知