【Hadoop】NameNode结构与功能

NameNode结构与功能

NameNode部分,主要分为以下几个方面:

NameNode总体架构

NameNode作为hdfs的master节点,负责管理这个整个集群元数据和集群管理功能,NameNode代码在org.apache.hadoop.hdfs.server.namenode包下,由于NN是通过master/slave方式管理整个集群的,它的主要功能是:

NameNode总体架构

  1. 文件系统元数据操作
    通过FSDirectory管理整个文件系统元数据的目录树
  2. 数据块的管理
    保存NN中所有数据块的元数据,用于block管理,维护这BlocksMap和接收来自DN的块汇报等
  3. 数据节点的管理
    namenode用于管理datanode,包含了decomission和activities的节点,用于接收DN注册,心跳等。
  4. 租约管理
    用于管理文件访问的租约
  5. 缓存管理
    缓存管理器处理DataNode上的缓存。这个类由由FSNamesystem实例化。它通过datanode缓存report来维护cache block到datanode的映射。根据这些report,添加和删除缓存指令
  6. 提供客户端和slave远程方法的调用
    创建了ServerRPCServer和ClientRPCServer用于处理客户端和slave请求

FSDirectory数据结构

  INodeDirectory rootDir;//用于记录目录树的根路径
  private final FSNamesystem namesystem; //FSNameSystem对象
  private volatile boolean skipQuotaCheck = false; //skip while consuming edits 是否跳过quota检测
  private final int maxComponentLength; //目录中每个Component的最大长度
  private final int maxDirItems; //目录里最大的文件数量
  private final INodeMap inodeMap; // Synchronized by dirLock 存储了inodeid和Inode的对应关系
  private int quotaInitThreads; //用于在启动NN后,初始化quota的线程数量
  private final FSEditLog editLog; //FSEditlog对象,用于写editlog

主要方法有:
FSDirectory的主要方法

如何添加文件

在调用FileSystem.create之后,在FSDirectory是如何添加文件的:

  在指定的Inode
  @VisibleForTesting
  public INodesInPath addLastINode(INodesInPath existing, INode inode,
      boolean checkQuota) throws QuotaExceededException {//在一个存在的目录下边创建文件
    assert existing.getLastINode() != null &&
        existing.getLastINode().isDirectory();

    final int pos = existing.length();//查看路径level
    // Disallow creation of /.reserved. This may be created when loading
    // editlog/fsimage during upgrade since /.reserved was a valid name in older
    // release. This may also be called when a user tries to create a file
    // or directory /.reserved.
    if (pos == 1 && existing.getINode(0) == rootDir && isReservedName(inode)) {
      throw new HadoopIllegalArgumentException(
          "File name \"" + inode.getLocalName() + "\" is reserved and cannot "
              + "be created. If this is during upgrade change the name of the "
              + "existing file or directory to another name before upgrading "
              + "to the new release.");
    }
    //获取创建目录的上一级InodeD
    final INodeDirectory parent = existing.getINode(pos - 1).asDirectory();
    // The filesystem limits are not really quotas, so this check may appear
    // odd. It's because a rename operation deletes the src, tries to add
    // to the dest, if that fails, re-adds the src from whence it came.
    // The rename code disables the quota when it's restoring to the
    // original location because a quota violation would cause the the item
    // to go "poof".  The fs limits must be bypassed for the same reason.
    if (checkQuota) {//是否检测quota
      final String parentPath = existing.getPath();
      verifyMaxComponentLength(inode.getLocalNameBytes(), parentPath);
      verifyMaxDirItems(parent, parentPath);
    }
    // always verify inode name 验证inode name
    verifyINodeName(inode.getLocalNameBytes());
    //通过块存储策略来计算quota使用量
    final QuotaCounts counts = inode.computeQuotaUsage(getBlockStoragePolicySuite());
    //更新父目录的quota
    updateCount(existing, pos, counts, checkQuota);

    boolean isRename = (inode.getParent() != null);
    boolean added;
    try {
      added = parent.addChild(inode, true, existing.getLatestSnapshotId());
    } catch (QuotaExceededException e) {
      updateCountNoQuotaCheck(existing, pos, counts.negation());
      throw e;
    }
    if (!added) {
      updateCountNoQuotaCheck(existing, pos, counts.negation());
      return null;
    } else {
      if (!isRename) {
        AclStorage.copyINodeDefaultAcl(inode);
      }
      addToInodeMap(inode);
    }
    //quota更新成功后,在对应父目录的InodePath中添加此inode对象
    return INodesInPath.append(existing, inode, inode.getLocalNameBytes());
  }
  

FSNamesystem

FSNamesystem是NN中最重要的类,实际记录了dn上所有的工作状态。
FSNamesystem
重要参数有:

  FSDirectory dir; FSDirectory
  private final BlockManager blockManager; //保存NN中所有数据块的元数据,用于block管理,维护这BlocksMap和接收来自dn的块汇报等
  private final SnapshotManager snapshotManager; //用于Snapshot的管理
  private final CacheManager cacheManager; //用于管理dn上的Cache
  private final DatanodeStatistics datanodeStatistics; //用于记录dn的统计信息,例如心跳汇报等

此类的方法很多,主要用于管理dn上报的比如心跳汇报、块汇报等,用于管理集群slave和数据块。具体内容如下:
FSNamesystem的方法

