WebHDFSを使ってみる

2012-11-22T00:00:00+00:00 Hadoop

WebHDFS Rest APIを使えばHDFS操作をRESTサービスベースでHTTPリクエストをぶん投げる事で出来るようになった模様。ちょっと興味あったので使ってみた

(Hadoopのバージョンは1.0.4です)

セットアップ

デフォルトでWebHDFSはサポートしてないので設定しないと使えない模様。なのでhdfs-site.xmlに追加する

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- 追加 -->
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>
</configuration>

設定はこんだけです。あとは

sudo -u hadoop /opt/hadoop/bin/hadoop namenode -format
sudo -u hadoop /opt/hadoop/bin/hadoop-daemon.sh start namenode
sudo -u hadoop /opt/hadoop/bin/hadoop-daemon.sh start datanode

でデータノードが立ち上がったら、初期時は何も無いのでユーザーディレクトリを作っておく。でユーザーディレクトリな所の所有者権限とかも直しておく。それは昨日の記事で書いたので省略

WebHDFS Rest APIを使って操作する

WebHDFS Rest APIのエントリーポイントとなるURLのベースが、「 http://host:port/webhdfs/v1 」になる。でポートっていうのはネームノードフロントエンドページとなる、恐らくはデフォルトでは50070のポート番号になる。そこにリクエストをぶっ飛ばす

ユーザーディレクトリ内にdataディレクトリを作る

curl -i -X PUT "http://localhost:50070/webhdfs/v1/user/kinjouj/data?op=mkdirs&user.name=kinjouj"

user.nameっていうのは指定しない場合はデフォルトの「webuser」っていうのが使用されるので、所有者関係上がある場合には指定しておく。この場合は自分のkinjoujアカウント。レスポンスが

{"boolean": true}

な感じでJSONで返ってくる

作ったディレクトリのステータスを見る

curl -i "http://localhost:50070/webhdfs/v1/user/kinjouj/data?op=GETFILESTATUS"

結果として

{
  "FileStatus": {
    "accessTime":0,
    "blockSize":0,
    "group":"kinjouj",
    "length":0,
    "modificationTime":1353549518275,
    "owner":"kinjouj",
    "pathSuffix":"",
    "permission":"755",
    "replication":0,
    "type":"DIRECTORY"
  }
}

なレスポンスが返ってくる

ディレクトリにファイルを突っ込んでみる

curl -i -X PUT "http://localhost:50075/webhdfs/v1/user/kinjouj/data/accesslog.txt?op=create&user.name=kinjouj" -T accesslog.json

ここポートが50075ってなってるのが50070で投げると50075に要求しろみたいにHTTP/307が出る。まぁ実際はそのLocationヘッダーに投げれば良い

ディレクトリにあるファイルステータスを取る

curl -i "http://localhost:50070/webhdfs/v1/user/kinjouj/data?op=liststatus"

レスポンスとして

{
  "FileStatuses":{
    "FileStatus":[
      {
        "accessTime":1353550656744,
        "blockSize":67108864,
        "group":"kinjouj",
        "length":175,
        "modificationTime":1353550656744,
        "owner":"kinjouj",
        "pathSuffix":"accesslog.txt",
        "permission":"644",
        "replication":1,
        "type":"FILE"
      },
      {
        "accessTime":0,
        "blockSize":0,
        "group":"kinjouj",
        "length":0,
        "modificationTime":1353551184724,
        "owner":"kinjouj",
        "pathSuffix":"test",
        "permission":"755",
        "replication":0,
        "type":"DIRECTORY"
      }
    ]
  }
}

な感じで返ってくるくる。そこに更にディレクトリがあったらどうなるのかの検証のためにテストなディレクトリを作ってる

ファイルを読み取る

curl -i "http://localhost:50075/webhdfs/v1/user/kinjouj/data/accesslog.txt?op=open"

こちらも50070なNamenodeな所のポートにぶん投げるとDatanode側にアクセスしろっと要求される。ちょっと気になるのがブロックサイズでチャンクされてるファイルとかどうなるんだっけと。ビッグデータが無いんでそこ未確認

ファイル等を消す

curl -i -X DELETE "http://localhost:50070/webhdfs/v1/user/kinjouj/data/test?op=delete&user.name=kinjouj"

な感じでファイル・ディレクトリ等を削除可能

という感じでHTTPリクエストぶん投げるだけでHDFS操作が出来る模様。まぁ詳しい事は http://hadoop.apache.org/docs/r1.1.0/webhdfs.html 見た方が良いかも

ちなみにPerlでWebHDFSを利用する場合にNet::Hadoop::WebHDFSっていうモジュールがある模様

追記1

appendサポートをするにはhdfs-site.xmlに設定が必要な模様

<property>
  <name>dfs.support.append</name>
  <value>true</value>
</property>

追記2 fluent-plugin-webhdfsでログをWebHDFSに飛ばす

<source>
    type tail
    format apache
    path /var/log/nginx/access.log
    pos_file /var/log/td-agent/nginx.pos
    tag accesslog.output
</source>

<match accesslog.output>
    type webhdfs
    host localhost
    port 50070
    path /user/kinjouj/%Y%m%d-accesslog.txt
    username kinjouj
    flush_interval 1s
</match>

FuelPHPをやってみる (18) - タスクを使う - Eclipse BIRTを使ってみる (5) - Excelで出力 -