以下に示すようなデータを含む区切り(|)入力ファイル(TableInfo.txt)があります
dbName1|Table1
dbName1|Table2
dbName2|Table3
dbName2|Table4
...
各行を解析し、dbName、TableNameなどの行から引数を渡す実行可能ファイルを呼び出すシェルスクリプト(LoadTables.sh)があります。このプロセスは、SQL Serverからデータを読み取り、それをHDFSにロードします。
while IFS= read -r line;do
fields=($(printf "%s" "$line"|cut -d'|' --output-delimiter=' ' -f1-))
query=$(< ../sqoop/"${fields[1]}".sql)
sh ../ProcessName "${fields[0]}" "${fields[1]}" "$query"
done < ../TableInfo.txt
現在、私のプロセスはファイル内の各行に対して順番に実行されており、ファイル内のエントリ数に基づいて時間がかかります。
プロセスを並行して実行する方法はありますか?xargs / GNU parallel / ampersandおよびwaitオプションの使用について聞いたことがあります。私はそれを構築して使用する方法に精通していません。どんな助けでも大歓迎です。
注:LinuxマシンにGNUパラレルをインストールしていません。したがって、アンパサンドと待機オプションの使用に関するいくつかの短所を聞いたので、xargsが唯一のオプションです。
&
背景に移動したい行の終わりにを置きます。コードで使用されているばかげた(バギー)配列分割メソッドをread
独自のフィールド分割に置き換えると、次のようになります。
while IFS='|' read -r db table; do
../ProcessName "$db" "$table" "$(<"../sqoop/${table}.sql")" &
done < ../TableInfo.txt
... FYI、re:「バギー」について私が意味したこと-
fields=( $(foo) )
...文字列分割だけでなく、foo
;の出力でグロブも実行します。したがって、*
出力のaは、現在のディレクトリ内のファイル名のリストに置き換えられます。このような名前は、foo[bar]
名前のファイルに置き換えることができfoob
、fooa
またはfoor
、globfail
シェルのオプションが失敗した結果に、このような拡張を引き起こす可能性があり、nullglob
それが空の結果につながる可能性がありますシェルオプション。等
GNU xargsがある場合は、次のことを考慮してください。
# assuming you have "nproc" to get the number of CPUs; otherwise, hardcode
xargs -P "$(nproc)" -d $'\n' -n 1 bash -c '
db=${1%|*}; table=${1##*|}
query=$(<"../sqoop/${table}.sql")
exec ../ProcessName "$db" "$table" "$query"
' _ < ../TableInfo.txt
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加