[HDFS] 파일 을 휴지통 에 넣 기 - rename 작업

잇다http://blog.csdn.net/tracymkgld/article/details/17552189
전편 에 서 는 휴지통 이 구체 적 으로 어떻게 일 하 는 지 언급 하지 않 았 으 니 이어서 보 세 요.
    if(!skipTrash) {
      try {
	      Trash trashTmp = new Trash(srcFs, getConf());
        if (trashTmp.moveToTrash(src)) {//new   trash,               
          System.out.println("Moved to trash: " + src);
          return;
        }
      } catch (IOException e) {
        Exception cause = (Exception) e.getCause();
        String msg = "";
        if(cause != null) {
          msg = cause.getLocalizedMessage();
        }
        System.err.println("Problem with Trash." + msg +". Consider using -skipTrash option");        
        throw e;
      }
    }
파일 을 삭제 할 때 보통 Trash 를 거 칩 니 다. FsShell 의 코드 를 보면 new Trash 대상 이 고 삭제 할 파일 경 로 를 전달 하 는 것 이 간단 합 니 다.
들 어가 서 휴지통 이 뭔 지 볼 까요?
  private final FileSystem fs;
  private final Path trash;//private static final Path TRASH = new Path(".Trash/");
  private final Path current;
  private final long interval;
public Trash(FileSystem fs, Configuration conf) throws IOException {
    super(conf);
    this.fs = fs;
    this.trash = new Path(fs.getHomeDirectory(), TRASH);
    this.current = new Path(trash, CURRENT);//private static final Path CURRENT = new Path("Current");
    this.interval = conf.getLong("fs.trash.interval", 60) * MSECS_PER_MINUTE;//        trash    1  ,            ,       Trash,       2 。
  }
휴지통 대상 이 초기 화 될 때 hdfs 파일 시스템 핸들 을 전달 하 는 것 을 볼 수 있 습 니 다. 그 안에 Path 대상 이 trash 라 고 합 니 다. 이 Path 는 사용자 의 집 디 렉 터 리 를 가리 키 는 'Trash 디 렉 터 리' 입 니 다.
집 목록 이 무엇 인지 한 번 보면 알 수 있다.
public Path getHomeDirectory() {
    return new Path("/user/"+System.getProperty("user.name"))
      .makeQualified(this);
  }

홈 디 렉 터 리 는 hdfs 상 / user / 사용자 이름 이 디 렉 터 리 를 말 합 니 다. 사용자 이름 은 클 라 이언 트 가 사용 하 는 사용자 이름 입 니 다.
Kerbose 통일 인증 은 여기 서 안 할 게 요.아무튼 집 디 렉 터 리 가 어디 인지 알 면 됩 니 다. Liux 와 같은 / home / username / 디 렉 터 리 입 니 다.
movetoTrash 방법의 세 션 을 다시 봅 니 다:
    Path trashPath = makeTrashRelativePath(current, path);
    Path baseTrashPath = makeTrashRelativePath(current, path.getParent());
무슨 뜻 이에 요?
private Path makeTrashRelativePath(Path basePath, Path rmFilePath) {
    return new Path(basePath + rmFilePath.toUri().getPath());
  }
