better done than better said

困ったときに調べた結果

hadoop hdfsでファイル数を監視するスクリプトを作ったのでメモ

hadoop hdfsでファイル数が増えすぎるのを防ぐために他スクリプトで圧縮や期間を見て削除するなど対策をしています。
しかしそれでも特定のサービスディレクトリにファイル数が急増してしまう問題があったため個別に閾値を見直せるために雑なスクリプトを作ったのでメモ。
閾値を超えている場合はslackに通知を行います。

#!/usr/bin/env bash
# 基本の閾値
avg=10000
# slackに通知
url="https://hooks.slack.com/services/xxxxxxxxx/xxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxx"


# 個別に閾値を設定したい場合は配列に入れておく
data=(
  '/services/a/z 50000'
  '/services/a/x 100000'
  '/services/b/z 100000'
  '/services/b/x 100000'
)

check() {
  for i in $@; do
    flg=0
    if [ -n "$i" ]; then
      line="$(hadoop fs -count $i)"
      # 対象ディレクトリとファイル数を取得
      dir=$(echo $line | awk '{print $4}')
      ct=$(echo $line | awk '{print $2}')

      #閾値を超えている場合はslackに通知
      if [ $ct -gt $avg ]; then
        for j in "${data[@]}"; do
          vdata=(${j[@]})
          # 個別の閾値が設定されている場合
          if [ ${vdata[0]} = $dir ]; then
            flg=1
            if [ $ct -gt ${vdata[1]} ]; then
              echo PATH: ${vdata[0]}, CT: $ct, LIMIT: ${vdata[1]}
              curl -X POST --data-urlencode "payload={\"text\": \"Path: ${vdata[0]}, Ct: $ct, Limit: ${vdata[1]}\" }" $url
            fi
            break
          fi
        done
   
        # 個別の閾値が設定されていない場合
        if [ $flg -eq 0 ]; then
          echo path: $dir, ct: $ct, limit: $avg
          curl -X POST --data-urlencode "payload={\"text\": \"path: $dir, ct: $ct, limit: $avg\" }" $url
        fi
      fi
    fi
  done
}

# services直下のディレクトリ一覧を取得
ar=$(hadoop fs -ls /services | awk '{print $8}')
for j in "${ar[@]}"; do
  # services直下のディレクトリ一覧のさらにディレクトリ一覧を取得
  sr=$(hadoop fs -ls $j | awk '{print $8}')
  check ${sr[@]}
done

hdoopコマンドで再帰的にディレクトリを拾う方法はもっと良い方法があるはずなので諸々改善の余地あり。