WebHDFSのコマンド(REST API)のメモ。
|
REST APIなので、コマンド(URI)をブラウザーのURL欄に入力したり、wgetやcurlコマンドを使うことで実行する。
$ wget "http://ネームノード:50070/webhdfs/v1〜" $ curl "http://ネームノード:50070/webhdfs/v1〜"
接続先のサーバーはNameNode、ポート番号はHDFSのポート(CDH3のデフォルトなら50070、EMRなら9101)。
(ブラウザーから「/webhdfs/v1」を付けずに「http://ネームノード:50070
」にアクセスするとHDFSの状態を見られる画面が開くが、そのポート番号と同じ)
wgetを使うとファイルが作られる。
URIを元にファイル名が決まるので、ファイル名に「?」や「&」が含まれてしまう。「-O」オプションで出力ファイル名を指定した方が良さそう。
curlだとボディー部のみが画面に出力される。
「-i」オプションを付けるとヘッダー情報も表示される。
また、APIによってはHTTPのGETメソッドでなくPUTやDELETEを使うことがある。curlなら「-X」で指定できる。
URIに「http://ネームノード:50070/webhdfs/v1
」だけ指定すると、以下のようなメッセージが返ってくる。
HTTP/1.1 400 Bad Request Content-Type: application/json Transfer-Encoding: chunked Server: Jetty(6.1.26.cloudera.1) {"RemoteException":{"exception":"UnsupportedOperationException","javaClassName":"java.lang.UnsupportedOperationException","message":"op=NULL is not supported"}}[
WebHDFSのAPIでは「op=命令」でどのような操作をするのか指定する必要がある。
認識できない命令を指定すると、以下のようなエラーになる。
"http://ネームノード:50070/webhdfs/v1?op=gethomedir" ↓ {"RemoteException":{"exception":"IllegalArgumentException","javaClassName":"java.lang.IllegalArgumentException","message":"Invalid value for webhdfs parameter \"op\": No enum const class org.apache.hadoop.hdfs.web.resources.GetOpParam$Op.GETHOMEDIR"}}
APIのコマンド(「op=」で指定するもの)は、大文字でも小文字でも大丈夫なようだ。
コマンドによってはオプション(引数)があるので、WebHDFS REST APIを参照。
コマンドの実行結果はJSON形式で返ってくる。
操作 | HTTP | 例 | 返り値 | hadoop相当 |
---|---|---|---|---|
GETHOMEDIRECTORY ホームディレクトリー取得 |
GET | curl
"http://namenode:50070/webhdfs/v1?op=gethomedirectory&user.name=hishidama" |
{"Path":"/user/hishidama"} |
|
LISTSTATUS ファイル一覧取得 |
GET | curl "http://namenode:50070/webhdfs/v1/user/hishidama?op=liststatus" |
ファイル・ディレクトリー情報の一覧 pathSuffixがファイルやディレクトリー名 |
hadoop fs -ls /user/hishidama |
GETFILESTATUS ファイル情報取得 |
GET | curl "http://namenode:50070/webhdfs/v1/user/hishidama/test.txt?op=getfilestatus" |
ファイル情報 | hadoop fs -ls /user/hishidama/test.txt |
OPEN ファイル読み込み |
GET | curl -i "http://namenode:50070/webhdfs/v1/user/hishidama/test.txt?op=open" |
ファイルの内容 | hadoop fs -cat /user/hishidama/test.txt |
curl -L "http://namenode:50070/webhdfs/v1/user/hishidama/test.txt?op=open" |
||||
CREATE ファイル作成 |
PUT | curl -i -X PUT "http://namenode:50070/webhdfs/v1/user/hishidama/aaa.txt?op=create" |
JSONオブジェクトは無し | hadoop fs -put a.txt /user/hishidama/aaa.txt |
curl -i -X PUT -L "http://namenode:50070/webhdfs/v1/user/hishidama/aaa.txt?op=create"
-T a.txt |
||||
MKDIRS ディレクトリー作成 |
PUT | curl -X PUT "http://namenode:50070/webhdfs/v1/user/hishidama/zzz?op=mkdirs" |
{"boolean":true} ディレクトリーが既存でもtrueが返る |
hadoop fs -mkdir /user/hishidama/zzz |
RENAME 改名 |
PUT | curl -X PUT "http://namenode:50070/webhdfs/v1/user/hishidama/zzz?op=rename&destination=/user/hishidama/zzz2" |
{"boolean":true} 対象が無い場合はfalse |
hadoop fs -mv /user/hishidama/zzz /user/hishidama/zzz2 |
DELETE 削除 |
DELETE | curl -X DELETE "http://namenode:50070/webhdfs/v1/user/hishidama/test.txt?op=delete" |
{"boolean":true} |
hadoop fs -rm /user/hishidama/test.txt |
curl -X DELETE "http://namenode:50070/webhdfs/v1/user/hishidama/zzz2?op=delete&recursive=true" |
{"boolean":true} |
hadoop fs -rmr /user/hishidama/zzz2 |
HttpFSはWebHDFSにAPI(URIの形式)を合わせている。
しかし、URIはほぼそっくり同じだが、実際の動作は異なる部分があるので要注意。
操作 | コマンド(API) | 返り値 | 説明 | |
---|---|---|---|---|
LISTSTATUS ファイル一覧取得 |
WebHDFS | curl "http://namenode:50070/webhdfs/v1/user/hishidama/a.txt?op=liststatus" |
ファイル・ディレクトリー情報の一覧 pathSuffixがファイルやディレクトリー名 |
存在しているファイル名を指定した場合、 HttpFSはpathSuffixにファイル名が入るが、 WebHDFSは空文字列になる。 |
HttpFS | curl "http://namenode:14000/webhdfs/v1/user/hishidama/a.txt?op=liststatus" |
|||
OPEN ファイル読み込み |
WebHDFS | curl -i "http://namenode:50070/webhdfs/v1/user/hishidama/a.txt?op=open" |
HTTP/1.1 307 TEMPORARY_REDIRECT |
WebHDFSでは、NameNodeに対してオープンしたいファイル名を指定すると、DataNodeのURIが返ってくる。 そのURIを再度指定するとファイルの内容が返ってくる。 これはHTTPのリダイレクト処理なので、ブラウザーで1つ目のURIを指定すれば自動的にファイルがダウンロードされる。 |
curl -i
"http://datanode02:50075/webhdfs/v1/user/hishidama/a.txt?op=OPEN&offset=0" |
ファイルの内容 | |||
HttpFS | curl -i "http://namenode:14000/webhdfs/v1/user/hishidama/a.txt?op=open" |
ファイルの内容 | HttpFSでは、最初のURIだけでファイルの内容が返ってくる。 | |
CREATE ファイル作成 |
WebHDFS | curl -i -X PUT "http://namenode:50070/webhdfs/v1/user/hishidama/a.txt?op=create&user.name=hishidama" |
HTTP/1.1 307 TEMPORARY_REDIRECT |
WebHDFSでは、NameNodeに対して作成したいファイル名を指定すると、DataNodeのURIが返ってくる。 そのURIを(転送したいファイル名と共に)再度指定するとデータが転送される。 HDFS上で2ブロック以上になる大きなファイルでも、リダイレクトは1回しか必要ないようだ。 「user.name」で指定したユーザー名がHDFS上のファイルのオーナーとなる。 指定しないと「webuser」になる。 |
curl -i -X PUT
"http://datanode02:50075/webhdfs/v1/user/hishidama/a.txt?op=CREATE&user.name=hishidama&overwrite=false"
-T a.txt |
HTTP/1.1 100 Continue |
|||
HttpFS | curl -i -X PUT "http://namenode:14000/webhdfs/v1/user/hishidama/a.txt?op=create&user.name=hishidama" |
HTTP/1.1 307 Temporary Redirect |
HttpFSでもHttpFSサーバー(今回はNameNodeと同一)に対して作成したいファイル名を指定するとURIが返ってくるのだが、DataNodeではなく、HttpFSサーバーのまま。ただし末尾に「data=true」が付いている。 このURIと共にファイル名を指定するとデータが転送される。 (最初から「data=true」を付けていれば、1回の呼び出しでファイルが作成できるようだ) また、HTTPヘッダーでcontent-typeを明示しないとエラーになる。 |
|
curl -i -X PUT "http://namenode:14000/webhdfs/v1/user/hishidama/a.txt?op=CREATE&user.name=hishidama&data=true"
-T a.txt --header "content-type: application/octet-stream" |
HTTP/1.1 100 Continue |
|||
RENAME 改名 |
WebHDFS | curl -i -X PUT "http://namenode:50070/webhdfs/v1/user/hishidama/z1?op=rename&destination=x1" |
HTTP/1.1 400 Bad Request |
destination(移動先名)に相対パスを指定するとエラーになるのだが、 WebHDFSでは400 Bad Requestでエラーメッセージが返るが、 HttpFSでは200 OKでfalseが返る。 |
HttpFS | curl -i -X PUT "http://namenode:14000/webhdfs/v1/user/hishidama/z2?op=rename&destination=x2" |
HTTP/1.1 200 OK |
||
DELETE 削除 |
WebHDFS | curl -i -X DELETE "http://namenode:50070/webhdfs/v1/user/hishidama/x1?op=delete" |
HTTP/1.1 403 Forbidden |
空でないディレクトリーをrecursive=trueの指定無しで削除しようとするとエラーになるのだが、 WebHDFSは403 Forbiddenで、 HttpFSは500 Internal Server Errorになる。 HttpFSは単なるプロキシーなので、HDFS側で例外が発生したら(RemoteExceptionを受け取ったら)内部エラーとするしかない、ということか? |
HttpFS | curl -i -X DELETE "http://namenode:14000/webhdfs/v1/user/hishidama/x2?op=delete" |
HTTP/1.1 500 Internal Server Error |
WebHDFSを試すにはcurlコマンドが便利。[2012-10-11]
「-X」でHTTPメソッドを指定できる。
WebHDFSのREST APIではHTTPメソッドのGET以外をよく使用する。
「-i」でHTTPレスポンスのヘッダー部およびボディー部の内容を表示する。
「-I」だとヘッダー部のみ表示する。
ヘッダーの情報表示は、HTTPレスポンスの内容を(改行コードまで含めて)そのまま出しているような気がする。
HTTPでは改行はCRLF(0d0a)なので、UNIXではLF(0a)のみだから、場合によってはCR(0d)が悪さをするので要注意。
(例えばリダイレクト先のURIは「Location:」の行で分かるが、行末はCRLFになっているので、シェルのパイプとかでそのまま次のcurlコマンドの引数にしたりすると、CRが残っていて存在しないURIを指している状態になってしまう!)
「-o」で出力ファイル名を指定できる。
WebHDFSのOPENやCREATEではリダイレクト先URIが返ってくるが、「-L」を付けておけば自動的にリダイレクトしてくれる。
curl -i -X PUT -L "http://namenode:50070/webhdfs/v1/user/hishidama/aaa.txt?op=create"
-T a.txt