무슨 뜻 이에 요?예 를 들 어 제 가 파일 을 만 들 었 습 니 다: / hadop dfs - touchz / hello / World / o / ca / 123
원래
/ hello / World / wo / ca / 123 이 잖 아 요. 지금 rm 을 떨 어 뜨리 면 이 파일 / user / username /. Trash / current / hello / World / wo / ca / 123 을 발견 할 수 있어 요.
즉, / user / username /. Trash / current / 새로운 쓰레기 뿌리 입 니 다.
그 다음 에 rename 작업 을 수행 하면 원래 파일 rename 을 앞쪽 에 / user / username /. Trash / current 접 두 사 를 붙 이 는 것 입 니 다.그 러 니까 휴지통 에서 지 우 는 게 파일 이름 바 꾸 는 거 야.
rename 에 대해 서 는 한 걸음 한 걸음 추적 하지 않 고 namenode 에 들 어가 보 세 요.
  private synchronized boolean renameToInternal(String src, String dst
      ) throws IOException {
    NameNode.stateChangeLog.debug("DIR* NameSystem.renameTo: " + src + " to " + dst);
    if (isInSafeMode())
      throw new SafeModeException("Cannot rename " + src, safeMode);
    if (!DFSUtil.isValidName(dst)) {
      throw new IOException("Invalid name: " + dst);
    }//            !

    if (isPermissionEnabled) {
      //We should not be doing this.  This is move() not renameTo().
      //but for now,
      String actualdst = dir.isDir(dst)?//               ,       ,  ,  :/a/b/c   /1/2/,    /1/2/a/b/c
          dst + Path.SEPARATOR + new Path(src).getName(): dst;
      checkParentAccess(src, FsAction.WRITE);
      checkAncestorAccess(actualdst, FsAction.WRITE);//             inode     ,  renameTo    
    }

    HdfsFileStatus dinfo = dir.getFileInfo(dst);
    if (dir.renameTo(src, dst)) {
      changeLease(src, dst, dinfo);     // update lease with new filename
      return true;
    }
    return false;
  }
   dir FSDirectory  ,   renameTo  ,    log       ,      
  boolean unprotectedRenameTo(String src, String dst, long timestamp) 
  throws QuotaExceededException {
    synchronized (rootDir) {
      INode[] srcInodes = rootDir.getExistingPathINodes(src);//               inode  
//http://blog.csdn.net/tracymkgld/article/details/17553173
      // check the validation of the source
      if (srcInodes[srcInodes.length-1] == null) {//      inode,           inode
        NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
            + "failed to rename " + src + " to " + dst
            + " because source does not exist");
        return false;
      } 
      if (srcInodes.length == 1) {
        NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
            +"failed to rename "+src+" to "+dst+ " because source is the root");
        return false;//root      
      }
      if (isDir(dst)) {
        dst += Path.SEPARATOR + new Path(src).getName();
      }
      //                     
      // check the validity of the destination
      if (dst.equals(src)) {
        return true;
      }//         ,   ?
      // dst cannot be directory or a file under src
      if (dst.startsWith(src) && //             
          dst.charAt(src.length()) == Path.SEPARATOR_CHAR) {
        NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
            + "failed to rename " + src + " to " + dst
            + " because destination starts with src");
        return false;
      }
      
      byte[][] dstComponents = INode.getPathComponents(dst);
      INode[] dstInodes = new INode[dstComponents.length];
      rootDir.getExistingPathINodes(dstComponents, dstInodes);
      if (dstInodes[dstInodes.length-1] != null) {//   ,   ,  src inode   dst inode 
        NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
                                     +"failed to rename "+src+" to "+dst+ 
                                     " because destination exists");
        return false;
      }
      if (dstInodes[dstInodes.length-2] == null) {
        NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
            +"failed to rename "+src+" to "+dst+ 
            " because destination's parent does not exist");
        return false;
      }
      
      // Ensure dst has quota to accommodate rename
      verifyQuotaForRename(srcInodes,dstInodes);//quota  ,     。
      
      INode dstChild = null;
      INode srcChild = null;
      String srcChildName = null;
      try {
        // remove src
        srcChild = removeChild(srcInodes, srcInodes.length-1);//                    ,      
        if (srcChild == null) {
          NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
              + "failed to rename " + src + " to " + dst
              + " because the source can not be removed");
          return false;
        }
        srcChildName = srcChild.getLocalName();
        srcChild.setLocalName(dstComponents[dstInodes.length-1]);
        
        // add src to the destination
        dstChild = addChildNoQuotaCheck(dstInodes, dstInodes.length - 1,
            srcChild, -1, false);//  dst inode ,add  dst  Inode children (List) ,    quota     ,mtime    。
        if (dstChild != null) {
          srcChild = null;
          if (NameNode.stateChangeLog.isDebugEnabled()) {
            NameNode.stateChangeLog.debug("DIR* FSDirectory.unprotectedRenameTo: " + src
                    + " is renamed to " + dst);
          }
          // update modification time of dst and the parent of src
          srcInodes[srcInodes.length-2].setModificationTime(timestamp);//          mtime
          dstInodes[dstInodes.length-2].setModificationTime(timestamp);
          return true;
        }
      } finally {
        if (dstChild == null && srcChild != null) {
          // put it back
          srcChild.setLocalName(srcChildName);
          addChildNoQuotaCheck(srcInodes, srcInodes.length - 1, srcChild, -1,
              false);
        }
      }
      NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
          +"failed to rename "+src+" to "+dst);
      return false;
    }
소결:
파일 을 삭제 할 때 파일 을 trash 에 넣 으 면 rename 작업 을 수행 하고 / user / username /. Trash / Current / 디 렉 터 리 에 넣 은 다음 namenode 에서 원본 파일 을 namespace 작업 을 합 니 다.
1. 아버지 로부터 벗 어 나 아버지 inodeDirectory 의 children 목록 에서 지 웁 니 다.
2, add 목적 inodeDirectory 의 children 목록 에
3. 원본 디 렉 터 리 의 mtime 를 수정 하 는 동시에 원본 디 렉 터 리 의 quota 점용 을 줄 이 고 dst 의 quota 점용 을 증가 합 니 다.
trash 는 언제 실행 합 니까?http://blog.csdn.net/tracymkgld/article/details/17552189이 6 단계 삭제 작업 이나 trash 를 자동 으로 청소 하 는 방법 은 다음 과 같 습 니 다.http://blog.csdn.net/tracymkgld/article/details/17557655

좋은 웹페이지 즐겨찾기