【问题标题】:Delete files older than 10days on HDFS删除 HDFS 上超过 10 天的文件
【发布时间】:2017-10-29 07:43:25
【问题描述】:

有没有办法删除 HDFS 上超过 10 天的文件?

在 Linux 中我会使用:

find /path/to/directory/ -type f -mtime +10 -name '*.txt' -execdir rm -- {} \;

有没有办法在 HDFS 上做到这一点? (根据文件创建日期删除)

【问题讨论】:

  • 没有 find 命令,但hdfs dfs -ls -R /path/to/directory | egrep .txt$ 是一个好的开始。
  • @cricket_007 但是我们如何处理超过“x”天的事情?
  • 您必须删除标准输出的日期部分,存储过滤后的文件列表,然后循环运行hdfs dfs -rm...换句话说,它需要编写脚本。
  • 我用这个script
  • @jww 请返回您在earlier comment 中指向的链接并通读。与程序员常用的框架/工具(在本例中为 Hadoop)相关的问题很适合 SO。参考:SO on-topic

标签: hadoop hdfs


【解决方案1】:

解决方案 1:使用多个命令,由 daemon12 回答

hdfs dfs -ls /file/Path    |   tr -s " "    |    cut -d' ' -f6-8    |     grep "^[0-9]"    |    awk 'BEGIN{ MIN=14400; LAST=60*MIN; "date +%s" | getline NOW } { cmd="date -d'\''"$1" "$2"'\'' +%s"; cmd | getline WHEN; DIFF=NOW-WHEN; if(DIFF > LAST){ print "Deleting: "$3; system("hdfs dfs -rm -r "$3) }}'

解决方案 2: 使用 Shell 脚本

today=`date +'%s'`
hdfs dfs -ls /file/Path/ | grep "^d" | while read line ; do
dir_date=$(echo ${line} | awk '{print $6}')
difference=$(( ( ${today} - $(date -d ${dir_date} +%s) ) / ( 24*60*60 ) ))
filePath=$(echo ${line} | awk '{print $8}')

if [ ${difference} -gt 10 ]; then
    hdfs dfs -rm -r $filePath
fi
done

【讨论】:

  • grep "^d" 将只返回目录(等待我的编辑批准)。如果有必要,建议使用... | grep "/file/Path/" | ... 之类的东西来避免处理输出中的标题行,以及使用grep -v "^d" 来避免目录。
  • 修复 $(date -d ${dir_date} +%s)$(date -d ${dir_date} +'%s')
【解决方案2】:

这个怎么样:

hdfs dfs -ls /tmp    |   tr -s " "    |    cut -d' ' -f6-8    |     grep "^[0-9]"    |    awk 'BEGIN{ MIN=14400; LAST=60*MIN; "date +%s" | getline NOW } { cmd="date -d'\''"$1" "$2"'\'' +%s"; cmd | getline WHEN; DIFF=NOW-WHEN; if(DIFF > LAST){ print "Deleting: "$3; system("hdfs dfs -rm -r "$3) }}'

详细说明是here

【讨论】:

  • 然后跳过垃圾箱??
  • 是的,如果用户想删除文件而不将它们移动到垃圾箱。
【解决方案3】:

是的,您可以尝试使用 HdfsFindTool

hadoop jar /opt/cloudera/parcels/CDH/lib/solr/contrib/mr/search-mr-job.jar \
  org.apache.solr.hadoop.HdfsFindTool \
  -find /pathhodir -mtime +10 -name ^.*\.txt$ \
  | xargs hdfs dfs -rm -r -skipTrash

【讨论】:

  • 对于我们这些不使用 CDH 的人,我们如何获得它?
  • 这真的很慢。
【解决方案4】:

我尝试实施上述公认的解决方案。

不幸的是,它只对我部分有用。我遇到了 3 个现实世界的问题。

首先,hdfs 没有足够的 RAM 来加载和打印所有文件。

其次,即使 hdfs 可以打印所有文件,awk 在中断之前也只能处理大约 8300 条记录。

第三,表现糟糕透顶。实施时,它每分钟删除约 10 个文件。这没有用,因为我每分钟生成约 240 个文件。

所以我的最终解决方案是这样的:

tmpfile=$(mktemp)
HADOOP_CLIENT_OPTS="-Xmx2g" hdfs dfs -ls /path/to/directory    |   tr -s " "    |    cut -d' ' -f6-8    |     grep "^[0-9]"    |    awk 'BEGIN{ MIN=35*24*60; LAST=60*MIN; "date +%s" | getline NOW } { cmd="date -d'\''"$1" "$2"'\'' +%s"; cmd | getline WHEN; DIFF=NOW-WHEN; if(DIFF > LAST){ print $3}}; close(cmd);' > $tmpfile
hdfs dfs -rm -r $(cat $tmpfile)
rm "$tmpfile"

我不知道这个解决方案是否有额外的限制,但它可以及时处理 50,000 多条记录。

编辑:有趣的是,我再次遇到了这个问题,在删除时,我不得不批量删除,因为 hdfs rm 语句不能接受超过 ~32,000 个输入。

【讨论】:

    【解决方案5】:
    hdfs dfs -ls -t /file/Path|awk -v dateA="$date" '{if ($6" "$7 < {target_date}) {print ($8)}}'|xargs -I% hdfs dfs -rm "%" /file/Path
    

    【讨论】:

      【解决方案6】:
      today=`date +'%s'`
      days_to_keep=10
      
      # Loop through files
      hdfs dfs -ls -R /file/Path/ | while read f; do
        # Get File Date and File Name
        file_date=`echo $f | awk '{print $6}'`
        file_name=`echo $f | awk '{print $8}'`
      
        # Calculate Days Difference
        difference=$(( ($today - $(date -d $file_date +%s)) / (24 * 60 * 60) ))
        if [ $difference -gt $days_to_keep ]; then
          echo "Deleting $file_name it is older than $days_to_keep and is dated $file_date."
          hdfs dfs -rm -r $file_name
        fi
      done
      

      【讨论】:

      【解决方案7】:

      只是为了添加以前提交的答案的另一个变体(我不想假装是原创的)。可以修改脚本以递归删除子文件夹或文件

      #!/bin/bash
      function hdfs-list-older-than () {
      # list all content | filter out sub-folders | filter by creation datetime and isolate filepath
        hdfs dfs -ls  $1 | grep ^- | awk -v d=$2 -v t=$3 '{if($6 < d || ($6 == d && $7 < t) ){print $8}}'
      }
      hdfs-list-older-than $1 `date -d "-10 days"  +'%Y-%m-%d %H:%M'` | xargs hdfs dfs -rm {}
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多