技術情報 Nutch 0.9 - Hadoop 0.10 - チュートリアル

Nutch と Hadoop のセットアップ方法 (Ubuntu 6.06)

本稿は http://wiki.apache.org/nutch/Nutch0.9-Hadoop0.10-Tutorial を日本語に訳したものです。

last edited 2008-09-19 22:05:49 by MarcinOkraszewski

前提条件

Hadoop を実行するには、本来の分散ファイルシステムを利用するために少なくとも2台のコンピュータを必要とします。1台のマシン上でも実行することもできますが、分散処理能力が無駄になります。

Nutch は Java で書かれているため、ant と同様に java コンパイラとランタイムが必要です。Hadoop はすべてのマシン上で ssh クライアントと ssh サーバを利用します。Lucene は Servlet コンテナが必要です。私は tomcat5 を使いました。

su で root としてログインできるようにするには、次のコマンドを実行して、指示どおりに root のための新しいパスワードを入力します。

sudo passwd

root としてログイン

su

apt の sources.list ファイルを編集して、universe と multiverse リポジトリを有効にしてください。

vi /etc/apt/sources.list

もしくは、もしあなたがオランダにいてUbuntu 6.06 Dapper を使っていたら、次を実行してください。

echo "deb http://nl.archive.ubuntu.com/ubuntu/ dapper universe multiverse" >> /etc/apt/sources.list
echo "deb-src http://nl.archive.ubuntu.com/ubuntu/ dapper universe multiverse" >> /etc/apt/sources.list

apt のキャッシュを更新します。

apt-get update

すべてのマシン上で Nutch に必要なパッケージ(java と ssh) をインストールします。

apt-get install sun-java5-jre
apt-get install ssh

update-alternatives --config java
#select /usr/lib/jvm/java-1.5.0-sun/jre/bin/java

そして、検索サーバに必要なものも

apt-get install apache2
apt-get install sun-java5-jdk
apt-get install tomcat5

/etc/default/tomcat5 を編集して tomcat を設定します

vi /etc/default/tomcat5
#Add JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun/

もしくは以下を実行します

echo "JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun/" >> /etc/default/tomcat5

nutch のビルド

Nutch をダウンロードします。これは Hadoop と Lucene が含まれています。私は執筆時点で最新の nightly ビルドを使いました。Nutch nightly

tarball を nutch-nightly に解凍して、ant でビルドします。

tar -xvzf nutch-2007-02-06.tar.gz
cd nutch-nightly
mkdir /nutch-build
echo "/nutch-build" >> build.properties
ant package

セットアップ

マシンの準備

それぞれのマシンに、nutch ユーザーを作成し、必要なディレクトリを作成します。

ssh root@???

mkdir /nutch-0.9.0
mkdir /nutch-0.9.0/search
mkdir /nutch-0.9.0/filesystem
mkdir /nutch-0.9.0/local
mkdir /nutch-0.9.0/home

groupadd users
useradd -d /nutch-0.9.0/home -g users nutch
passwd nutch

chown -R nutch:users /nutch-0.9.0
exit
nutch と hadoop のインストール・設定

nutch を namenode (マスター) にインストールし、hadoop-env.sh シェルスクリプトに以下の変数を追加します。

