【问题标题】:Adding a new namenode data directory to an existing cluster将新的 namenode 数据目录添加到现有集群
【发布时间】:2014-01-23 08:04:13
【问题描述】:

我需要遵循什么程序才能将 new NameNode 数据目录(dfs.name.dir、dfs.namenode.name.dir)正确添加到 现有生产集群?我在 hdfs-site.xml 文件中添加了逗号分隔列表的新路径,但是当我尝试启动 namenode 时,出现以下错误:

目录/data/nfs/dfs/nn处于不一致状态:存储目录不存在或不可访问。

在我的例子中,我有两个目录已经就位并且正在工作。 (/data/1/dfs/nn,/data/2/dfs/nn) 当我添加新目录时,我无法启动名称节点。删除新路径后,它开始就好了。我的新目录的 fstab 如下所示:

备份服务器:/hadoop_nn /data/nfs/dfs nfs tcp,soft,intr,timeo=10,retrans=10 1 2

在上面的挂载点中,我创建了一个名为 nn 的文件夹。该文件夹与其他两个现有位置 nn 文件夹具有相同的所有权和权限。

drwx----- 2 hdfs hadoop 64 Jan 22 16:30 nn

我是否需要手动复制/复制现有名称节点目录之一中的所有文件,或者名称节点服务是否应该在启动时自动执行?

【问题讨论】:

  • /data/nfs/dfs(你的挂载点)的所有权是否允许hdfs用户进入目录?
  • 挂载点归root所有。 (用户和组)该目录的权限为 700。这与其他数据目录遵循的结构相同。 (/data/1/dfs 由 root 拥有,权限为 700,而 /data/1/dfs/nn 由 hdfs/hadoop 拥有)
  • 很公平。还有一个愚蠢的问题:hdfs 用户和hadoop 组在 NFS 服务器和客户端上是否具有相同的 uid(gid)?
  • NFS 服务器是一个 Windows 2012R2 机器。我已为此特定共享打开未映射的 UNIX 用户名访问。据我了解,UUUA 会做到这一点,这样 Windows 就不会真正关心 unix uid/gid,而是随 unix 客户端告诉它的任何内容。

标签: hadoop hdfs cloudera


【解决方案1】:

我相信我可能刚刚回答了我自己的问题。我最终将现有名称节点目录之一的全部内容复制到新的 NFS 名称节点目录中,并且我能够启动名称节点。 (请注意,我在复制之前停止了 namenode 以避免出现问题)

cp -rp /data/1/dfs/nn /data/nfs/dfs/nn

我猜我认为 namenode 会自动将现有元数据复制到新目录的假设是不正确的。

