M-Software.de V3.0

Nutch Installation und Test

Mein erster Test der Suchmaschine nutch 0.71

Einrichten und Testen der Suchmaschine Nutch (Version 0.7.1)

Schritt 1: Download

Aktuelle Version von der Apache Seite oder einem Mirror herunterladen. Zum Beispiel mit dem Programm wget.

wget http://www.apache.org/dist/lucene/nutch/nutch-0.7.1.tar.gz
--09:13:48--  http://www.apache.org/dist/lucene/nutch/nutch-0.7.1.tar.gz
           => `nutch-0.7.1.tar.gz\'
Resolving www.apache.org... 209.237.227.195
Connecting to www.apache.org[209.237.227.195]:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 47,492,822 [application/x-gzip]

100%[======================>] 47,492,822   179.99K/s    ETA 00:00

09:18:20 (171.06 KB/s) - `nutch-0.7.1.tar.gz\' saved [47492822/47492822]


Schritt 2: Entpacken

Einfach in dem Verzeichnis tar -xvzf nutch-0.7.1.tar.gz aufrufen.

Schritt 3: Einrichten

Nutch unterscheidet zwischen 2 Methoden den Crawler zu verwenden.

I Intranet:

Sollte man verwenden, wenn bis zu 1.000.000 Seiten auf ein paar festgelegten Servern gecrawlt werden sollen.

II Whole-web Crawling:

Findet Verwendung bei sehr grußen Datemengen. Whole-web Crawling kann beliebig viele Seiten crawlen. Der Prozess läuft oft Wochenlang, wenn sehr viele Seiten gecrawlt werden müssen.
Ich habe mich für I (Intranet) entschieden, da ich nur eine Domain mit ca. 800MB Content indizieren möchte.
Als erstes habe ich eine Datei mit meinem Start URL angelegt. In dieser Datei kann man dann die URLs auflisten, die dann als Startpunkte für den Crawler dienen (vi urls). Als nächstes muss noch der Host in der Konfiguration eingetragen werden. Folgender Eintrag muss in die Datei conf/crawl-urlfilter.txt eingetragen werden \"+^http://www.meinserver.de/\". Hier sollten alle Domains eingetragen werden, die gecrawlt werden dürfen. Das war\'s schon.

Schritt 4. Crawler starten (und warten :-) )

Nachdem nun alles konfiguriert ist, kann der Crawler gestartet werden.

bin/nutch crawl urls -dir crawl.test -depth 3 >& crawl.log

Wichtig ist, dass die Umgebungsvariable JAVA_HOME gesetzt ist. Nicht so wichtig, aber ganz interessant ist der Aufruf des Java Interpreters.

