Monthly Archives: 7月 2013

[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アドレスで記録されている。

 

処理の流れ

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:」は、システムメッセージ行を読み飛ばすため。

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

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

 

reducer.py

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

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

実行権限を付ける。

 

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

 

Hadoopで動かしてみよう。

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

実行。

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

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

実際のログ

 

結果の確認

hadoop dfs -catなどで。

以上

 

No tags for this post.

コード、エラー、設定ファイル共有サイトのすすめ

Pocket

 

sprunge.usというサービスがあるのを、いまさら知って驚いてそして大感謝した。
以下に顛末を記す。

sprunge.usってなんだ。

ブラウザでsprunge.usを開くと、manページのような見てくれで何か間違えたかと二度見するようなサイトなのだが、よく見ると凄い事が書いてある。

何らかのコマンドの標準出力をsprunge.usに食わすと、URLが返る。
そのURLへアクセスすると、先の出力結果が見えるというわけ。

sprunge.usの使い方

使い方といっても上記の通りなんだが、やってみるのが早い。
uname -aの結果を食べさせてみる。

返ってきたURL、http://sprunge.us/CTQLにアクセスしていただくと、uname -aの結果、すなわち我輩の鯖の詳細が分かる。

 

使いどころ

このサービスの何が便利なのか。
sprunge.usを使うことで、エラーや設定ファイル、ちょっとしたスクリプト、ソースを手軽に共有できる。

たとえば私が、あるサーバが意図した動作をせず困っているときに、助けを求めるとする。
助けを求める相手が、twitterにいるとする。
twitterには140文字しか書けないので、エラー、使用している設定ファイルの中身をすべて貼り付けるのは無理がある。
ではどこかのサイト(いわゆるアップローダと言われているサイトなど)にアップロードするか?それも面倒。
そこでコマンドラインからsprunge.usにアップロードし、そのURLを相手に送る。

これは便利じゃありませんかみなさん。
まあ、助けを求める相手がいる限りにおいてですが。

 

いつまで残るの・・・?

sprungeに載せた内容はいつまで残るのか。
調べてみたけど、ちょっと分からなかった。
末尾で触れるpastebinだと、残す期間を選べたりするのだが。

 

やってもうた時は?

共有すべきでない内容をsprunge.usしてしまった時はどうするのだろうか。
これも検索したけど分からない。
センシティブな情報、IDとかパスワードとかが含まれそうな場合は、後述のpastbinの方がよいかも。

 

sprungeをもっと便利に使う。

まずですね、aliasを設定しましょう。
こんな長いの、いちいちタイプできんですよ。
設定したらすぐ確かめるのが紳士のたしなみ。ここだとaliasを引数なしですぐさま叩く。

テストして問題なければ、シェルに合わせた初期設定ファイルに書き込んでおく。
~/.profileとか。

sprungeはファイルの内容だってOK。

sprungeは標準出力を受け付けるので、ファイルの内容だって貼り付けられる。
FreeBSDのftpd起動シェルスクリプトで試してみよう。
どうせなら、上記で作成したaliasで。

http://sprunge.us/LQCZ どうだろうか。

 

構文強調と行番号表示もできる。

sprunge.usに以下のように書いてある。

上記のftpdシェルスクリプトを例に引く。
シェルスクリプトなので、「sh」を?に続けてURLに加えればよい。

http://sprunge.us/LQCZ?sh

 

sprungeに意地悪をしてみる。

知る人ぞ知るコマンドにslがある。

これはlsをslとタイプミスしてしまったとき、アスキーアートのSL機関車がターミナルを爆走する豪快なコマンドだ。
slコマンドをご存じなく、UNIX系マシンをお持ちの方はぜひインストールしてその目で確かめてほしい。
ちなみにFreeBSDではportsに収録されている。games/slからどうぞ。

で、これをsprungeに食わせてみた。

http://sprunge.us/Sijg …うん。まあ。仕方ないね。

 

同様の別サービス

sprunge.usと同様のサービスにpastbinがある。
http://pastebin.com/
世間的にはsprunge.usよりこちらの方が有名な様子。

CUIから使うためにwgetpastといったツールもある。

 

 

No tags for this post.

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

Pocket

 

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

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

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

 

ファイルのHDFSへの格納

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

下記の例では、カレントディレクトリにあるinputディレクトリを、HDFSのinputディレクトリに-putでコピーしている。
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の実行は何かとコマンドが長くなりがちなので、\を使って見やすく複数行にしたほうがよいでしょう。

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

結果の確認

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

これだけのために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

hdfs-site.xml

mapred-site.xml

 

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と書いておく。

 

HDFSのフォーマット

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

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

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

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

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

 

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で起動させる。

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

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

 

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

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.

[FreeBSD] portsのHadoopで分散(x-distributed)モードを動かす準備

Pocket

 

Hadoopを動かすには、いくつか環境変数の設定が必要である。
JAVA_HOMEとか、HADOOP_PREFIXとか。
また同時に、複数ノードの制御のために、sshやrsyncだって使う。

以上のことを考えると、専用のユーザを作っておくのが便利である。

ところで、Hadoopをportsから入れると、ユーザhadoopが作られる。
ユーザhadoopを使うのがよさそうだが、しかしこのユーザhadoopはそのままでは使えない。
シェルに/sbin/nologinが設定されているから。

Hadoopをportsからインストールしたとき、そういったことも併せて、擬似分散モード、完全分散モードで動かす準備をまとめる。
準備は大きく分けて二段階。ユーザhadoopの環境設定と、sshdの設定変更。

ユーザhadoopのホームディレクトリ、シェル情報の変更

vipwでhadoopの行を以下のように書き換える。

 

パスワードは変えなくてもよい。
sudo su – hadoopしたらいいし、リモートから直接hadoopとしてログインしたい場合には鍵を使うから。

ユーザhadoopのホームディレクトリと.profileの作成

ホームディレクトリを作り、HADOOP関連の環境変数を.profileに書き込む。
追加でHADOOP_PREFIXという変数も加えておく。

 

上記の手順を踏むと、.profileの中身は以下のように。

 

 

実際にログインして環境変数が設定されているか確認。
なってますな。

 

ユーザhadoopのssh設定。

これは複数ノードの制御のため。
ポイントは二つある。
・パスワードなしでssh接続できるようにしておく。
・リモート接続したときにも環境変数が有効になるようにしておく。

パスワードなしのssh接続。

鍵を作っておいて、パスワードなしでリモートノードに接続できるようにしておく。
(セキュリティ的にはおおらかですな。もちろんセキュリティ向上の取り組みはなされているようだけど)

これはもうお決まりの手順。

いったん抜ける

リモート制御(コマンド実行)のためのssh設定

ここでまとめた通り、~/.ssh/environment環境変数の記載をする。
$PATHとかの表記をしない。exportも省く。

 

リモート制御(コマンド実行)のためのssh「d」設定

おなじく、sshdの設定を変える。

 

確認。
パスワードなしでログインできて、環境変数もOK.

 

以上

関連エントリ。

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

No tags for this post.

[FreeBSD][Linux] ssh経由でコマンド実行すると環境変数を読まないでござる

Pocket

ssh経由bashでコマンド実行するときの環境変数を有効にするには。

以下のようにして、リモートホストでコマンドを実行する場合、リモートでの環境変数が有効にならない事がある。

 

これはbashの仕様が原因で、解決にはsshdとリモートユーザの設定が必要。
おそらくshでも同じと思うが、ひとくちにshと言ってもいろんな変種があるので調べていない。
以下にまとめる。

なお、複数ホストを用意するのが面倒なので、本記事で実例を示す場合には接続先をlocalhostしている。

Continue reading

No tags for this post.

[FreeBSD] Hadoopのportsからのインストール

Pocket

 

Hadoopをインストールしたのでメモ。

 

野良HadoopとportsのHadoop

Hadoopを野良で入れるか、portsから入れるか。
結局portsにした。その訳は。

hadoopはJavaで動作する。
ということは、Javaさえ入っていれば、インストールに特殊な手間の必要なくhadoopが動作するはず。
だからインストールを扱う記事、blog等々はhadoopをダウンロードしてtarで展開して…、というものがほとんど。
FreeBSDでだってそれは同じ。

しかしFreeBSDでは、hadoopがportsに収録されている。
portsだと依存するportsを一括で入れてくれるし、ユーザ追加や権限設定なども自動でしてくれる。
便利な一方、世の中の記事とは違うところ(おもにファイル配置)が出てきたり、ひょっとすると最新版を使えないリスクもある。

どっちもどっちだが、hadoopが初めてならportsから入れるのが良いと判断した。
Javaなど依存portsのインストールが面倒だし、そもそもやりたいことはHadoopのセットアップではなくてその先にあるわけだから。
なお2013/7/23時点でportsのhadoopは1.0.0の模様。

 

hadoopのインストール

ports、と言っておきながらなんだけど、けっこう量があるのでスピード重視でpackageから入れた。

まずpackageの入手先を近所のftpに設定する。~/.profileに書いとけ。

 

sudoを使うならvisudoで以下の行をアンコメントしておく。

 

インストール。あそうそう、bashとrsyncも忘れずにね。

 

しばらく放置。

 

事前準備

一式が入ったのだが、hadoopを動かす前に準備がいる。
OpenJDK向け設定、ホスト名の設定、JAVA_HOMEの設定。

 

OpenJDK向けの設定

OpenJDKをインストールすると以下の表示が現れる。
素直に設定する。

 

以下のように。

 

/etc/fstabにも以下の通り記載しておく(空白はタブで)

 

ホスト名の設定

hadoopはhostnameが解決できないと動作しない。
/etc/hostsにhostnameの記載があるか確認して、なければ加える。
DHCPでIPアドレス取得しているなら、127.0.0.1のところにホスト名を入れる。
以下はhostnameがvanillaの場合

 

JAVA_HOMEの設定

portsからHadoopをインストールしているなら不要。
/usr/local/etc/hadoop/envvars.d/000.java_home.envでJAVA_HOMEを設定している。
そして000.java_home.envは起動の都度、読み込まれる(後述)。

 

portsから入れていないんだったら、hadoopを使うユーザの~/.profileで設定しておく。

 

 

ファイル配置

ファイル配置の確認。
portsから入れると、FreeBSDの流儀に沿ってファイルが配置される。

openjdk6の場所

 

hadoop関連

hadoopコマンド: /usr/local/bin/hadoop
実行ファイル他: /usr/local/share/hadoop
設定: /usr/local/etc/hadoop
ログ: /var/log/hadoop
設定サンプル: /usr/local/share/examples/hadoop/

 

各ディレクトリの中身

openjdk6

 

hadoop関連ファイル

 

これでインストールはおしまい。
hadoopはこれだけでも動く。しかしその前に。

/usr/local/bin/hadoopってなんだ

FreeBSDのports特有のものと思うけど、/usr/local/bin/hadoopについて。

/usr/local/bin/hadoopを便宜的にhadoopコマンドと呼ぶ。
hadoop一式は/usr/local/share/hadoop下にあるのに一体これはなんだろう。

中身を見ればすぐ分かる。hadoopコマンドの正体はbashスクリプト。
もう少し見ると、環境変数を設定してからhadoopの実体を呼ぶwrapperであると分かる。
と同時に、環境変数の設定は/usr/local/etc/hadoop/envvars.dの下に置いておけばよいと言う点も分かる。

続き

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

 

 


No tags for this post.

PDFをKindle PaperWhiteで読みやすく

Pocket

PDFをKindle PaperWhiteで読もうとすると、字が小さくなるうえにアンチエイリアスがかかってモヤっとした表示になり読みにくいことこの上ない。

そこでk2optpdfを使ってみた。
結論。
k2optpdfはやめて、横画面モード(Landscape Mode)にして読んでる。

k2optpdfとは

http://www.willus.com/k2pdfopt/
PDFを読みたい端末の解像度、画面サイズに合わせて表示を最適化してくれるツール。
なおここでのPDFとは、テキストデータが埋め込まれているものであって、画像データのPDF、要するに自炊PDFは対象外(のはず)

アウトプットのイメージは上記サイトの通り。

入手方法
http://www.willus.com/k2pdfopt/download/
ここで、左側のCapchaに数字を入れてから、使用しているコンピュータに対応したバージョンをダウンロードする。
スタンドアロンのプログラムなので、ダウンロードしたらそのまま使える。

使い方

http://www.willus.com/k2pdfopt/help/
ダウンロードしたファイルに、変換したいPDFをドラッグアンドドロップし、上記URLを参考に選択肢を選ぶだけ。
Windowsだとコマンドプロンプトが開いてメニューが表示される。

そこで変換先デバイスを選ぶ。dを押してから4を押す。
そしてもう一回Enterを押せばOK。

微妙な調整

上記で普通は問題ないはずだが、それでも変換結果に納得いかない場合がある。
以下にその例と対策を示す。

やっぱり字が小さい

-odpiでdpiを変更できる。-odpi 250くらいでどうか。

途中で落ちる

どうやら、ちょっと気合の入った段組みになったページはうまく変換できず落ちてしまうようだ。
面倒この上ないが、そういう場合は落ちたページを覚えておいて、以下のようにしてそのページを変換対象外にする。

k2pdfoptが落ちてしまうp3以外を変換する。
1-2, 4-

しかし最初から最後まで落ちまくる本もある。
例えばオライリーのheadfirstシリーズとか。
そういうのはもう諦めるしかない。

やっぱり微妙…。

そうしてこうして頑張って変換したけど、やっぱり使いにくい。
その理由を以下に列挙

  • 所詮は自動変換。段組みによって無茶苦茶な変換をする。
  • 変換したら格段にファイルサイズが増える。(画像データになるから)
  • テキストを選択できない。(画像データになるから。 native PDFオプションもあるにはあるが)
  • 落ちまくる。ストレス。

 

最終的に

冒頭で書いたとおり、そのままPDFを横画面モードで読んでます。

 

 

No tags for this post.