ssh nutch@???
cp -Rv /nutch-build/* /nutch-0.9.0/search/

echo "export HADOOP_HOME=/nutch-0.9.0/search" >> /nutch-0.9.0/search/conf/hadoop-env.sh
echo "export JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun" >> /nutch-0.9.0/search/conf/hadoop-env.sh
echo "export HADOOP_LOG_DIR=/nutch-0.9.0/search/logs" >> /nutch-0.9.0/search/conf/hadoop-env.sh
echo "export HADOOP_SLAVES=/nutch-0.9.0/search/conf/slaves" >> /nutch-0.9.0/search/conf/hadoop-env.sh

exit
SSH の設定

nutch がパスワードのプロンプトを表示することなく ssh でログインできるようにするため、ssh の鍵を作ります。

ssh nutch@???
cd /nutch-0.9.0/home
ssh-keygen -t rsa
#! Use empty responses for each prompt
#  Enter passphrase (empty for no passphrase): 
#  Enter same passphrase again: 
#  Your identification has been saved in /nutch-0.9.0/home/.ssh/id_rsa.
#  Your public key has been saved in /nutch-0.9.0/home/.ssh/id_rsa.pub.
#  The key fingerprint is:
#  a6:5c:c3:eb:18:94:0b:06:a1:a6:29:58:fa:80:0a:bc nutch@localhost

master (namenode) の公開鍵を authorized_keys ファイルにコピーします。このファイルは他のマシン(slave)にコピーされます。

cd /nutch-0.9.0/home/.ssh
cp id_rsa.pub authorized_keys
Hadoop の設定

mapred-default.xml 設定ファイルを編集します。ない場合は作成して、次のようにします:

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>

<property> 
  <name>mapred.map.tasks</name>
  <value>2</value>
  <description>
    This should be a prime number larger than multiple number of slave hosts,
    e.g. for 3 nodes set this to 17
  </description> 
</property> 

<property> 
  <name>mapred.reduce.tasks</name>
  <value>2</value>
  <description>
    This should be a prime number close to a low multiple of slave hosts,
    e.g. for 3 nodes set this to 7
  </description> 
</property> 

</configuration>

注意: これらのプロパティを hadoop-site.xml に設定しないでください。そのファイルは(後述)はジョブではなく、クラスタについての特性のプロパティのみを保持しておくべきです。これらの設定を忘れると奇妙でデバッグしずらい問題を引き起こします―例えば、プログラム的に map/reduce タスクの数を指定できないなど(Generator と Fetcher はこの設定に依存しています)。

hadoop-site.xml 設定ファイルを編集します。

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

<property>
  <name>fs.default.name</name>
  <value>???:9000</value>
  <description>
    The name of the default file system. Either the literal string 
    "local" or a host:port for NDFS.
  </description>
</property>

<property>
  <name>mapred.job.tracker</name>
  <value>???:9001</value>
  <description>
    The host and port that the MapReduce job tracker runs at. If 
    "local", then jobs are run in-process as a single map and 
    reduce task.
  </description>
</property>

<property>
  <name>mapred.tasktracker.tasks.maximum</name>
  <value>2</value>
  <description>
    The maximum number of tasks that will be run simultaneously by
    a task tracker. This should be adjusted according to the heap size
    per task, the amount of RAM available, and CPU consumption of each task.
  </description>
</property>

<property>
  <name>mapred.child.java.opts</name>
  <value>-Xmx200m</value>
  <description>
    You can specify other Java options for each map or reduce task here,
    but most likely you will want to adjust the heap size.
  </description>
</property>

<property>
  <name>dfs.name.dir</name>
  <value>/nutch-0.9.0/filesystem/name</value>
</property>

<property>
  <name>dfs.data.dir</name>
  <value>/nutch-0.9.0/filesystem/data</value>
</property>

<property>
  <name>mapred.system.dir</name>
  <value>$/nutch-0.9.0/filesystem/mapreduce/system</value>
</property>

<property>
  <name>mapred.local.dir</name>
  <value>/nutch-0.9.0/filesystem/mapreduce/local</value>
</property>

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

</configuration>
Nutch の設定

nutch-site.xml を編集します。次の内容を使い、value タグを入力します。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
<property>
  <name>http.agent.name</name>
  <value></value>
  <description>HTTP 'User-Agent' request header. MUST NOT be empty - 
  please set this to a single word uniquely related to your organization.

  NOTE: You should also check other related properties:

  http.robots.agents
  http.agent.description
  http.agent.url
  http.agent.email
  http.agent.version

  and set their values appropriately.

  </description>
</property>

<property>
  <name>http.agent.description</name>
  <value></value>
  <description>Further description of our bot- this text is used in
  the User-Agent header.  It appears in parenthesis after the agent name.
  </description>
</property>

<property>
  <name>http.agent.url</name>
  <value></value>
  <description>A URL to advertise in the User-Agent header.  This will 
   appear in parenthesis after the agent name. Custom dictates that this
   should be a URL of a page explaining the purpose and behavior of this
   crawler.
  </description>
</property>

<property>
  <name>http.agent.email</name>
  <value></value>
  <description>An email address to advertise in the HTTP 'From' request
   header and User-Agent header. A good practice is to mangle this
   address (e.g. 'info at example dot com') to avoid spamming.
  </description>
</property>
</configuration>

crawl-urlfilter.txt を編集し、取得すべき URL のパターンを設定します。

cd /nutch-0.9.0/search
vi conf/crawl-urlfilter.txt

次のような行を:               +^http://([a-z0-9]*\.)*MY.DOMAIN.NAME/
このように変えてください:    +^http://([a-z0-9]*\.)*org/

もしくは、もしインターネット全体からダウンロードしたい場合は、nutch-site.xml を編集し、次のようなプロパティを指定します。

<property>
  <name>urlfilter.regex.file</name>
  <value>automaton-urlfilter.txt</value>
</property>
コードと設定の分配

コードと設定を slave にコピーします。

scp -r /nutch-0.9.0/search/* nutch@???:/nutch-0.9.0/search

鍵を slave マシンにコピーします。

scp /nutch-0.9.0/home/.ssh/authorized_keys nutch@???:/nutch-0.9.0/home/.ssh/authorized_keys

マシンで sshd が準備できたかチェックします

ssh ???
hostname

クローリング

dfs を使ってクロールをするには、まず Hadoop の namenode をフォーマットする必要があります。そして、すべての datanode サービスと同様に namenode を開始します。

namenode をフォーマット

bin/hadoop namenode -format

すべてのマシン上ですべてのサービスを起動する。

bin/start-all.sh

すべてのサービスを止めるには以下のコマンドを実行してください。でも今は実行しないでください。

bin/stop-all.sh

いくつかのseed url を元にクロールをはじめるには、seed url ディレクトリが作成します。このディレクトリにはいくつかのseed urlを持つseed file入っています。

このファイルは hdfs 上に置かれます、hadoop の dfs -ls オプションを使ってディレクトリが保存されているかどうか調べることができます。

mkdir urls
echo "http://lucene.apache.org" >> urls/seed
bin/hadoop dfs -put urls urls
bin/hadoop dfs -ls urls

初回のクロールを開始します

bin/nutch crawl urls -dir crawled -depth 3

masternode 上では、ウェブブラウザで進捗やステータスを見ることができます。[http://localhost:50030/]

検索

集めたページを検索するには、hdfs上にあるデータをローカルファイルシステムにコピーすることがパフォーマンス上最もよいです。1台のマシンで処理しきれないほどインデックスが大きくなってきた場合は、インデックスを分割して別々のマシンでインデックスの一部を処理することができます。最初は1台のマシン上での検索を行ってみます。

検索用 nutch のインストール

検索はクロールとは異なる nutch 設定が必要となるため、そのような設定を簡単に行うには、検索用 nutch のために別のフォルダを作ります。

ssh root@???
mkdir /nutchsearch-0.9.0
chown nutch:users /nutchsearch-0.9.0
exit

ssh nutch@???
cp -Rv /nutch-build /nutchsearch-0.9.0/search
mkdir /nutchsearch-0.9.0/local
設定

検索用 nutch のディレクトリにある、nutch-site.xml を編集します

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

  <property>
    <name>fs.default.name</name>
    <value>local</value>
  </property>

  <property>
    <name>searcher.dir</name>
    <value>/nutchsearch-0.9.0/local/crawled</value>
  </property>

</configuration>

hadoop-site.xml を編集し、すべてのプロパティを削除します。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

</configuration>
ローカルインデックスの作成

dfs からローカルファイルシステムにデータをコピーします。

bin/hadoop dfs -copyToLocal crawled /nutchsearch-0.9.0/local/

すべての設定が適切かどうかテストします

bin/nutch org.apache.nutch.searcher.NutchBean an

最後のコマンドではたくさんのヒットがあるはずです。もしクエリ結果が 0 件の場合、設定かインデックスになにか問題があるか、この単語を含んでいる文書がない可能性があります。いくつかの単語を試しても、すべて 0件の場合、ほぼ確実に設定に問題があるか、インデックスが壊れています。私が出くわした設定の問題は、間違ったインデックスディレクトリを指定していて、hadoop が気づかずそれを使っていました。

ウェブ検索インターフェイスを有効にする

tomcat ディレクトリに war ファイルをコピーします。

rm -rf usr/share/tomcat5/webapps/ROOT*
cp /nutchsearch-0.9.0/*.war /usr/share/tomcat5/webapps/ROOT.war

設定を tomcat ディレクトリにコピーします

cp /nutchsearch-0.9.0/search/conf/* /usr/share/tomcat5/webapps/ROOT/WEB-INF/classes/

tomcat を開始します

/usr/share/tomcat5/bin/startup.sh

ウェブブラウザで検索ページを開きます。[http://localhost:8180/]

分散検索

他のマシンがインデックスの一部を対応するように準備する。

ssh root@???
mkdir /nutchsearch-0.9.0
mkdir /nutchsearch-0.9.0/search
chown -R nutch:users /nutchsearch-0.9.0
exit

検索用 nutch のディレクトリを他のマシンにコピーする。

scp -r /nutchsearch-0.9.0/search nutch@???:/nutchsearch-0.9.0/search
設定

nutch-site.xml を編集し、search.dir プロパティに、search-servers.txt を含むディレクトリを指定する。このファイルには IPアドレスとポート番号がリストされている。conf ディレクトリにある search-servers.txt に、IPアドレスとポート番号を追加します。

x.x.x.1 9999
x.x.x.2 9999
x.x.x.3 9999

nutch-site.xml を編集します:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

  <property>
    <name>fs.default.name</name>
    <value>local</value>
  </property>

  <property>
    <name>searcher.dir</name>
    <value>/nutchsearch-0.9.0/search/conf/</value>
  </property>

</configuration>
インデックスの分割

現在の Nutch と Lucene のコードには、ひとつのインデックスを小さなインデックスに分割する機能がありません。メーリングリストに、ほとんど要件を満たすコードが発表されています。[http://www.nabble.com/Lucene-index-manipulation-tools-tf2781692.html#a7760917]

インデックスの各パーツを異なるマシンにコピーします。

サービスの開始

インデックスの一部をもっているすべてのマシンで、検索サービスを起動します。

bin/nutch server 9999 /nutchsearch-0.9.0/local/crawled

マスターの検索ノードを再起動します。

/usr/share/tomcat5/bin/shutdown.sh
/usr/share/tomcat5/bin/startup.sh

ウェブブラウザで検索ページを開きます。[http://localhost:8180/]

さらなるページのクロール

nutch には、データベースからリンクを抽出しその他のページをクロールするためのコマンド、 generate、fetch、updatedb があります。以下の Bash スクリプトはこれらのコマンドを組み合わせ、データディレクトリの場所と取得する件数の二つのパラメータをとりクロールを開始します。以下の Bash スクリプトはこれらのコマンドを組合せており、これはデータディレクトリの場所と取得するページ数の二つのパラメータをとり、クロールを開始します。例えばこのファイルを bin/fetch として保存します。データが crawl01 にあるとしたら、`bin/fetch crawl01 10000' と実行すると、10000件のリンクをデータベースから抽出し、それらを取得します。

bin/nutch generate $1/crawldb $1/segments -topN $2
segment=`bin/hadoop dfs -ls crawled01/segments/ | tail -1 | grep -o [a-zA-Z0-9/]*`
bin/nutch fetch $segment
bin/nutch updatedb $1/crawldb $segment

新しいインデックスを構築するには以下のスクリプトを実行してください:

bin/hadoop dfs -rmr $1/indexes

bin/nutch invertlinks $1/linkdb $1/segments/*

bin/nutch index $1/indexes $1/crawldb $1/linkdb $1/segments/*

データをローカルにコピーすれば、新しいデータで検索できるようになります。

コメント

map reduce タスクの数

map reduce タスクの数は Hadoop のパフォーマンスに影響を与える事に気づきました。大量のページをクロールした後では、何度もノードから 'java.lang.OutOfMemoryError: Java heap space' エラーを報告しました。これはまた、インデックス段階でも起こりました。map の数を増やすとこれらの問題は解決しました。20万ページ以上を持つインデックスで、3台のマシンで合計306つの map が必要になりました。hadoop-site.xml の、mapred.maps.tasks プロパティを 99 に設定(これは他のチュートリアルや hadoop-site.xml の推奨値よりはるかに大きいです)すると問題は解決しました。

上記で述べられているように、hadoop-site.xml に map/reduce タスクの数を設定しないでください。代わりに mapred-default.xml に指定してください。

map reduce タスクの数についての詳細は http://wiki.apache.org/lucene-hadoop/HowManyMapsAndReduces をご覧ください。

DFS へのファイル作成時のエラー

このようなエラーが出た場合:

put: java.io.IOException: failed to create file /user/nutch/.test.crc on client 127.0.0.1 because target-length is 0, below MIN_REPLICATION (1)

この場合ディスクスペースが十分でない可能性があります。私の場合残りディスク容量が 90MB のときに発生しました (Nutch 0.9/Hadoop 0.12.2)。メーリングリストの投稿もご覧ください。

お問い合わせ・ご相談はこちら

OpenCMSサポート

充実のユビキャストユーザー向けプラン

サポート詳細はこちら

Ubicast スタッフブログ

  • OpenCMS 公式サイト
  • メールでブログ投稿
  • プロジェクト管理ツール