/opt/jdk1.5.0/bin/java -Xmx1000m -classpath /opt/nutch/nutch-0.7.1/conf:
/opt/nutch/nutch-0.7.1/nutch-0.7.1.jar:
/opt/nutch/nutch-0.7.1:
/opt/nutch/nutch-0.7.1/lib/commons-logging-api-1.0.4.jar:
/opt/nutch/nutch-0.7.1/lib/concurrent-1.3.4.jar:
/opt/nutch/nutch-0.7.1/lib/jakarta-oro-2.0.7.jar:
/opt/nutch/nutch-0.7.1/lib/jetty-5.1.2.jar:
/opt/nutch/nutch-0.7.1/lib/junit-3.8.1.jar:
/opt/nutch/nutch-0.7.1/lib/lucene-1.9-rc1-dev.jar:
/opt/nutch/nutch-0.7.1/lib/lucene-misc-1.9-rc1-dev.jar:
/opt/nutch/nutch-0.7.1/lib/servlet-api.jar:
/opt/nutch/nutch-0.7.1/lib/taglibs-i18n.jar:
/opt/nutch/nutch-0.7.1/lib/xerces-2_6_2-apis.jar:
/opt/nutch/nutch-0.7.1/lib/xerces-2_6_2.jar:
/opt/nutch/nutch-0.7.1/lib/jettyext/*.jar org.apache.nutch.tools.CrawlTool urls -dir crawl.test -depth 3

Für meinen Test habe ich alle CVS Module aus dem Eclipse Repository ausgecheckt und in einer Web Applikation (ähnlich dem webcvs) zugreifbar gemacht. Um hier alle Webseiten abrufen zu können, musste ich noch die Option -depth auf 20 erhöhen. Um eine Vorstellung davon zu bekommen, hier das CVS Kommando, dass die Module auflistet.

cvs -d :pserver:[email protected]:/cvsroot/eclipse co -c

Der Crawl Prozess schreibt nun alle Informationen (Index, Lexikon, Repository, ...) in das Verzeichnis crawl.test. Mit dem Aufruf \"grep status crawl.log\" kann man die Statusinformationen aus dem crawl.log ermitteln, die von Zeit zu Zeit geschrieben werden.

Hier ein Beispiel während der Crawler läuft.

060222 100145 status: segment 20060222094928, 700 pages, 14 errors, 4044928 bytes, 736321 ms
060222 100145 status: 0.9506723 pages/s, 42.917423 kb/s, 5778.4688 bytes/page

Es ist gut zu erkennen, dass er ca. 1 Webseite pro Sekunde schafft, dass die Webseiten im Schnitt 5,8 kB groß sind und dass er schon 14 Seiten nicht laden konnte. In meinem Fall ist dies jeweils folgende Exception.

failed with: java.lang.Exception: org.apache.nutch.protocol.RetryLater: Exceeded http.max.delays: retry later.

Hier muss also der Wert für \"http.max.delays\" in der Datei \"conf/nutch-default.xml\" angepasst werden.

<property>
<name>http.max.delays</name>
<value>10</value>
<description>The number of times a thread will delay when trying to
fetch a page. Each time it finds that a host is busy, it will wait
fetcher.server.delay. After http.max.delays attepts, it will give
up on the page for now.</description>
</property>
Nachdem ich den Wert von 3 auf 10 erhöht habe konnte ich den Fehler in meinem Logfile nicht mehr finden.

Schritt 5. Die Suche

Ein fertiger Index ist gut, aber ohne eine funktionierende Suche ist er noch nicht viel wert.

Um eine Suche zu ermöglichen sind 2 Punkte zu erledigen.

1. Die Suchapplikation im Tomcat webapps Verzeichnis installieren.
cp nutch*.war TOMCAT_HOME/webapps/nutch.war
Hierdurch wird die Suchapplikation im Tomcat installiert. Evtl. muss dann der Tomcat einmal duchgestartet werden. Ich habe es noch nicht getestet, aber es sollte auch mit anderen Appliktionsservern wie z.B. resin funktionieren.

2. Es muss ein Link auf den Index angelegt werden, damit die Suche den Index findet. Das könnte z.B. so aussehen.

cd CATALINA_HOME/bin
ln -s /opt/nutch/nutch-0.7.1/crawl.test/segments segments


Wichtig ist, dass der Link sich in dem Verzeichnis befindet, aus dem der Tomcat gestatrtet wird. Das ist etwas komisch realisiert, muss aber so gemacht werden. Bei mir ist es das Verzeichnis $CATALINA_HOME/bin.
Nachdem das gemacht wurde, konnte ich unter http://www.meinedomain.de:8080/eclipse/ die Suchmaske aufrufen und die Eclipse Sourcen nach belieben durchsuchen.
Die Geschwindigkeit der Suche ist sehr gut. Ich hatte vorher schon Tests mit htdig gemacht, war aber nicht zufrieden damit. (Fairerweise muss ich zugeben, dass ich den Test mit htdig auf einem anderen Server durchgeführt habe, der weniger Haupspeicher und auch einen langsameren Prozessor hat. Ein objektiver Vergleich ist also nicht möglich)

Einrichten mehrerer paralleler Suchmaschinen in einer Tomcat Applikation.

Bei der Standardinstallation von Nutch ist es nicht vorgesehen mehrere \'segments\' Verzeichnisse in einer gemeinsamen Tomcat Appliation zu verwenden. Trotzdem kann das in einigen Fällen nötig sein. Nach ein wenig Forschungsarbeit in den Sourcen habe ich aber nun doch noch eine einfache Lösung gefunden.

In der Anleitung wird empfohlen das Verzeichnis \'segments\' nach

Möglichkeit 1 ist nun, für jeden nutch Index eine eigene Tomcat Applikation zu installieren. Dafür muss lediglich die Datei nutch*.war nach TOMCAT_HOME/webapps/meineeneue.war kopieren und dann in der Datei WEB-INF/classes/nutch-site.xml noch folgendes eintragen. In meinem Falle befindet sich das \'segments\' Verzeichnis unter \'/opt/nutch/index/eclipse\'.


<nutch-conf>
<property>
  <name>searcher.dir</name>
  <value>/opt/nutch/index/eclipse</value>
  <description></description>
</property>
</nutch-conf>


Nachdem das gemacht wurde, muss der Tomcat einmal neu gestartet werden und schon hat man eine neue Suche.
Möchte man nun aber mehrere \'segments\' Verzeichnisse in einer Tomcat Applikation verwenden, muss man schon etwas tiefer eingreifen, da hier mehr als nur die Konfiguration angepasst werden muss. Hier eine kurze Anleitung, wie man einen Suchdienst für mehrere Index Verzeichnisse einrichtet.
Das Objekt NutchBean, hat einen default Konstruktor, der folgendermaßen aussieht.

public NutchBean() throws IOException 
{
	this(new File(NutchConf.get().get(\"searcher.dir\", \".\")));
}

Dieser wird von der statischen Methode get(ServletContext app) aufgerufen.

/** Cache in servlet context. */
public static NutchBean get(ServletContext app) throws IOException {
    NutchBean bean = (NutchBean)app.getAttribute(\"nutchBean\");
    if (bean == null) {
      LOG.info(\"creating new bean\");
      bean = new NutchBean();
      app.setAttribute(\"nutchBean\", bean);
    }
    return bean;
}

An dieser Stelle wird schon das Problem sichtbar. Die Methode setAttribute von ServletContext hält das NutchBean Objekt zur Verbesserung der Antwortzeiten im Cache. Um nun aber mehrere NutchBean Objekte verwenden zu können muss man entweder den Attributnamen jeder Suchfunktion individuell gestalten oder das Objekte nicht im ServletContext cachen. Ich habe mich dazu entschieden, die zweite Methode zu verwenden. Um aber den Mechanismus des Caches nicht völlig zu verlieren werde ich den Cache statt im ServletContext nun in meiner Session halten.

In den JSPs anchors.jsp, cached.jsp, explain.jsp, search.jsp und text.jsp ist nun der Aufruf \'NutchBean bean = NutchBean.get(application);\' durch folgende Zeilen zu ersetzen.

NutchBean bean = null;
try {
	bean =  (NutchBean)session.getAttribute(\"nutchBean\");
} catch (IOException e)
{
	// Fehlerbehandlung
}
if (bean == null)
{
	try {
		File  selectedDir = new File 
			(\"[Verzeichnis in dem sich \' segments\' befindet.]\");
		bean = new NutchBean(selectedDir);
		session.setAttribute(\"nutchBean\", bean);
	} catch ( IOException e)
	{
		// Fehlerbehandlung
	}
}
PS: Dies funktioniert auch für den DistributedSearch. In dem Fall muss sich in dem Verzeichnis dann die Datei \'search-servers.txt\' befinden.

Der Eintrag [Verzeichnis in dem sich \' segments\' befindet.] kann nun über ein HTML-Formular z.B. ein hidden Feld customisiert werden.

Bei mir laufen derzeit 27 Suchformulare parallel und ich habe bisher keine ernsthaften Probleme. Die Sessions werden regelmäßig aufgeräumt und der Tomcat ist stabil. Leider habe ich schon des öfteren von Problemen mit dem Tomcat in Zusammenhang mit Nutch gehört. In dem Fall hilft oft Resin als Alternative. Allerdings ist das Deployment nicht so einfach, da Resin seine Klassen lieber selber compliert :-)

Fragen oder Anregungen zum Thema beantworte ich jederzeit gerne.

Hat Ihnen dieser Beitrag geholfen? Dann speichern Sie Ihne doch bei diesen Diensten:

Wenn Ihnen diese Informationen zu "Nutch Installation und Test" gefallen haben, Sie Anregungen oder Kritik haben, dann schreiben Sie mir doch einfach eine E-Mail an [email protected].