Category Archives: hadoop

[メモ] FreeBSD10にhadoopインストール

Pocket

素の状態のFreeBSD 10にpkgngでhadoopをインストールしたときのメモ。

2014/7/4時点でのpkgにはhadoop-1.2.1が入ってる。

pkgのインストール

pkgの初回インストールに成功した試しがない。
pkgのpackageをダウンロードしてインストール。
具体的には、pkg-staticを取り出し、pkg-staticでpkgのpackageをインストール。

$ fetch http://pkg0.isc.freebsd.org/freebsd:10:x86:64/latest/Latest/pkg.txz
pkg.txz                                       100% of 2013 kB  552 kBps 00m03s
$
$  tar xvzf ./pkg.txz --include "*pkg-static" --strip-components 4
x pkg-static
$
(rootになって)
# ./bin/pkg-static add ./pkg.txz
Installing pkg-1.2.7_3... done
If you are upgrading from the old package format, first run:

  # pkg2ng
root@hdmock:/home/doe # 

pkg update。

# pkg update
Updating repository catalogue
digests.txz                         100% 1112KB 556.1KB/s 192.2KB/s   00:02
packagesite.txz                     100% 5014KB 626.7KB/s 373.9KB/s   00:08
Incremental update completed, 23278 packages processed:
0 packages updated, 0 removed and 23278 added.
# 

シェルとか、sudoとか、必要なものがあればインストールする。

hadoopのインストール

$ pkg search hadoop
apache-hadoop-1.2.1_1
$ sudo pkg install hadoop
Updating repository catalogue
pkg: No packages matching 'hadoop' available in the repositories
[doe@hdmock ~]$ sudo pkg install apache-hadoop
Updating repository catalogue
The following 39 packages will be installed:
(中略)
[39/39] Installing apache-hadoop-1.2.1_1...===> Creating users and/or groups.
Creating group 'hadoop' with gid '955'.
Creating user 'hadoop' with uid '955'.
 done

OpenJDKのための設定

hadoopについてくるOpenJDKのためにfstabに設定を加える。
OpenJDKインストール時のメッセージに沿って進める。

======================================================================

This OpenJDK implementation requires fdescfs(5) mounted on /dev/fd and
procfs(5) mounted on /proc.

If you have not done it yet, please do the following:

        mount -t fdescfs fdesc /dev/fd
        mount -t procfs proc /proc

To make it permanent, you need the following lines in /etc/fstab:

        fdesc   /dev/fd         fdescfs         rw      0       0
        proc    /proc           procfs          rw      0       0

=====================================================================

fstabに以下に行を追加。区切りはtab。

fdesc           /dev/fd         fdescfs rw      0       0
proc            /proc           procfs  rw      0       0

mount。
mountと叩いてmountされていることを確認。

$ sudo mount -a
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
fdescfs on /dev/fd (fdescfs)
procfs on /proc (procfs, local)

以上。
続きはこちら

Hadoopフレンドリーなデータとは

Pocket

 

ログは1行1イベントに

何を言っとるんだお前はという感じであるが、つまりこういう事である。

通常、ログは1行が1イベントである。
たとえばapacheのログやらなにやら、みんなそうである。
少なくともUNIX系のシステムであれば、これは常識である。
しかし、この世の中、UNIX系の常識が通用しないログだって山ほどあるのである。

1イベントが複数行にわたるログがなぜいけないか。

たとえば以下の様な擬似ログを考えてみよう。

まったく関係のない話だが、以下のデータは手元にあるLIFEのノートから適当にでっち上げた。
冒頭にタイムスタンプがあり、イベントの内容が記される、典型的なログである。

2013/12/16 17:55:05.6582 N28 [499016804864] Noble note section B6 5m/m

しかしこれが、以下のように複数行にわたって記録(あるいは表示)される、こういうログを相手にすることだってあるのだ。

2013/12/16 17:55:05.6582 N28
4990 1680
4864
Noble note section
B6 5m/m

 

これは主に可読性を意識したせいであろうが、こういったログをHadoopで扱うのは難しい。

Hadoopのデータの扱い方

というのも、Hadoopは分散処理のためにログを分割するからだ(デフォルトでは64MBごと)。

しかもその分割は、単純にサイズのみで判断され、文脈は考慮されない。
上のログで言えば、Nobleの手前で切られてしまってログとして意味がなくなってしまうことだってある。

これを避けるには、Hadoopにファイルそのものではなくて、ファイルリストを与える手があるけれども、それではHadoopの長所を活かせない。
ファイルリストは綺麗に分割されるけど、ファイルの大きさはまちまちだから。

ログの整形

というわけで、こういったログを扱う前に、下準備として1行1イベントにまとめてしまおう。

まとめ自体もHadoopで処理してしまえば楽である。
Hadoopの象本Appendix Cに良い例があるのでこれを使う。
ここでfiles.txtは処理するログファイルをリストしたものとする。
また、concat.shは1行1イベントにまとめるスクリプトとする。

$ hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar \
-D mapred.reduce.tasks=0 \
-D mapred.map.tasks.speculative.execution=false \
-D mapred.task.timeout=12000000 \
-input files.txt \
-inputformat org.apache.hadoop.mapred.lib.NLineInputFormat \
-output output \
-mapper concat.sh \
-file concat.sh

 

reduceは必要ないのでmapred.reduce.tasks=0。
重複して書き込んでほしくないのでmapred.map.tasks.speculative.execution=false。
タイムアウトは長めに。
mapが一回に処理するファイルはひとつにしたいので、-inputformat org.apache.hadoop.mapred.lib.NLineInputFormat 。

以上

hadoopのsafemodeとfsck

Pocket

 

Hadoopのnamenode兼datanodeが電源瞬断のせいで壊れてしもうた。
勉強用のHadoopなのでダメージはないのだが、せっかくなのでfsckなどを試した結果を記す。
hadoop-1.0.0。
OS側でもfsckはしておいた。

サマリ

  • HDFSにもfsckがある。
  • hadoop fsckでチェック、修正できる。
  • hadoop fsckと叩けば使い方の簡単な説明が表示される。
  • namenodeがsafemodeのためにHDFSが読み取り専用になっていることがある。
  • 読み取り専用ではfsckで修正できないので、safemodeから出る必要がある。

 

HDFSでのfsck

hadoop fsck <path>と指定すればよい。
CORRUPT!とのことで、壊れておりますなあ。

