タスク構造:
- プロジェクト
- project1 /-プロジェクト
- conf /
- <run_configurations> * .conf-テーブルレポート構成
- レポート/
- <run_configurations> /
- report1.json-レポート自体。ApacheHiveテーブルの統計が含まれます
- report2.json
- <run_configurations> /
- conf /
- project2 /
...
- project1 /-プロジェクト
期限切れのレポートを見つけることが必要です。
だから、Bashを見つけて、マン用に別のターミナルを開いて続行してください)
興味のある方は誰でも猫をお願いします。
プロジェクトを含むフォルダー形式の内部レポートシステム。 各プロジェクトの
conf
フォルダーには、レポートが作成されるテーブルに従って、
"schema"
フィールドにHiveデータベースの名前を含むレポートを作成するための構成があります。
reports
フォルダー内-構成名を持つフォルダーに配置されたレポート自体。 各レポートは、
"table"
オブジェクトの配列内のHiveテーブルに関する統計と、
"created_date"
フィールドの作成日を含む
json
です。 ファイルの作成日ではなく、それを使用してみましょう。 レポートの作成後に変更されたテーブルを含むレポートを見つける必要があります。
なぜSQLスタイルなのですか? Bashは、SQLでのテーブルの処理を連想させる、列(通常はスペース)に分割されたテキストを操作する絶好の機会を提供します。
ツールキット:
- cat、find、grepなど-ビューは必要ありません)
- sed-
sed s// /g
をダム自動交換に使用 - awk-列の表示/再配置/マージ、列の内容による行のフィルタリングを可能にします
- ソート、uniq-おそらくログレイカーのお気に入りのツール)最初-ソート、2番目-重複を削除/カウントします。 すべてに頻繁に使用される トップN
awk '...' log | sort -k field_n | uniq -c | sort -n -r | head -n N
- xargs-単一のコマンドで文字列のストリームを処理します。 特定のコマンドのargument-listの行を展開したり、各行でこのコマンドを実行したりできます。
- join-自然なSQL-evsky INNER JOIN。 2つのソートされたファイルを1つの同一フィールドの値で1つにマージします。最初に共通フィールド、次に最初のファイルの残りのフィールド、次に2番目のフィールドが続きます。
始めましょう。 開始するには、使用するテーブルを曲げるだけです:
grep -r "\"table\":" projects/*/reports/* | ...
彼はこの形式でデータを提供します:
projects / project1 / reports / run1 / report1.json: "table": "table1"、
projects / project1 / reports / run2 / report2.json: "table": "table2"、
projects / project2 / reports / run3 / report3.json: "table": "table3"、
...
... | sed 's/:/ /g' | awk '{print $1 " " $3}' | sed 's/[\r\n",:]//g' | ... ... | sort -k 1b,1 | uniq > report_tables
「:」をスペースに変更して、「テーブル」列からファイル名を正確に分離し、最初の(レポートファイル)および3番目(テーブル名)の列を印刷し、sed破片をきれいにし、最初のテーブルでreport_tablesを並べ替えて保存します。
次に、同じ方法で、report_datesテーブルを作成し、created_dateを使用して、もう少し列(日付と時刻)を表示します。
grep -r "\"created_date\":" projects/*/reports/* | sed 's/:/ /g' | ... ... | awk '{print $1 " " $3"T"$4":"$5":"$6}' | sed 's/[\r\n",:]//g' | ... ... | sort -k 1b,1 | uniq > report_dates
次に、レポートファイル名とテーブル名を1つの列に結合して結合します。レポートファイル、テーブル、およびこのレポートの作成日を含むテーブルを取得します。
join report_tables report_dates | awk '{print $1"#"$2 " " $3}' | ... ... | sort -k 1b,1 > report_table_date
projects / project1 / reports / run1 / report1.json#table1 2017-08-07T070918.024907
projects / project1 / reports / run1 / report1.json#table2 2017-08-07T070918.024907
projects / project1 / reports / run1 / report1.json#table3 2017-08-07T070918.024907
...
最初の部分は準備ができているようです。 今、類推により、使用されたデータベースを加熱します。
grep -r "schema\":" projects/*/conf/* | sed 's/:/ /g' | ... ... | awk '{print $3 " " $1}' | sed 's/[\r\n":,]//g' | ... ... | sort -k 1b,1 | uniq > schema_configs
schema1プロジェクト/ project1 / conf / run1.conf
schema1プロジェクト/ project1 / conf / run2.conf
schema2プロジェクト/ project2 / conf / run1.conf
...
これが最初の困難です。 前の表はレポートファイルに基づいており、これは構成ファイルに基づいています。 それらの間に貼り付ける必要があります:
cat schema_configs | awk '{print $2}' | sort | uniq | ...
考えてみてください。
xargs -n1 find ...
置くだけ
xargs -n1 find ...
設定自体の行が失われるため、できませんが、必要です。 したがって、サイクルを繰り返します。 まあ。 パイプを入れて行きます:
... | while read line; do <statements>; done | sort -k 1b,1 > config_reports
次に、ステートメント内にすべてを記述します。
dir=$(dirname $line); dir2=$(dirname $dir); ... run=$(echo $line | sed "s/.*\///" | sed 's/\.conf//g'); ... reps=$(find $dir2/reports/$run/ -name *.json); ... for r in $reps; do echo $line $r ; done
複雑に見えます。
dirname
はファイルパスから最後のスラッシュへのパスを取得します。これを使用して、レポートファイルを数レベル
($dir2)
上に上げます。 次の式
run=...
は、ファイル
run.conf
名前を
$line
から
run.conf
、拡張子を切り捨てて起動構成の名前を取得します。 次に、
reps
はこの構成のレポートを含むファイルの名前であり、それらのループにより、
$line
のファイルとレポート
$r
のファイルが表示されます。
config_reports
プレートを並べ替えて記述し
config_reports
。
projects / project1 / conf / run1.conf projects / project1 / reports / run1 / report1.json
projects / project1 / conf / run1.conf projects / project1 / reports / run1 / report2.json
projects / project1 / conf / run2.conf projects / project1 / reports / run2 / report3.json
...
これは作業の最も重要な部分でした-構成のスペースとレポートのスペースを対応させること。 使用されたデータベースのテーブルの最終変更の日付を決定するためだけに残っており、必要なすべての情報があります。残りはすべてを適切に変更することです。 行こう:
cat schema_configs | awk '{print $1}' | sort | uniq | ... ... |sed 's/^/path_in_hive/g' | sed 's/$/\.db/g' | ... ... | xargs -n1 -I dr hdfs dfs -ls dr | sed 's/\// /g' | ... ... | sed 's/\.db//g' | awk '{print $12 " " $13 " " $6"T"$7}' | ... ... | sort -k 1b,1 | uniq > schema_tables
長さにもかかわらず、すべてが簡単です。 最初に
schema_configs
を
schema_configs
、そこから一意の回路を
schema_configs
し、
sed
使用してHiveストレージへのパスを先頭に、
.db
拡張子を末尾
sed
割り当てます。 そのような行ごとに
hdfs dfs -ls
を実行すると、指定されたデータベース内のすべてのテーブルとその最終変更日が表示されます。 すべてのスラッシュをスペースに変更し、データベースの名前、テーブルの名前、およびその変更の日付を
schema_tables
、再ソートし、
schema_tables
プレートの
schema_tables
が
schema_tables
。
最後のパート:
# configs - tables join schema_configs schema_tables | awk '{print $2 " " $3 " " $4}' | ... ... | sort -k 1b,1 | uniq > config_tables # reports - tables hive dates join config_reports config_tables | awk '{print $2"#"$3 " " $4}' | ... ... | sort -k 1b,1 > report_table_hive_dates # final! join report_table_date report_table_hive_dates | sed 's/#/ /g' | ... ... | awk '{if ($3<$4) print $1}' | sort | uniq > outdated_reports
最初に、
schema_configs
と
schema_tables
をdbという名前のフィールドで結合すると、
config_tables
プレートが取得されます
config_tables
、table、および最後に変更された日付です。 次に、
config_reports
と
config_tables
を
config_tables
して、最終的に一致するレポート(Hiveのテーブル)を取得します。 さらに、レポートを含むファイルの名前とテーブル名は、
#
を使用して1つのフィールドに結合されます。 最後に、
report_table_date
と
report_table_hive_dates
を結合し、ファイル名をレポートで、テーブル名をスペースで区切り、レポートの作成日がテーブルの変更日よりも小さいレポートを印刷し、一意のレポートを探して作業の準備をします。
おわりに
bashの9つのかなり単純な行は、この問題を解決するのに十分であることが判明しました。 次に、このスクリプトを王冠で実行すると、webmordは、
outdated_reports
"Report is outdated"
ファイルに焦点を合わせて、
"Report is outdated"
outdated_reports
見出しを
outdated_reports
でき
outdated_reports
(またはそうではありません)。
ここにコード