DataNode启动优化改进:磁盘检测并行化

本文探讨了HDFS DataNode启动时磁盘检测过程的优化,通过并行化处理提高启动效率。当DataNode配置的磁盘目录数量较多或存在性能问题时,串行检测可能导致启动缓慢。社区的改进方案包括使用ListenableFuture实现异步检测,保存检测结果以避免重复检测,并设置最大超时时间以防止长时间阻塞。改造涉及AsyncChecker、ThrottledAsyncChecker和StorageLocationChecker等类的设计与实现。
摘要由CSDN通过智能技术生成

前言


在本篇文章中,本人打算聊一个大家平常都会遇见到的场景:HDFS中的DataNode启动的问题。DataNode启动不是一件非常迅速的事情吗?这其中能有大问题?看到这里,如果你也是这么想的话,那说明一点:你所运维的集群碰到的异常场景还不太多。本文所要讲述的问题并不是DataNode无法启动的问题,而是它启动有时会过慢的问题。DataNode进程启动过慢造成的直接影响是其上数据的服务延时。集群规模在一个很大规模量级的情况下,如果出现了大量DataNode慢启动的现象,这将会对集群本身对外提供服务造成不小的影响。本文所要讲述的内容是对于目前DataNode的启动优化,以此加速其启动时间,优化的主要点在于将DataNode启动时的磁盘检测行为。

现有DataNode启动时的磁盘检测


在讲述本节主要内容之前,我们要大概了解DataNode启动时的相关操作。在HDFS中,一个DataNode从启动开始到最终提供数据服务,中间会做很多的操作步骤。这里主要概括为以下几点:

  • 1.读取解析数据目录即datadir所配置的目录。
  • 2.检查这些目录对应磁盘是否是坏的磁盘(此步骤现有的逻辑为串行执行)。
  • 3.DataNode发送心跳信息,向NameNode进行注册。
  • 4.扫描各个数据目录下的数据块,并将这些数据块初次汇报给NameNode。

主要为以上的逻辑,而本节我们要优化的点在于其中第2点,也就是磁盘检测相关的操作。在DataNode的启动过程中,为什么要对磁盘做一次健康检查呢?因为它是保证节点本身数据可用性的一个重要指标,如果DataNode在磁盘检测中发现坏盘的个数超出了可容忍阈值(可配)的情况下,会直接让DataNode启动失败,并抛出异常。由此可见,HDFS对其磁盘可用性的一个重视。在正常情况下,这部分的检测操作会非常顺利,但是在某些情况下,可能会出现检测十分耗时的情况,比如下面两类情况:

第一个,如果节点内配置的磁盘目录非常多,比如一个机器,上面有10来块,20来块盘,然后我配置了对应盘数的目录。由于目前磁盘健康检测的逻辑是串行执行,所以总执行时间会线性增长。当然,如果机器磁盘本身都比较健康,它所花的总时间也不会多多少时间。可怕的是第二种情况。
第二个,个别DataNode磁盘数据目录检测出现非常慢的现象,可能是这个目录对应磁盘本身的性能问题(DataNode磁盘健康检测时会尝试在目录下创建文件、目录动作以此确定磁盘是否可用)。这个时候后面待检测的目录就会被迫等待当前磁盘检测动作的完成,最后就会导致总检测时间过长。

所以为了避免出现第二点提到的个别磁盘检测极慢影响到整体的问题,我们可以对其进行改造,改造的核心点就在于将原有磁盘检测的执行逻辑由串行化改为并行化。这个改进想法是目前社区在做的,JIRA编号HDFS-11086DataNode disk check improvements)。本文的主要思想和代码也是借鉴于这个JIRA上的。

现有DataNode内部磁盘检测代码


接下来我们来看一下目前DataNode磁盘检测代码,既然我们已经知道它是串行执行的逻辑了,那么DataNode内部到底是怎么执行的呢?

首先它是在初始化DataNode节点的操作中,代码如下:

  public static DataNode instantiateDataNode(String args [], Configuration conf,
      SecureResources resources) throws IOException {
    if (conf == null)
      conf = new HdfsConfiguration();

    if (args != null) {
      // parse generic hadoop options
      GenericOptionsParser hParser = new GenericOptionsParser(conf, args);
      args = hParser.getRemainingArgs();
    }

    // 解析DataNode启动参数
    if (!parseArguments(args, conf)) {
      printUsage(System.err);
      return null;
    }
    Collection<StorageLocation> dataLocations = getStorageLocations(conf);
    UserGroupInformation.setConfiguration(conf);
    SecurityUtil.login(conf, DFS_DATANODE_KEYTAB_FILE_KEY,
        DFS_DATANODE_KERBEROS_PRINCIPAL_KEY, getHostName(conf));
    // 进入DataNode构建实例方法
    return makeInstance(dataLocations, conf, resources);
  }

r然后我们进入makeInstance方法,

  static DataNode makeInstance(Collection<StorageLocation> dataDirs,
      Configuration conf, SecureResources resources) throws IOException {
    LocalFileSystem localFS = FileSystem.getLocal(conf);
    FsPermission permission = new FsPermission(
        conf.get(DFS_DATANODE_DATA_DIR_PERMISSION_KEY,
                 DFS_DATANODE_DATA_DIR_PERMISSION_DEFAULT));
    // 初始化磁
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值