hadoop fs
HDFSの照会にかかる遅い起動時間に疲れました。ただし、Pig "grunt shell"でHDFSファイルシステムコマンドを使用することは非常に高速であるため、HDFS自体には問題ありません。しかし、いくつかのHDFSコマンドを実行したい場合は、常にグラントシェルを起動することは非現実的です。だから私はバックグラウンドでグラントシェルインスタンスを起動し、その後の呼び出しのために開いたままにするために次のスクリプトを書いた。
#!/bin/bash
in=/tmp/grunt_in
out=/tmp/grunt_out
err=/tmp/grunt_err
if [ ! -p $in ]
then
mkfifo $in
mkfifo $out
( pig <>$in >$out 2>$err; rm $in $out ) &
disown
fi
>$err # Truncate errors
echo "fs $*" >$in
echo >$in
echo "-- end" >$in
sed -n '/^grunt> -- end/q;/^grunt>/d;p' $out
cat $err >&2
もちろん、入力をスクリプトに送信するだけでなく、スクリプトの出力も現在のbashセッションにリダイレクトする必要があります。私はこれを達成するためにここでFIFOを/tmp/grunt_in
使用しています/tmp/grunt_out
。pig
コマンドをいつ処理するかを知るために、コメントを送信し、出力を受け取るコマンドでそれを検出してトークンに遭遇した"-- end"
ときsed
に終了し、end
すべてのプロンプトをスキップして関連部分のみを出力しますgrunt>
。
<>$in
出力をリダイレクトしても、$out
最初のコマンド以降にPigが終了するのを防ぐために、入力FIFOを追加する必要があります。正確な理由はわかりませんが、こうなると思います。
これは実際にはかなりうまく機能します。例えば
$ time hadoop fs -ls
Found 38 items
[ skipped output ]
real 0m1.828s
user 0m3.160s
sys 0m0.137s
$ time dfs -ls
[apollo@dc1-had03-clusterutil01 reporting-APO-5394]$ time dfs -ls
Found 38 items
[ skipped output ]
real 0m0.149s
user 0m0.003s
sys 0m0.006s
(ここでスクリプトを呼び出しますdfs
。)現在、解決できない問題は2つだけです。
- 初めてスクリプトを呼び出すと(つまり、
/tmp/grunt_in
fifoがまだ存在せず、pigインスタンスがバックグラウンドで起動された場合)、ターミナル設定はとても混乱します。これ以上入力エコーが発生しなくなるため、reset
通常の端末に戻るには盲目的に入力する必要があります。しかし、その後の呼び出しはうまく機能します。 HDFSからファイルの内容を出力しようとすると、出力はランダムに切り捨てられます
-cat
。-text
たとえば、$ hadoop fs -text some-medium-size.gz|wc -l 3606 $ dfs -text some-medium-size.gz|wc -l text: Unable to write to output stream. 9
ここでエラーメッセージを確認してください。から来たのではなく、のコマンドから来たの
text: Unable to write to output stream.
です。ここのように、最初の9〜10行が切れる場合もあり、中間部分が切られる場合もあります。これはとても奇妙です。また、手動でにコマンドを送信してから読み込もうとしましたが、同じ結果が得られましたが、ここではとして解析することは問題ではないことを確認しました。一般的にこれは大きな出力にも問題にならないようです。たとえば、長いディレクトリリストの場合はうまく機能します。pig
fs -text
hadoop
/tmp/grunt_in
/tmp/grunt_out
cat
sed
$ dfs -ls -R|wc -l 10686
(これはと同じ結果を提供しますhadoop fs -ls -R|wc -l
)
hadoop fs -text
たぶん最後の問題はand自体の問題ですかhadoop fs -cat
?それとも名前付きパイプの使用に問題がありますか?
答え1
今、このバージョンはそれほど明確ではありません。
#!/bin/bash
in=/tmp/grunt_in
out=/tmp/grunt_out
err=/tmp/grunt_err
if [ ! -p $in ]
then
mkfifo $in
mkfifo $out
mkfifo $err
{ script -q -c "pig 1>$out 2>$err" <>$in; rm $in $out $err; } &
fi
{
echo "fs $*"
echo
echo "-- end"
} >$in
cat $err >&2 &
catpid=$!
sed -n -u '/^grunt> -- end/q;/^grunt>/d;p' <$out
kill $catpid
だから私はコマンドの中からstderrをリダイレクトしましたscript
。また、かっこを中かっこに変えて、disown
そうしても何のメリットもないので削除しました。$err
早期に出力できるようにFIFOに交換したりしましたが、これによりキルも追加されましたcat
。
これまではそのようにうまくいった。とは別にパイプを介して出力を切り捨てると、head
次のコマンドで切り捨てられるか、追加の出力が表示されます。明らかに名前付きパイプを適切にフラッシュする方法が必要です。誰でもアドバイスがあれば嬉しいです。