【问题标题】:Finding directories older than N days in HDFS在 HDFS 中查找超过 N 天的目录
【发布时间】:2019-05-17 19:51:31
【问题描述】:

hadoop fs -ls 可以用来查找所有超过 N 天(从当前日期开始)的目录吗?

我正在尝试编写一个清理例程来查找和删除 HDFS 上的所有目录(匹配模式),这些目录是在当前日期前 N 天创建的。

【问题讨论】:

  • 早期的解决方案之一有部分帮助。我可以编写一个 shell 脚本来查找和删除所有与模式匹配的目录,但我真正需要做的是只删除那些超过 N 天的目录。 (stackoverflow.com/questions/7733096/…)

标签: hadoop hdfs


【解决方案1】:

此脚本列出所有早于[days] 的目录:

#!/bin/bash
usage="Usage: $0 [days]"

if [ ! "$1" ]
then
  echo $usage
  exit 1
fi

now=$(date +%s)
hadoop fs -lsr | grep "^d" | while read f; do 
  dir_date=`echo $f | awk '{print $6}'`
  difference=$(( ( $now - $(date -d "$dir_date" +%s) ) / (24 * 60 * 60 ) ))
  if [ $difference -gt $1 ]; then
    echo $f;
  fi
done

【讨论】:

    【解决方案2】:

    如果你碰巧使用CDH Hadoop 发行版,它带有一个非常有用的HdfsFindTool 命令,其行为类似于Linux 的find 命令。

    如果您使用的是默认包裹信息,请按照以下步骤操作:

    hadoop jar /opt/cloudera/parcels/CDH/jars/search-mr-*-job.jar \
    org.apache.solr.hadoop.HdfsFindTool -find PATH -mtime +N
    

    您可以将 PATH 替换为搜索路径,将 N 替换为天数。

    【讨论】:

    • 温馨提示:CDH 6.X 已弃用 HdfsFindTool
    【解决方案3】:

    对于真正的集群,这不是一个好主意, 使用 ls。如果您有管理员权限, 用fsimage比较合适。

    我修改了上面的脚本来说明想法。

    首先,获取 fsimage

    curl "http://localhost:50070/getimage?getimage=1&txid=latest" > img.dump
    

    将其转换为文本(与 lsr 给出的输出相同)

    hdfs oiv -i img.dump -o fsimage.txt
    

    脚本:

    #!/bin/bash
    usage="Usage: dir_diff.sh [days]"
    
    if [ ! "$1" ]
    then
      echo $usage
      exit 1
    fi
    
    now=$(date +%s)
    curl "http://localhost:50070/getimage?getimage=1&txid=latest" > img.dump
    hdfs oiv -i img.dump -o fsimage.txt
    cat fsimage.txt | grep "^d" | while read f; do 
      dir_date=`echo $f | awk '{print $6}'`
      difference=$(( ( $now - $(date -d "$dir_date" +%s) ) / (24 * 60 * 60 ) ))
      if [ $difference -gt $1 ]; then
        echo $f;
      fi
    done
    

    【讨论】:

    • 您能解释一下为什么使用 fsimage 更好吗?
    • 如果你有数百万个文件,'fs -ls' 可能不起作用。因此,您可以编写自己的 java 代码来迭代文件系统或转储 fsimage 一次,然后使用它和简单的 unix 工具运行许多后续操作。
    【解决方案4】:

    hdfs dfs -ls /hadoop/path/*.txt|awk '$6

    【讨论】:

    • 请对您的回答给出适当的解释。
    • hdfs dfs -ls /hadoop/path/*.txt - 这部分将搜索所有 .txt 文件 awk '$6
    【解决方案5】:

    我没有HdfsFindTool,也没有来自curlfsimage,我不太喜欢lsgrepwhile 循环使用date awkhadoopawk 再次。 但我很欣赏这些答案。

    我觉得只需要一个ls、一个awk 和一个xargs 就可以完成。

    我还添加了在选择删除文件之前列出文件或汇总文件的选项,以及选择特定目录。最后我离开了目录,只关心文件。

    #!/bin/bash
    USAGE="Usage: $0 [N days] (list|size|delete) [path, default /tmp/hive]"
    if [ ! "$1" ]; then
      echo $USAGE
      exit 1
    fi
    AGO="`date --date "$1 days ago" "+%F %R"`"
    
    echo "# Will search for files older than $AGO"
    if [ ! "$2" ]; then
      echo $USAGE
      exit 1
    fi
    INPATH="${3:-/tmp/hive}"
    
    echo "# Will search under $INPATH"
    case $2 in
      list)
        hdfs dfs -ls -R "$INPATH" |\
          awk '$1 ~ /^[^d]/ && ($6 " " $7) < '"\"$AGO\""
      ;;
      size)
        hdfs dfs -ls -R "$INPATH" |\
          awk '$1 ~ /^[^d]/ && ($6 " " $7) < "'"$AGO"'" {
               sum += $5 ; cnt += 1} END {
               print cnt, "Files with total", sum, "Bytes"}'
      ;;
      delete)
        hdfs dfs -ls -R "$INPATH" |\
          awk '$1 ~ /^[^d]/ && ($6 " " $7) < "'"$AGO"'" {print $8}' | \
          xargs hdfs dfs -rm -skipTrash
      ;;
      *)
        echo $USAGE
        exit 1
      ;;
    esac
    

    我希望其他人觉得这很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-11
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      相关资源
      最近更新 更多