$ hadoop fsck /
FSCK started by hadoop from /172.29.17.159 for path / at Wed Dec 25 18:51:37 JST 2013
(略)
/var/hadoop/mapred/system/jobtracker.info: MISSING 1 blocks of total size 4 B.Status: CORRUPT
Total size: 45638364128 B
Total dirs: 5321
Total files: 13059
Total blocks (validated): 9819 (avg. block size 4647964 B)
********************************
CORRUPT FILES: 2470
MISSING BLOCKS: 2498
MISSING SIZE: 15590981155 B
CORRUPT BLOCKS: 2498
********************************
Minimally replicated blocks: 7321 (74.559525 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 7321 (74.559525 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 2
Average block replication: 0.7455953
Corrupt blocks: 2498
Missing replicas: 7321 (100.0 %)
Number of data-nodes: 1
Number of racks: 1
FSCK ended at Wed Dec 25 18:51:38 JST 2013 in 1185 milliseconds

The filesystem under path '/' is CORRUPT

 

壊れている場合の対処:消去か移動

壊れている場合には対処が二つ。
壊れているブロックを消すか、lost+foundに移すか。
消す場合には-delete, 移す場合には-moveを指定する。
以下は消した場合の例….なのだが、namenodeがsafemodeにいるので変更が出来ないとのこと。

$ hadoop fsck / -delete
FSCK started by hadoop from /172.29.17.159 for path / at Wed Dec 25 18:58:29 JST 2013
.
/tmp/hadoop-hadoop/mapred/staging/hadoop/.staging/job_201308300823_0001/job.jar: CORRUPT block blk_3947350403157044322

/tmp/hadoop-hadoop/mapred/staging/hadoop/.staging/job_201308300823_0001/job.jar: MISSING 1 blocks of total size 66249 B.FSCK ended at Wed Dec 25 08:58:29 JST 2013 in 5 milliseconds
Cannot delete /tmp/hadoop-hadoop/mapred/staging/hadoop/.staging/job_201308300823_0001/job.jar. Name node is in safe mode.
The ratio of reported blocks 0.7456 has not reached the threshold 0.9990. Safe mode will be turned off automatically.

Fsck on path '/' FAILED

 

safemodeとは

そもそもnameodeは通常の動作として、起動時には状態がsafemodeである。
safenodeのまま待機をしているうちに、datanodeが起動し、保管しているブロックの報告をnamenodeに行う。
namenodeは、充分なブロックの確認ができれば自動的にsafemodeを出る。
「充分なブロック」がどれくらいか、は設定できる。

safemodeのときは読み取り専用になり、複製や消去もできないが、手動でsafemodeに入ったり出たりすることができる。

以下、公式からの引用

Safe mode is entered automatically at Namenode startup, and leaves safe mode automatically when the configured minimum percentage of blocks satisfies the minimum replication condition. Safe mode can also be entered manually, but then it can only be turned off manually as well.
Safe mode maintenance command. Safe mode is a Namenode state in which it
1. does not accept changes to the name space (read-only)
2. does not replicate or delete blocks.

今回、問題の発生したnamenodeはdatanodeも兼ねている。
電源瞬断でブロックが壊れているからブロックの報告はできないし、そもそもnamenodeが保管しているメタデータも壊れている。
ボロボロである。
したがって、いつまで待ってもsafemodeから出るはずがない。
そこで手動でsafemodeを解除する。

safemodeの操作

safemodeの操作はhadoop dfsadmin -safemodeに続けて行う。
getで状態を得る。
enterでsafemodeに入る。
leaveでsafemodeから出る。
面白いのは、wait。
safemodeから出たらコマンド実行する、というもの。

# 状態を得る。
$ hadoop dfsadmin -safemode get

# 終わってからコマンド実行
$ hadoop dfsadmin -safemode wait

# safemodeに入る。
$ hadoop dfsadmin -safemode enter

# safemodeから出る。
$ hadoop dfsadmin -safemode leave

以下、実際の例。
safe modeがONになっているので、OFFに。

$ hadoop dfsadmin -safemode get
Safe mode is ON

$ hadoop dfsadmin -safemode leave
Safe mode is OFF

改めてfsck / -delete
blockが2000個くらい消えた。ま、まあ勉強用だし(震え声)

$ hadoop fsck / -delete
FSCK started by hadoop from /172.29.17.159 for path / at Wed Dec 25 19:05:54 JST 2013
(略)
.......Status: HEALTHY
Total size: 29928657533 B
Total dirs: 5321
Total files: 10589
Total blocks (validated): 7319 (avg. block size 4089173 B)
Minimally replicated blocks: 7319 (100.0 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 7319 (100.0 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 2
Average block replication: 1.0
Corrupt blocks: 0
Missing replicas: 7319 (100.0 %)
Number of data-nodes: 1
Number of racks: 1
FSCK ended at Wed Dec 25 19:05:55 JST 2013 in 1696 milliseconds

The filesystem under path '/' is HEALTHY

HEALTYになったので、これでhadoopが使える状態に戻った。
以上。

Hadoopのインプット指定にワイルドカードが使える件について

Pocket

 

Hadoopへのインプットはふつう、ディレクトリかファイルの指定で行う。

しかし以下のような場合にどうするか。

  • 複数のディレクトリの下にあるファイルをhadoopに処理させたいとき。
  • 特定拡張子のファイルのみをhadoopに処理させたいとき。

実はワイルドカードが使えるので、それで解決。
以下、hadoop-1.0.0で確認。

ケース1:複数ディレクトリの下に処理対象ファイルがある場合。

 

top-+-dir1-file1
    |     -file2
    |     -file3
    |
    +-dir2-file4
          -file5
          -file6

以上のような状態でhadoopへのinputにtopを指定すると、hadoopはdir1をファイルとして処理しようとし、失敗する。
たとえばこのように。

13/11/13 22:26:03 ERROR security.UserGroupInformation: PriviledgedActionException as:hadoop cause:java.io.IOException: Not a file: hdfs://namenode/user/hadoop/top/dir1
13/11/13 22:26:03 ERROR streaming.StreamJob: Error Launching job : Not a file:
hdfs://namenode/user/hadoop/top/dir1
Streaming Job Failed!

このような場合には、top/*と指定してあげればよい。
たとえばこのように。

$ hadoop jar ${HADOOP_PREFIX}/contrib/streaming/hadoop-streaming-1.0.0.jar \
-D mapred.reduce.tasks=0 \
-input top/*  \
-output sampleoutput \
-mapper /home/hadoop/map.py \
-file /home/hadoop/map.py

 

ケース2:特定のファイルのみ処理したい場合

たとえば以下のdir3で.txtのみを処理したい場合。

-dir3-file1.txt
     -file2.bin
     -file3.txt

-input dir3/*.txtとすればよい。

 

ケース3:ケース1/2の複合ケース

 

top-+-dir4-file1.txt
    |     -file2.bin
    |     -file3.txt
    |
    +-dir5-file4.txt
          -file5.bin
          -file6.txt

 

合わせ技でtop/*/*.txtと指定すればよい。

No tags for this post.

[Hadoop] 擬似分散モードから完全分散モードへ(データノードの追加)

Pocket

Hadoopへのノードの追加

hadoopの長所は、処理量に応じて簡単にスケールできる点にある。
処理がおっつかなくなってきたら、データノードを追加するだけ。
擬似分散モードから完全分散モードへの移行は、データノードの追加と同じ。
もう少し詳しく言うと、最初の1台をnamenode/jobtrackerのままにして、datanode/tasktrackerを追加する。
※FreeBSDで、hadoop-1.0.0です。

背景

namenode, datanodeはHDFSのノード種別を表し、namenodeはファイルのメタデータを扱い、datanodeは実データを扱う。
namenodeはhadoopクラスタに原則1台。datanodeは1台以上必要。

jobtracker, tasktrackerはMapReduceでのノード種別を表し、jobtrackerは作業の分担を、tasktrackerは作業の実施を行う。
jobtrackerはhadoopクラスタに原則1台。tasktrackerは1台以上必要。

hadoopクラスタに参加しているノードは、4つの役割のいずれかを担う。複数の役割をこなすのも可。
ただしdatanodeとtasktrackerは必ずセット。
イメージを示す。

hadoopmode

 

設定ファイル

再掲になるが。

どのノードがnamenodeかを指定するのは、core-site.xml 。
どのノードがjobtrackerかを指定するのは、mapred-site.xml 。
どのノードがdatanode/tasktrackerかを指定するのは、slaves 。

擬似分散モードでは、以上3つのファイルに1ノードしか書かれていなかった。

ノードを追加するなら、slavesにdatanode/tasktrackerを追記すればよい。
擬似分散モードの状態からjobtrackerを分離するには、mapred-site.xmlを書き換えればよい。
擬似分散モードの状態からnamenodeを分離するには、core-site.xmlを書き換えればよいけど、HDFS上にすでにファイルを置いている状態でそんなことするとファイルが吹き飛ぶので止めよう。

そしてこれら設定ファイルは、クラスタ内のノードで同じものを使う。

作業の流れ。

datanode/tasktrackerを追加してみる。

擬似分散モードを仮想マシンで動かしている場合には、それをまるまるコピーしてしまえばよい。
私の場合は、ESXi上でHadoop環境を作ったので、それをコピーし、別マシンのESXiに移し替えた。
もちろんホスト名は別のものにする。

ESXiなどを挟まない場合にはもう一度セットアップ。
ほんとに面倒くさいので、chefやらpuppetなどを使うことになるでしょう。

なお、ESXiは使わない方がパフォーマンスは良い。これは当たり前。

追加ノードの注意点

便宜上、擬似分散モードを動かしたノードをoriginal、追加するノードをaddとする。
addを追加するときの注意点は以下の通り。

/etc/hostsの設定。

original, addの/etc/hostsには、original, addの名前解決ができるようにしておくこと。

時刻同期

original, addで時刻を合わせておくこと。

slavesへの追記

original, addそれぞれでslavesにaddと追記しておく。

SSHログインの確認

originalからaddへsshログインできることを確認しておく。
datanode/jobtrackerの制御はsshでされるため。

replication数の変更

HDFS上でデータのコピーをどれだけ作成するかの設定。
擬似分散ではreplicationを1にしていた。
せっかくなのでこれを2に変更する。
デフォルトは3。
datanodeをさらに増やしたなら、ここの上限をとりあえず3として増やそう。

ノード追加の反映

ノードの追加が初めてならstop-all.shで止めて、start-all.shでまるまる再起動するのがいいでしょう。

当然ながら、hadoop上で何かしらの作業が動いていたらやり直しになってしまう。
通常は、namenodeでhadoop dfsadmin -refreshNodesを実行。
さらにhadoop dfsadmin -reportで確認する。

[hadoop@vfbsd ~]$ hadoop dfsadmin -refreshNodes
[hadoop@vfbsd ~]$ hadoop dfsadmin -report
Configured Capacity: 96683511808 (90.04 GB)
Present Capacity: 57517137920 (53.57 GB)
DFS Remaining: 28587847680 (26.62 GB)
DFS Used: 28929290240 (26.94 GB)
DFS Used%: 50.3%
Under replicated blocks: 5
Blocks with corrupt replicas: 0
Missing blocks: 0

-------------------------------------------------
Datanodes available: 2 (2 total, 0 dead)

Name: 192.168.200.1:50010
Decommission Status : Normal
Configured Capacity: 65501978624 (61 GB)
DFS Used: 28920520704 (26.93 GB)
Non DFS Used: 35444080640 (33.01 GB)
DFS Remaining: 1137377280(1.06 GB)
DFS Used%: 44.15%
DFS Remaining%: 1.74%
Last contact: Mon Aug 12 22:19:15 JST 2013

Name: 192.168.200.100:50010
Decommission Status : Normal
Configured Capacity: 31181533184 (29.04 GB)
DFS Used: 8769536 (8.36 MB)
Non DFS Used: 3722293248 (3.47 GB)
DFS Remaining: 27450470400(25.57 GB)
DFS Used%: 0.03%
DFS Remaining%: 88.03%
Last contact: Mon Aug 12 22:19:17 JST 2013

 

上記の例で言えば、192.168.200.100が追加したdatanode。
使用量がまだ8MBしかないことが分かるだろうか。
replication数を2にしたので、ゆくゆくは192.168.200.1と同じ程度の使用量になるはず。
しばらく放置が必要。
(いま気がついたけど、”Under replicated blocks”、つまり所定のreplicationに満たないblockの数が5…)

擬似分散→擬似分散+1の効果

効果は劇的。
もともと2時間半かかっていたものが1時間半に短縮できた。
下記はtimeの結果。上が擬似分散、下が擬似分散+1。

real    147m34.258s
user    0m6.835s
sys     0m2.233s

real    82m59.557s
user    0m5.624s
sys     0m1.604s

ああもっとdatanode増やしたい。

関連エントリ

[FreeBSD] Hadoopのportsからのインストール
[FreeBSD] portsのHadoopで分散(x-distributed)モードを動かす準備
[Hadoop]Hadoop 擬似分散(Psuedo-distributed)モードの設定
[Hadoop]擬似分散モードで実験

No tags for this post.

[hadoop] hadoop streamingでファイルを分割させないためには。

Pocket

※hadoop-1.0.0です。

hadoop streamingで困ること。

作業データ(たとえばログ)を与えると、Hadoopはまず分割をする。
分割されたものはinput splits, あるいは単にsplitsと呼ばれる。
splitsのサイズはデフォルトで64MBytesだ。
Hadoop(JobTracker)は作業ノード(TaskTracker)にsplitsを割り当てる。
作業ノードはsplitsに対してmapタスクを行う。

なお、作業ノードの割り当てにあたっては、splitsの物理的な場所との近さも考慮される。
要するにsplitsの実データが置かれている作業ノードが選ばれる。

これは素晴らしい仕組みなのだが、困ることもある。
例えば以下のような場合。

 

  • ファイルの冒頭にあるヘッダが処理に必要な場合。
    →分割されると、ヘッダのないsplitsが出来てしまう。
  • ログ上の2点間の時間差分を知りたい場合。
    →2点の間で分割されると計算できない。

回避策

下記の通り。

How do I process files, one per map?

つまり、hadoopへの入力に、いきなり「ファイルの内容」を送り込むのではなく、「ファイルのリスト」を渡す。
ファイルのリストだから、いくら分割してもファイル自体は分割されない。
なるほど。

 

回避策とはいっても。

しかし、この場合mapper側に工夫が必要になる。

通常であれば、標準入力からファイルの中身がドバドバやってくる。
PythonだろうとRubyだろうとstdinをforループで読むだけ。
楽ちん。

ところがこの回避策だと、ファイルリストが入力されるわけだから、ファイルを開くことから始めなければならない。
そしてファイルを開くには、mapperスクリプト内で「hadoop dfs -cat <ファイル>」しないといけない
(ファイルがHDFSにあるとして)。

それも面倒だし、加えて、無駄な通信が発生する可能性がある点も懸念。

先述の通り、Hadoopは作業の振り分けにあたって、実データに近い作業ノードを選ぶ。
しかしファイル「リスト」を渡すということは、ファイル「リスト」と作業ノードの近さは考慮してくれるものの、リストに書かれたファイルと作業ノードの近さは考慮外になるということ。

つまり、作業ノードと実際のデータのある場所が一致するとは限らない。
一致しなければ、作業ノードはデータを別ノードからダウンロードしなければならない。

ノード間通信はコスト高なのでなるべく避けよう、というHadoopの思想にはそぐわない。

mapperの例

しかし選択肢はないので進める。
以下はpythonでファイルリストを受けた場合の処理例。
作業データはHDFS上にあるので、subprocessで「hadoop dfs -cat <ファイル>」する。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys os subprocess

for line in sys.stdin:

        line.strip("\n")
        filename = line

        cat = subprocess.Popen(["hadoop","dfs","-cat",filename],stdout=subprocess.PIPE)

        for logline in cat.stdout:
		#処理
		print line

 

大したことではないけれど、下記のように必ずテストしてからhdoopに投入すること。

$ cat filelist.txt | mapper.py | sort | reducer.py

hadoopは自前mapper, reducerが失敗しても、エラー内容を教えてはくれないので(たぶん)。

注意点

HDFS上にファイルを置いている場合、絶対パスで指定すること。
相対パスではダメだった。
また、HDFSでは「/user/hadoop/input」のように、「user」であって「usr」でないことに注意。

作業データがローカルディスクにあるなら、hadoop dfs -getとか。
しかしそうするとすべての作業ノードがローカルディスクにアクセスしてくることになる。
それは避けたいので、HDFS上に置いた方がよいでしょう。

No tags for this post.

[Hadoop] $HADOOP_HOME is deprecatedの対処

Pocket

“$HADOOP_HOME is deprecated”が鬱陶しい。

※本記事ではhadoop 1.00を使ってます。

hadoopを実行すると”$HADOOP_HOME is deprecated”と表示されることがある。
HADOOP_HOMEはもう使われなくなり、代わりにHADOOP_PREFIXにするよう推奨されている。

これを抑制するには、以下二つのうち、いずれかをすればよい。

”$HADOOP_HOME is deprecated”を抑制するには。

  1. HADOOP_HOMEをHADOOP_PREFIXに置き換える。あるいは。
  2. HADOOP_HOME_WARN_SUPPRESS=YESと宣言する。

hadoopのバージョンアップをするつもりがないなら、②が楽でしょうかね。
具体的には、hadoopを使うユーザの.profileあたりで宣言しておけばOK。

エラーメッセージの原因

なお、HADOOP関連のスクリプトを当該メッセージでgrepすると、hadoop-config.shに以下の記載がある。

hadoop-config.sh

if [ "$HADOOP_HOME_WARN_SUPPRESS" == "" ] && [ "$HADOOP_HOME" != "" ]; then
  echo "Warning: \$HADOOP_HOME is deprecated." 1>&2
  echo 1>&2
fi

つまりHADOOP_HOMEに何か設定されていれば、メッセージを表示する。
しかし、HADOOP_HOME_WARN_SUPPRESSに何か設定されていれば、そのメッセージを抑制する、というわけ。
上記ではHADOOP_HOME_WARN_SUPPRESS=”YES”にしているが、実際のところ中身はなんだってよい。

No tags for this post.

[Hadoop] Hadoop Streaming / mapperとreducerにPythonを使ってみる。

Pocket

 

HadoopはJavaで作られている。
だからHadoopに何か操作をさせたい場合には、通常、Javaで記述する必要がある。
しかしHadoopにはHadoop Streamingという仕組みがあり、早い話UNIXのStandard Stream要するに標準入出力を扱うことができる。

すなわち、UNIXの標準入出力の流儀に則ってさえいれば、お好きな言語で操作ができる。
Javaがまったく合わない私としては、Hadoop Streamはとてもありがたい。
これがなければHadoopに手を付ける気にはならなかった。

Hadoop Streamに必要なもの。

mapperとreducerを、好きな言語で書くだけ。
べつにmapperだけでもよいけど。
私はPython。

Hadoop streamにおけるmapperとreducerの概要。

mapperは何らかの入力を得て、キーと値(key, value)を出力する。
reducerはmapperからのkey, valueを受けて、keyごとにvalueを処理する。

なお、mapperの出力がreducerに渡されるとき、Hadoopがkeyごとにソートしてくれる。
この点はreducerの処理を簡単にする。詳細は後述。

試しにやってみること。

LAN向けのApacheのアクセス状況をカウントしてみる。
IPアドレスごとのアクセス回数だ。
ログは以下のようなもの。
アクセス元はすべてIPアドレスで記録されている。

192.168.100.106 - - [24/Jul/2013:22:35:26 +0900] "GET /MT/js/common/Editor/Iframe.js?v=5.14-ja HTTP/1.1" 304 - "http://192.168.100.5/MTcgi/mt.cgi?__mode=view&_type=entry&blog_id=2&id=330" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"
192.168.100.106 - - [24/Jul/2013:22:35:26 +0900] "GET /MT/js/common/Editor/Textarea.js?v=5.14-ja HTTP/1.1" 304 - "http://192.168.100.5/MTcgi/mt.cgi?__mode=view&_type=entry&blog_id=2&id=330" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"
192.168.100.106 - - [24/Jul/2013:22:35:26 +0900] "GET /MT/mt.js?v=5.14-ja HTTP/1.1" 304 - "http://192.168.100.5/MTcgi/mt.cgi?__mode=view&_type=entry&blog_id=2&id=330" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"

 

処理の流れ

1.mapperは、アクセスログからIPアドレスを抜き出す。
そして「<IPアドレス><タブ>1」を出力する。
これは、たとえば「192.168.1.1」から「1」回アクセスがあったよ、という意味。

2.hadoopがIPアドレスをキーにソート。

3.reducerは、IPアドレスごとに回数をカウントし、
「<IPアドレス><タブ><集計回数>」を出力する。

mapper.py

IPアドレスは、Apacheログにおいて、スペースを区切りにした第一フィールドに記載される。
だから一行ずつログを読んで、行頭のIPアドレスを抜き出し、その都度「<IPアドレス><タブ>1」を出力する。
「if “newsyslog” not in line:」は、システムメッセージ行を読み飛ばすため。

#!/usr/bin/env python

import sys

for line in sys.stdin:
        if "newsyslog" not in line:
                fields = line.strip().split()
                print '%s\t%s' % (fields[0],1)

実行権限も忘れずにつける。

$ chmod a+x ./mapper.py

実験。意図したとおり動いていますね。

$ cat ../input/httpd-access.log |./mapper.py 

192.168.100.107 1
192.168.100.106 1
192.168.100.110 1
192.168.100.107 1
192.168.100.107 1
192.168.100.107 1

 

reducer.py

mapper.pyからの出力は、ソートされてreducer.pyに入力される。
上記のmapper.py出力例は、以下のようにソートされる。

192.168.100.106 1
192.168.100.107 1
192.168.100.107 1
192.168.100.107 1
192.168.100.107 1
192.168.100.110 1

だからreducerとしては、第一フィールドを上から読んでいって、keyが変化したら、そこまでのカウント数を出力する。
そしてそのkeyの事は、さっぱり忘れて次のkeyのカウントに移ることができる。
もしソートがなされていないならば、入力の終わりまですべてのkeyを保持しなければならない。Hadoopに感謝である。

#!/usr/bin/env python

import sys

(last_key, count) = (None, 0)

for line in sys.stdin:
        (key, val) = line.strip().split("\t")

        if last_key and last_key != key:
                print "%s\t%s" % (last_key, count)
                (last_key, count) = (key,int(val))
        else:
                last_key = key
                count += int(val)

if last_key:
        print "%s\t%s" % (last_key, count)

実行権限を付ける。

 $ chmod a+x reducer.py

 

実験。間にsortを入れること。
問題なし。

$ cat ../input/httpd-access.log |./mapper.py |sort|./reducer.py 

127.0.0.1       567
192.168.100.106 327
192.168.100.107 671
192.168.100.109 2
192.168.100.150 193

 

Hadoopで動かしてみよう。

まずカウント対象となるログをHDFSにコピーする。

[hadoop@isis ~]$ hadoop dfs -put apachelog apachelog
[hadoop@isis ~]$
[hadoop@isis ~]$ hadoop dfs -ls
Found 1 items
drwxr-xr-x   - hadoop supergroup          0 2013-07-28 12:57 /user/hadoop/apachelog
[hadoop@isis ~]$
[hadoop@isis ~]$ hadoop dfs -ls apachelog
Found 1 items
-rw-r--r--   1 hadoop supergroup     999290 2013-07-28 12:57 /user/hadoop/apachelog/httpd-access.log
[hadoop@isis ~]$

実行。

hadoopにhadoop-streaming-1.0.0.jarを与え、input、outputのほかに、mapperとreducerも指定する。
-mapper -reducerとしてローカルファイルシステムでのパスを与える。
同時に、-fileでそれぞれのスクリプトを指定すると、スクリプトファイルをリモートのノードへ送ってくれる。

コマンドはすごく長くなる。
エスケープシーケンスを使って適宜改行し、見やすくしてタイプミスを防ぐ。

hadoop  jar \
/usr/local/share/hadoop/contrib/streaming/hadoop-streaming-1.0.0.jar \
    -input apachelog \
    -output apachelog.out \
    -mapper /home/hadoop/sandbox/mapper/mapper.py \
    -reducer /home/hadoop/sandbox/mapper/reducer.py \
    -file /home/hadoop/sandbox/mapper/mapper.py \
    -file /home/hadoop/sandbox/mapper/reducer.py

実際のログ

[hadoop@isis ~]$ hadoop  jar \
>    -output apachelog.out \
>    -mapper /home/hadoop/sandbox/mapper/mapper.py \
> /usr/local/share/hadoop/contrib/streaming/hadoop-streaming-1.0.0.jar \
>    -file /home/hadoop/sandbox/mapper/mapper.py \
>    -file /home/hadoop/sandbox/mapper/reducer.py \
>     -input apachelog \
>     -output apachelog.out \
>     -mapper /home/hadoop/sandbox/mapper/mapper.py \
>     -reducer /home/hadoop/sandbox/mapper/reducer.py \
>     -file /home/hadoop/sandbox/mapper/mapper.py \
>     -file /home/hadoop/sandbox/mapper/reducer.py

packageJobJar: [/home/hadoop/sandbox/mapper/mapper.py, /home/hadoop/sandbox/mapper/reducer.py, /tmp/hadoop-hadoop/hadoop-unjar1190814954490199586/] [] /tmp/streamjob8960127756596123730.jar tmpDir=null
13/07/28 13:30:15 INFO mapred.FileInputFormat: Total input paths to process : 1
13/07/28 13:30:43 INFO streaming.StreamJob: getLocalDirs(): [/tmp/hadoop-hadoop/mapred/local]
13/07/28 13:30:43 INFO streaming.StreamJob: Running job: job_201307281252_0001
13/07/28 13:30:43 INFO streaming.StreamJob: To kill this job, run:
13/07/28 13:30:43 INFO streaming.StreamJob: /usr/local/share/hadoop/bin/../bin/hadoop job  -Dmapred.job.tracker=localhost:8021 -kill job_201307281252_0001
13/07/28 13:30:43 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201307281252_0001
13/07/28 13:30:46 INFO streaming.StreamJob:  map 0%  reduce 0%
13/07/28 13:39:14 INFO streaming.StreamJob:  map 100%  reduce 0%
13/07/28 13:40:27 INFO streaming.StreamJob:  map 100%  reduce 33%
13/07/28 13:40:33 INFO streaming.StreamJob:  map 100%  reduce 67%
13/07/28 13:40:49 INFO streaming.StreamJob:  map 100%  reduce 100%
13/07/28 13:42:39 INFO streaming.StreamJob: Job complete: job_201307281252_0001
13/07/28 13:42:41 INFO streaming.StreamJob: Output: apachelog.out

 

結果の確認

hadoop dfs -catなどで。

[hadoop@isis ~]$ hadoop dfs -ls
Found 2 items
drwxr-xr-x   - hadoop supergroup          0 2013-07-28 12:57 /user/hadoop/apachelog
drwxr-xr-x   - hadoop supergroup          0 2013-07-28 13:42 /user/hadoop/apachelog.out
[hadoop@isis ~]$
[hadoop@isis ~]$ hadoop dfs -ls apachelog.out

Found 3 items
-rw-r--r--   1 hadoop supergroup          0 2013-07-28 13:42 /user/hadoop/apachelog.out/_SUCCESS
drwxr-xr-x   - hadoop supergroup          0 2013-07-28 13:30 /user/hadoop/apachelog.out/_logs
-rw-r--r--   1 hadoop supergroup       1438 2013-07-28 13:40 /user/hadoop/apachelog.out/part-00000
[hadoop@isis ~]$
[hadoop@isis ~]$ hadoop dfs -cat apachelog.out/part-00000

127.0.0.1       567
192.168.100.106 327
192.168.100.107 671
192.168.100.109 2
192.168.100.150 193

[hadoop@isis ~]$

以上

 

No tags for this post.

[Hadoop]擬似分散モードで実験

Pocket

 

擬似分散モードで実験してみる。
Hadoopには、単語を数えるデモが付いてくるのでこれを使う。

カウント対象テキストの準備

以下のようなファイルを作る。

[hadoop@isis ~/sandbox/input]$ ls
test.txt
[hadoop@isis ~/sandbox]$ cat ./input/test.txt
aa
bb
cc
aa
bb

 

ファイルのHDFSへの格納

上で作ったファイルをHDFSに置く。
こういったファイル操作は、hadoopコマンドにdfsを付けて、-putとか-lsとか叩く。
hadoop dfsとやれば使用できるコマンドの一覧が表示される。-catとか-rmとかも使える。ディレクトリの削除は-rmr。

下記の例では、カレントディレクトリにあるinputディレクトリを、HDFSのinputディレクトリに-putでコピーしている。
inputディレクトリには、先に作ったtest.txtが入っている。

[hadoop@isis ~/sandbox]$ hadoop dfs -put input input
[hadoop@isis ~/sandbox]$
[hadoop@isis ~/sandbox]$ hadoop dfs -ls
Found 1 items
drwxr-xr-x   - hadoop supergroup          0 2013-07-27 23:51 /user/hadoop/input
[hadoop@isis ~/sandbox]$
[hadoop@isis ~/sandbox]$ hadoop dfs -ls input
Found 1 items
-rw-r--r--   1 hadoop supergroup         15 2013-07-27 23:51 /user/hadoop/input/test.txt

送り先には絶対パスを付けなくても自動的に/usr/hadoopの下になっていることが分かる。
すなわち、~/sandboxにいるときに、送り元、送り先双方にinputを指定すると、ローカルの~/hadoop/sandbox/inputが、HDFS上の/usr/hadoop/inputにコピーされる。

 

wordcountの実行

hadoop-examples-1.0.0.jarにwordcountと続け、カウント対象のファイルが置かれるディレクトリ、カウント結果のファイルが置かれるディレクトリを指定する。
下記の例では先にコピーしたinputを、結果をoutputとして指定する。
outputはこの時点では無くてOK。
「outputがすでにあるよ」と言われたら中身を確認してからhadoop dfs -rmr outputなどとして消す。

hadoopの実行は何かとコマンドが長くなりがちなので、\を使って見やすく複数行にしたほうがよいでしょう。

[hadoop@isis ~/sandbox]$ hadoop jar \
/usr/local/share/examples/hadoop/hadoop-examples-1.0.0.jar \
wordcount input output

13/07/28 00:02:27 INFO input.FileInputFormat: Total input paths to process : 1
13/07/28 00:02:45 INFO mapred.JobClient: Running job: job_201307272333_0001
13/07/28 00:02:46 INFO mapred.JobClient:  map 0% reduce 0%
13/07/28 00:06:44 INFO mapred.JobClient:  map 100% reduce 0%
13/07/28 00:08:01 INFO mapred.JobClient:  map 100% reduce 66%
13/07/28 00:08:11 INFO mapred.JobClient:  map 100% reduce 100%
13/07/28 00:09:15 INFO mapred.JobClient: Job complete: job_201307272333_0001
13/07/28 00:09:26 INFO mapred.JobClient: Counters: 26
13/07/28 00:09:26 INFO mapred.JobClient:   Job Counters
13/07/28 00:09:26 INFO mapred.JobClient:     Launched reduce tasks=1
13/07/28 00:09:26 INFO mapred.JobClient:     SLOTS_MILLIS_MAPS=159745
13/07/28 00:09:26 INFO mapred.JobClient:     Total time spent by all reduces waiting after reserving slots (ms)=0
13/07/28 00:09:26 INFO mapred.JobClient:     Total time spent by all maps waiting after reserving slots (ms)=0
13/07/28 00:09:26 INFO mapred.JobClient:     Launched map tasks=1
13/07/28 00:09:26 INFO mapred.JobClient:     Data-local map tasks=1
13/07/28 00:09:26 INFO mapred.JobClient:     SLOTS_MILLIS_REDUCES=66457
13/07/28 00:09:26 INFO mapred.JobClient:   File Output Format Counters
13/07/28 00:09:26 INFO mapred.JobClient:     Bytes Written=15
13/07/28 00:09:26 INFO mapred.JobClient:   FileSystemCounters
13/07/28 00:09:26 INFO mapred.JobClient:     FILE_BYTES_READ=33
13/07/28 00:09:26 INFO mapred.JobClient:     HDFS_BYTES_READ=123
13/07/28 00:09:26 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=43099
13/07/28 00:09:26 INFO mapred.JobClient:     HDFS_BYTES_WRITTEN=15
13/07/28 00:09:26 INFO mapred.JobClient:   File Input Format Counters
13/07/28 00:09:26 INFO mapred.JobClient:     Bytes Read=15
13/07/28 00:09:26 INFO mapred.JobClient:   Map-Reduce Framework
13/07/28 00:09:26 INFO mapred.JobClient:     Map output materialized bytes=33
13/07/28 00:09:26 INFO mapred.JobClient:     Map input records=5
13/07/28 00:09:26 INFO mapred.JobClient:     Reduce shuffle bytes=0
13/07/28 00:09:26 INFO mapred.JobClient:     Spilled Records=6
13/07/28 00:09:26 INFO mapred.JobClient:     Map output bytes=35
13/07/28 00:09:26 INFO mapred.JobClient:     Total committed heap usage (bytes)=209518592
13/07/28 00:09:26 INFO mapred.JobClient:     Combine input records=5
13/07/28 00:09:26 INFO mapred.JobClient:     SPLIT_RAW_BYTES=108
13/07/28 00:09:26 INFO mapred.JobClient:     Reduce input records=3
13/07/28 00:09:26 INFO mapred.JobClient:     Reduce input groups=3
13/07/28 00:09:26 INFO mapred.JobClient:     Combine output records=3
13/07/28 00:09:26 INFO mapred.JobClient:     Reduce output records=3
13/07/28 00:09:26 INFO mapred.JobClient:     Map output records=5
[hadoop@isis ~/sandbox]$

仮想環境上とはいえ7分てどういうこと。

結果の確認

結果は。指定したディレクトリ、outputに格納される。
outputの中身を見ると、処理の成功したことを示す_SUCCESSというファイルに、結果の書き込まれるpart-r-00000が格納されている。
hadoop dfs -catで中身を確認すると、各単語の数がリストされている。

[hadoop@isis ~/sandbox]$ hadoop dfs -ls

Found 2 items
drwxr-xr-x   - hadoop supergroup          0 2013-07-27 23:51 /user/hadoop/input
drwxr-xr-x   - hadoop supergroup          0 2013-07-28 00:08 /user/hadoop/output
[hadoop@isis ~/sandbox]$ hadoop dfs -ls output
Warning: $HADOOP_HOME is deprecated.

Found 3 items
-rw-r--r--   1 hadoop supergroup          0 2013-07-28 00:08 /user/hadoop/output/_SUCCESS
drwxr-xr-x   - hadoop supergroup          0 2013-07-28 00:02 /user/hadoop/output/_logs
-rw-r--r--   1 hadoop supergroup         15 2013-07-28 00:08 /user/hadoop/output/part-r-00000
[hadoop@isis ~/sandbox]$
[hadoop@isis ~/sandbox]$ hadoop dfs -cat output/part-r-00000
aa      2
bb      2
cc      1
[hadoop@isis ~/sandbox]$

これだけのために7分とは。
実マシン、かつもっともっと大きなログで試してみたいところ。

 

関連エントリ

[FreeBSD] Hadoopのportsからのインストール
[FreeBSD] portsのHadoopで分散(x-distributed)モードを動かす準備
[Hadoop]Hadoop 擬似分散(Psuedo-distributed)モードの設定
[Hadoop] 擬似分散モードから完全分散モードへ(データノードの追加)


No tags for this post.

[Hadoop]Hadoop 擬似分散(Psuedo-distributed)モードの設定

Pocket

 

Standaloneモードでは、複数のホストを使った処理は行わない。デーモンも動かさない。

しかしHadoopは分散処理をしてナンボである。
分散処理をする場合には、複数のホストでいくつかのデーモンを動作させる必要がある。
それはまあ当然。

ただ、いきなり複数ホストを使うのはハードルが高い。
そこで、「Hadoopは複数ホストで動いているつもりだけど実際は1台のホストで動いている」モードで設定の確認をする。
これが擬似分散(Psuedo-distributed)モード。

擬似分散モードに必要な各設定の意味

擬似分散(Psuedo-distributed)モードの動作には以下、四つの設定が必要。
完全分散(Full distributed)モードでも変わらないんだけどね。

  1. HDFSのメタデータを格納するnamenodeの設定
  2. データをいくつ複製(replication)するかの設定(デフォルトで3)
  3. タスク分散を受け持つJobTrackerの設定
  4. 実データを格納し、タスクを実行するdatanodeかつTaskTrackerの設定

1と3と4にそれぞれlocalhostを指定する(なおこれを別ホストにすればFull distributedモードに)。
2では1を指定する。
デフォルトのままだと、複製を3つ作ろうとする。ひいてはホストが3つ必要になってしまう。
擬似分散モードでは自ホストしか使わないわけだから1を指定するというわけ。

namenode, replication, JobTrackerの設定

以下、三つのファイルを変更する。
前章の1,2,3に対応する。

  • core-site.xml(namenode設定)
  • hdfs-site.xml(replication設定)
  • mapred-site.xml(JobTracker設定)

FreeBSDでportsから入れたなら/usr/local/etc/hadoopにある。

core-site.xml

<configuration>
        <property>
                <name>fs.default.name</name>
                <value>hdfs://localhost/</value>
        </property>
</configuration>

hdfs-site.xml

<configuration>
        <property>
                <name>dfs.replication</name>
                <value>1</value>
        </property>
</configuration>

mapred-site.xml

<configuration>
        <property>
                <name>mapred.job.tracker</name>
                <value>localhost:8021</value>
        </property>
</configuration>

 

datanode, TaskTrackerの設定

/usr/local/etc/hadoopの下にmasters, slavesというファイルを作る。
ここでsecondary namenode, datanode, TaskTrackerを指定する。

secondary namenodeとは、namenodeのデータをバックアップするノード。
datanode、TaskTrackerとは、HDFSの実データが置かれ、JobTrackerから指定されたタスクをこなすノード。

mastersというファイルには、secondary namenodeを書く。
slavesというファイルには、datanodeかつTaskTrackerとなるホストを書く。

擬似分散モードでは、secondary namenodeの指定は不要。
mastersという空ファイルだけ作っておけばよい。
slavesには、localhostと書いておく。

$ cd /usr/local/etc/hadoop/
$ sudo touch slaves masters
$ sudo sh -c 'echo "localhost" >> ./slaves'
$ cat masters
$
$ cat slaves
localhost
$

 

HDFSのフォーマット

初回に限り、HDFSのフォーマットが必要である。
HDFSにはメタデータを保存するnamenodeと、実データの保存されるdatanodeがある。

ここでの「HDFSのフォーマット」とは、実際のところnamenodeの初期化を意味する。

なので、datanodeはこのフォーマットとは無関係。不要。
しかもdatanodeを追加したり削除したときだって、namenodeでの設定変更、フォーマットは不要。

拍子抜けするくらいである。
だが。裏を返すとnamenodeが壊れればすべてのデータが死亡することを意味する。
実運用の際には、secondaly namenodeを立てるなどして事故に備えることになる。

しかし今は擬似分散モードなので気軽に進める。
HDFSのフォーマットは以下のようにして行う。
※フォーマットは、実際にHadoopを使うユーザで行うこと。FreeBSDでportsから入れた場合は注意

$ hadoop namenode -format
Warning: $HADOOP_HOME is deprecated.

13/07/23 20:12:16 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG: host = localhost/127.0.0.1
STARTUP_MSG: args = [-format]
STARTUP_MSG: version = 1.0.0
STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.0 -r 1214675; compiled by 'hortonfo' on Thu Dec 15 16:36:35 UTC 2011
************************************************************/
13/07/23 20:12:18 INFO util.GSet: VM type = 64-bit
13/07/23 20:12:18 INFO util.GSet: 2% max memory = 19.33375 MB
13/07/23 20:12:18 INFO util.GSet: capacity = 2^21 = 2097152 entries
13/07/23 20:12:18 INFO util.GSet: recommended=2097152, actual=2097152
13/07/23 20:12:19 INFO namenode.FSNamesystem: fsOwner=vanilla
13/07/23 20:12:20 INFO namenode.FSNamesystem: supergroup=supergroup
13/07/23 20:12:20 INFO namenode.FSNamesystem: isPermissionEnabled=true
13/07/23 20:12:20 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100
13/07/23 20:12:20 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s)
13/07/23 20:12:20 INFO namenode.NameNode: Caching file names occuring more than 10 times
13/07/23 20:12:20 INFO common.Storage: Image file of size 113 saved in 0 seconds.
13/07/23 20:12:20 INFO common.Storage: Storage directory /tmp/hadoop-vanilla/dfs/name has been successfully formatted.
13/07/23 20:12:20 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at localhost/127.0.0.1
************************************************************/

 

HDFSの場所

上記のログにもある通り、デフォルトでは/tmpの下に作られる。
厳密に言えば、/tmp/hadoop-${user.name} に作られる。
namenodeでも、datanodeでも同じ。

/tmpディレクトリだと、システムが消したりするので実運用では場所を変えたほうがよい。

これらの場所は、hdfs-site.xmlで制御できる。
hadoop.tmp.dirがprefixなので、これを変えればよい。
あるいは、dfs.name.dir(namenode向け)、dfs.data.dir(datanode向け)で明示してもよい。

Hadoopの起動

start-all.shで起動させる。

$ sudo su - hadoop
[hadoop@isis ~]$
[hadoop@isis ~]$
[hadoop@isis ~]$ start-all.sh
Warning: $HADOOP_HOME is deprecated.

starting namenode, logging to /var/log/hadoop/hadoop-hadoop-namenode-isis.out
localhost: Warning: $HADOOP_HOME is deprecated.
localhost:
localhost: starting datanode, logging to /var/log/hadoop/hadoop-hadoop-datanode-isis.out
starting jobtracker, logging to /var/log/hadoop/hadoop-hadoop-jobtracker-isis.out
localhost: Warning: $HADOOP_HOME is deprecated.
localhost:
localhost: starting tasktracker, logging to /var/log/hadoop/hadoop-hadoop-tasktracker-isis.out
[hadoop@isis ~]$

HADOOP_HOMEについて文句をつけられている。スクリプトを見れば分かるが、これは無視してよい。この点については別途。
namenode, datanode, jobtracker, tasktrackerの4つを起動しようと試みていることが分かる。

さて実際に起動しているか。jpsで確認。動いていますな。

[hadoop@isis ~]$ jps
2135 DataNode
2324 TaskTracker
2057 NameNode
2377 Jps
2229 JobTracker
[hadoop@isis ~]$

 

そしてこれらのプロセスは、ポート待ち受けをする。調べてみる。

[hadoop@isis ~]$ sockstat -l4|grep hadoop
hadoop   java       1746  55 tcp4 6 *:24923               *:*
hadoop   java       1746  60 tcp4   127.0.0.1:8021        *:*
hadoop   java       1746  71 tcp4 6 *:50030               *:*
hadoop   java       1621  55 tcp4 6 *:64722               *:*
hadoop   java       1621  63 tcp4   127.0.0.1:8020        *:*
hadoop   java       1621  74 tcp4 6 *:50070               *:*
[hadoop@isis ~]$

50030はJobTrackerの、50070はnamenodeの管理Web用ポート、8020はnamenodeの、8021はdatanodeのポート。

namenodeに対し、ブラウザで前二者のポートにアクセスするとステータスが分かる。

実際に動かすのは今度。
関連エントリ

[FreeBSD] Hadoopのportsからのインストール
[FreeBSD] portsのHadoopで分散(x-distributed)モードを動かす準備
[Hadoop]擬似分散モードで実験
[Hadoop] 擬似分散モードから完全分散モードへ(データノードの追加)

No tags for this post.