FSNamesystem如何处理dn发送的心跳汇报?

  //用于记录dn发送过来的心跳,确保dn不心跳超时,同时发送command给dn
  HeartbeatResponse handleHeartbeat(DatanodeRegistration nodeReg,
      StorageReport[] reports, long cacheCapacity, long cacheUsed,
      int xceiverCount, int xmitsInProgress, int failedVolumes,
      VolumeFailureSummary volumeFailureSummary,
      boolean requestFullBlockReportLease) throws IOException {
    readLock();
    try {
      //get datanode commands
      final int maxTransfer = blockManager.getMaxReplicationStreams()
          - xmitsInProgress;
      //nn通过调用DataNodeManager的handleHeartbeat方法进行心跳汇报的处理,生成一组需要被dn执行的cmds命令
      DatanodeCommand[] cmds = blockManager.getDatanodeManager().handleHeartbeat(
          nodeReg, reports, blockPoolId, cacheCapacity, cacheUsed,
          xceiverCount, maxTransfer, failedVolumes, volumeFailureSummary);
      long blockReportLeaseId = 0;
      if (requestFullBlockReportLease) {
        blockReportLeaseId =  blockManager.requestBlockReportLeaseId(nodeReg);
      }
      //create ha status 获取当前NS的HA状态
      final NNHAStatusHeartbeat haState = new NNHAStatusHeartbeat(
          haContext.getState().getServiceState(),
          getFSImage().getCorrectLastAppliedOrWrittenTxId());
      //生成HeartbeatResponse返回给dn
      return new HeartbeatResponse(cmds, haState, rollingUpgradeInfo,
          blockReportLeaseId);
    } finally {
      readUnlock("handleHeartbeat");
    }
  }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 如果Hadoop的NameNode无法启动,可能有多种原因导致。以下是一些可能的解决方案: 1. 检查配置文件:请确保Hadoop配置文件中的参数已正确设置,特别是fs.defaultFS和dfs.namenode.name.dir参数是否正确设置。 2. 检查磁盘空间:请确保NameNode所在的磁盘有足够的可用空间。 3. 检查端口号:请确保没有其他进程在使用NameNode所需的端口号。 4. 检查日志:请查看NameNode日志,以确定出现了什么错误,然后根据错误信息来调整配置和操作。 5. 删除临时文件:尝试删除dfs.namenode.name.dir目录下的所有临时文件,然后重新启动NameNode。 希望这些解决方案对你有所帮助。如果问题仍然存在,请提供更多细节,以便我们能够更好地帮助你解决问题。 ### 回答2: Hadoop的NameNodeHadoop分布式文件系统(HDFS)的关键组件之一,它负责管理整个系统的文件目录结构和元数据,并监控数据节点的状态。当NameNode无法启动时,可能会导致整个Hadoop集群无法正常工作。 NameNode启动失败可能是由于以下几个常见原因: 1. 配置问题:首先需要检查Hadoop的配置文件是否正确配置。确保 namenode 配置文件中的文件路径是正确且存在的。还需要确保Hadoop集群的各个组件的配置文件一致,特别是 core-site.xml 和 hdfs-site.xml。 2. 资源问题:NameNode可能因为机器资源不足而无法启动。这包括内存、磁盘空间和CPU等资源。确保服务器有足够的资源来运行NameNode。 3. 数据完整性问题:如果NameNode之前的关闭是非正常的,可能会导致数据损坏或元数据不一致。在这种情况下,可能需要修复文件系统的一致性。可以尝试在启动NameNode之前运行fsck命令来检查和修复数据节点中的错误。 4. 端口冲突:检查是否有其他服务在使用NameNode默认的端口(例如,50070和9000)。如果是这样,可以尝试更改端口来解决冲突。 5. 日志检查:定位问题的另一种方法是检查NameNode的日志文件。日志文件中通常会提供有关启动失败的详细错误信息。根据错误信息,可以尝试解决问题或进一步排查。 如果上述方法都无法解决问题,建议搜索相关问题的解决方案。也可以向Hadoop社区的论坛或邮件列表寻求帮助,与其他有经验的用户交流,并尽快找到问题的解决办法,以确保Hadoop集群的正常运行。 ### 回答3: Hadoop的NameNode启动不了可能有多种原因。 首先,可能是由于配置文件错误导致NameNode无法启动。我们可以检查hadoop配置文件中的namenode相关参数是否正确,包括文件路径、端口号等。确保配置文件中的参数与实际环境一致。 其次,可能是由于硬件或操作系统问题导致NameNode无法正常启动。我们可以检查系统的内存和磁盘空间是否足够,以及文件权限是否正确设置。 此外,可能是由于网络问题导致NameNode无法启动。我们可以检查网络配置是否正确,并尝试使用ping命令检查与其他节点的连通性。 如果以上方法都无法解决问题,我们可以查看hadoop日志文件以获取更详细的错误信息。日志文件通常位于hadoop安装目录下的logs文件夹中,其中包含有关启动失败的详细错误信息,可用于进一步排查问题。 最后,如果问题仍然无法解决,我们可以在hadoop社区或论坛上提问,向其他有经验的用户或开发人员寻求帮助。他们可能能够提供更专业的建议和解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镰刀韭菜

看在我不断努力的份上,支持我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值