【讨论】:

    【解决方案2】:

    在 Cloudera CDH 4.5.0 中,只有当以下函数(来自 Storage.java,第 418 行附近)返回 NON_EXISTENT 时,才会发生该错误。在每种情况下都会显示一条警告,其中包含更多详细信息,请查找来自org.apache.hadoop.hdfs.server.common.Storage 的日志行。

    简而言之,名称节点似乎认为它不存在,不是目录,不可写或以其他方式抛出SecurityException

    /**
     * Check consistency of the storage directory
     * 
     * @param startOpt a startup option.
     *  
     * @return state {@link StorageState} of the storage directory 
     * @throws InconsistentFSStateException if directory state is not 
     * consistent and cannot be recovered.
     * @throws IOException
     */
    public StorageState analyzeStorage(StartupOption startOpt, Storage storage)
        throws IOException {
      assert root != null : "root is null";
      String rootPath = root.getCanonicalPath();
      try { // check that storage exists
        if (!root.exists()) {
          // storage directory does not exist
          if (startOpt != StartupOption.FORMAT) {
            LOG.warn("Storage directory " + rootPath + " does not exist");
            return StorageState.NON_EXISTENT;
          }
          LOG.info(rootPath + " does not exist. Creating ...");
          if (!root.mkdirs())
            throw new IOException("Cannot create directory " + rootPath);
        }
        // or is inaccessible
        if (!root.isDirectory()) {
          LOG.warn(rootPath + "is not a directory");
          return StorageState.NON_EXISTENT;
        }
        if (!root.canWrite()) {
          LOG.warn("Cannot access storage directory " + rootPath);
          return StorageState.NON_EXISTENT;
        }
      } catch(SecurityException ex) {
        LOG.warn("Cannot access storage directory " + rootPath, ex);
        return StorageState.NON_EXISTENT;
      }
    
      this.lock(); // lock storage if it exists
    
      if (startOpt == HdfsServerConstants.StartupOption.FORMAT)
        return StorageState.NOT_FORMATTED;
    
      if (startOpt != HdfsServerConstants.StartupOption.IMPORT) {
        storage.checkOldLayoutStorage(this);
      }
    
      // check whether current directory is valid
      File versionFile = getVersionFile();
      boolean hasCurrent = versionFile.exists();
    
      // check which directories exist
      boolean hasPrevious = getPreviousDir().exists();
      boolean hasPreviousTmp = getPreviousTmp().exists();
      boolean hasRemovedTmp = getRemovedTmp().exists();
      boolean hasFinalizedTmp = getFinalizedTmp().exists();
      boolean hasCheckpointTmp = getLastCheckpointTmp().exists();
    
      if (!(hasPreviousTmp || hasRemovedTmp
          || hasFinalizedTmp || hasCheckpointTmp)) {
        // no temp dirs - no recovery
        if (hasCurrent)
          return StorageState.NORMAL;
        if (hasPrevious)
          throw new InconsistentFSStateException(root,
                              "version file in current directory is missing.");
        return StorageState.NOT_FORMATTED;
      }
    
      if ((hasPreviousTmp?1:0) + (hasRemovedTmp?1:0)
          + (hasFinalizedTmp?1:0) + (hasCheckpointTmp?1:0) > 1)
        // more than one temp dirs
        throw new InconsistentFSStateException(root,
                                               "too many temporary directories.");
    
      // # of temp dirs == 1 should either recover or complete a transition
      if (hasCheckpointTmp) {
        return hasCurrent ? StorageState.COMPLETE_CHECKPOINT
                          : StorageState.RECOVER_CHECKPOINT;
      }
    
      if (hasFinalizedTmp) {
        if (hasPrevious)
          throw new InconsistentFSStateException(root,
                                                 STORAGE_DIR_PREVIOUS + " and " + STORAGE_TMP_FINALIZED
                                                 + "cannot exist together.");
        return StorageState.COMPLETE_FINALIZE;
      }
    
      if (hasPreviousTmp) {
        if (hasPrevious)
          throw new InconsistentFSStateException(root,
                                                 STORAGE_DIR_PREVIOUS + " and " + STORAGE_TMP_PREVIOUS
                                                 + " cannot exist together.");
        if (hasCurrent)
          return StorageState.COMPLETE_UPGRADE;
        return StorageState.RECOVER_UPGRADE;
      }
    
      assert hasRemovedTmp : "hasRemovedTmp must be true";
      if (!(hasCurrent ^ hasPrevious))
        throw new InconsistentFSStateException(root,
                                               "one and only one directory " + STORAGE_DIR_CURRENT 
                                               + " or " + STORAGE_DIR_PREVIOUS 
                                               + " must be present when " + STORAGE_TMP_REMOVED
                                               + " exists.");
      if (hasCurrent)
        return StorageState.COMPLETE_ROLLBACK;
      return StorageState.RECOVER_ROLLBACK;
    }
    

    【讨论】:

    • 查看我对问题的回答。我的猜测是,由于新路径是空的,它在名称节点看来是不存在的。我以为添加新目录时会自动复制到新目录,但我想我错了。
    猜你喜欢
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2019-05-10
    • 2019-08-25
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多