【HDFS】文件入Trash-rename操作
接http://blog.csdn.net/tracymkgld/article/details/17552189
上篇没提到Trash具体怎么工作,接着看一下:
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对象,然后把要删的文件路径传给它就这么简单。
进入看看什么是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天。}
可以看到Trash对象初始化的时候,要传递hdfs的文件系统句柄,它里边有个Path对象叫trash,这个Path指向用户家目录的.Trash目录
什么是家目录,看一眼你就知道了:
public Path getHomeDirectory() {return new Path("/user/"+System.getProperty("user.name")).makeQualified(this);}
家目录是指hdfs上/user/用户名这个目录,用户名是你客户端使用的用户名,关于 Kerbose 统一认证这里就不讲了。总之知道哪里是家目录就行了,类似linux的/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());}
啥意思?是这样的,比如我创建一个文件:/hadoop dfs -touchz /hello/world/wo/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的前缀。所以删到Trash中就是给文件rename。
关于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/cdst + 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 filenamereturn 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 sourceif (srcInodes[srcInodes.length-1] == null) {//显然这是目标inode,就是你想改名的那个文件inodeNameNode.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 destinationif (dst.equals(src)) {return true;}//是不是同一个文件名,操蛋呢?// dst cannot be directory or a file under srcif (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 renameverifyQuotaForRename(srcInodes,dstInodes);//quota管理,这里先不讲。INode dstChild = null;INode srcChild = null;String srcChildName = null;try {// remove srcsrcChild = 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 destinationdstChild = 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 srcsrcInodes[srcInodes.length-2].setModificationTime(timestamp);//源和端的父目录都更新mtimedstInodes[dstInodes.length-2].setModificationTime(timestamp);return true;}} finally {if (dstChild == null && srcChild != null) {// put it backsrcChild.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
【HDFS】文件入Trash-rename操作相关推荐
- python 新建文件 hdfs_大数据学习(六):Python操作hdfs(包括追加数据文件到hdfs文件)...
#!coding:utf-8 import sys from hdfs.client import Client #设置utf-8模式 reload(sys) sys.setdefaultencodi ...
- MapReduce基础开发之八HDFS文件CRUD操作
HDFS文件操作的基础代码. package com.hive;import java.io.BufferedInputStream; import java.io.BufferedOutputStr ...
- Hadoop之HDFS文件操作
摘要:Hadoop之HDFS文件操作常有两种方式,命令行方式和JavaAPI方式.本文介绍如何利用这两种方式对HDFS文件进行操作. 关键词:HDFS文件 命令行 Java API HD ...
- HDFS文件和HIVE表的一些操作
HDFS文件和HIVE表的一些操作 1. hadoop fs -ls 可以查看HDFS文件 后面不加目录参数的话,默认当前用户的目录./user/当前用户 $ hadoop fs -ls 16/05 ...
- linux 查看hdfs文件,Hadoop之HDFS文件操作
摘要:Hadoop之HDFS文件操作常有两种方式,命令行方式和JavaAPI方式.本文介绍如何利用这两种方式对HDFS文件进行操作. 关键词:HDFS文件 命令行 Java API HDF ...
- hadoop的hdfs文件操作实现上传文件到hdfs
hdfs文件操作操作示例,包括上传文件到HDFS上.从HDFS上下载文件和删除HDFS上的文件,大家参考使用吧 复制代码代码如下: import org.apache.hadoop.conf.Conf ...
- Hadoop hdfs文件操作常用命令
hadoop fs -操作命令 -参数 -ls #显示目录信息 -->hadoop fs -ls hdfs://hadoop-server-00:9000/ 这些参数中,所有的hdfs路径都可以 ...
- 大数据上机基础—HDFS文件操作
本文为在校学习大数据课程期间,对厦门大学林子雨老师大数据技术原理与应用 第三章 分布式文件系统HDFS学习指南一文进行的整理,方便自己学习查看 原文地址为大数据技术原理与应用 第三章 分布式文件系统H ...
- hadoop shell操作HDFS文件
一.常用的 hadoop shell 文件路径需要自己有才行,示例中的文件路径是本人自己的文件路径,不是公共文件路径,如何建立自己的数仓,查看本人 大数据单机学习环境搭建 相关文章 1.1查看 创建 ...
最新文章
- 【算法笔记】哈密顿问题
- 【Python刷题】_2
- 如何:修改 Office Open XML 文档【转载】
- 【CodeForces 504A】Misha and Forest
- GX Works2无法步执行调试的说明
- Mac中Homebrew下载指定版本软件的方法
- ps怎么对比原图快捷键_ps快捷键对比
- java实现wps函数IRR,Excel表格技巧—如何用IRR函数算内部收益率
- 如何写一个好的缺陷(Defect)报告
- file_get_contents获取参数并用file_put_contents保存图片
- 要考试了,通过爬虫获取试题,最后再看2小时
- 001-mac使用桌面、Dock、键盘、程序安装
- Win 10 远程桌面连接
- 解决 “此图片来自微信公众平台未经允许不可引用” 的方法
- 全球最大双机身飞机Stratolaunch完成首飞
- 计算机视觉中的Transformer
- node14 升级 node16 后 vue2 项目中 sass 报错问题
- 工具及方法 - 如何保护眼睛
- Oracle Tigger触发器 实例
- 安居客爬虫+分析+回归