開發基於 Nutch 的集羣式搜索引擎

本文首先介紹 Nutch 的背景知識,包括 Nutch 架構,爬蟲和搜索器。然後以開發一個基於 Nutch 的實際應用爲例向讀者展示如何使用 Nutch 開發自己的搜索引擎。在該示例中,首先帶領讀者開發一個作爲 Nutch 爬蟲抓取的目標網站,目標網站將被部署在域名爲 myNutch.com 的服務器上。然後示例說明 Nutch 爬蟲如何抓取目標網站內容,產生片斷和索引,並將結果存放在集羣的2個節點上。最後使用 Nutch 檢索器提供的 API 開發應用,爲用戶提供搜索接口。

簡介

Nutch 是一個基於 Java 實現的開源搜索引擎,其內部使用了高性能全文索引引擎工具 Lucene。從 nutch0.8.0開始,Nutch 完全構建在 Hadoop 分佈式計算平臺之上。Hadoop 除了是一個分佈式文件系統外,還實現了 Google 的 GFS 和 MapReduce 算法。因此基於 Hadoop 的 Nutch 搜索引擎可以部署在由成千上萬計算機組成的大型集羣上。由於商業搜索引擎允許競價排名,這樣導致索引結果並不完全是和站點內容相關的,而 Nutch 搜索結果能夠給出一個公平的排序結果,這使得 Nutch 在垂直搜索、檔案互聯網搜索等領域得到了廣泛應用。

前提條件

  • Rational Application Developer v6.0
  • Websphere Application Server v6.0
  • Nutch 0.8.1
  • SSH Service Package
  • 主節點RHAS3.0
  • 從節點Debian GNU/Linux 3.1

背景知識

Nutch 搜索引擎是一個基於 Java 的開放源代碼的搜索引擎。Nutch 搜索引擎處理流程包括抓取流程和搜索流程,如圖 1 所示。相應地 Nutch 也分爲2部分,抓取器和搜索器。在抓取流程中,抓取器也叫蜘蛛或者機器人,以廣度優先搜索(BFS)的方式從企業內部網或者互聯網抓取網頁。這個過程涉及 到對 CrawlDB 和 LinkDB 數據庫的操作。然後 Nutch 解析器開始解析諸如 HTML、XML、RSS、PDF等不同格式的文檔。最後 Nutch 索引器針對解析結果建立索引並存儲到 indexDB 和 SegmentsDB 數據庫中,以供搜索器搜索使用。

在搜索流程中,搜索應用使用輸入關鍵詞調用 Nutch 搜索接口(Nutch Query Interface)。應用可通過網頁上的輸入框輸入相應關鍵詞。搜索接口解析搜索請求爲 Lucene 全文檢索引擎可以識別的格式。Nutch 索引器將會調用 Lucene 引擎來響應請求在 indexDB 上展開搜索。最後搜索接口收集從索引器返回的URL、標題、錨和從 SegmentsDB 返回的內容。所有上述內容將被提供給排序算法進行排序。排序完成後,搜索接口將返回命中的搜索結果。由於構建在 Hadoop 分佈式文件系統之上, Nutch 對CrawlDB, LinkDB, SegmentsDB 和 IndexDB 數據庫的操作都是通過調用 M/R(map/reduce) 函數完成的。這使得 Nutch 具有了集羣擴展能力。


圖 1 Nutch搜索引擎架構圖
Nutch搜索引擎架構圖

開發目標網站 targetWebSite

現在將開發一個供 Nutch 爬蟲抓取的目標網站應用。這個應用使用 RAD v6.0(Rational Application Developer)作爲集成開發工具開發。應用開發完成後,將被部署在 WAS v6.0(Websphere Application Server)服務器上,本樣例中服務器的域名設置是 myNutch.com。讀者可以按照下面的步驟來開發該目標網站應用。

  1. 創建一個動態 Web 項目。打開 RAD,選擇 File > New > Project,然後在嚮導裏選擇動態 Web 項目,如圖 2 所示。

    圖 2 創建一個動態 Web 項目
    創建一個動態Web項目
  2. 設計網頁。在項目裏面,選擇 File > New > HTML/XHTML,創建 index.html, one.html,two.html 和 three.html 一共4個文件。 項目的最終結構組成如圖 3 所示。

    圖 3 項目的最終結構組成
    項目的最終結構組成
  3. 在 WAS v6.0 中運行項目。 打開 RAD, 選擇 project > Run > Run on Server, 部署並在服務器上運行。如圖 4 所示。

    圖 4 在服務器上運行
    在服務器上運行
  4. 點擊完成按鈕。啓動瀏覽器,在地址欄中輸入 http://myNutch.com/targetWebApp。如圖 5 所示。

    圖 5 在瀏覽器中訪問
    在瀏覽器中訪問

定義搜索引擎

在抓取網站之前,需要定義搜索引擎。在本樣例中Nutch被配置爲集羣方式。集羣包括主節點(地址9.181.87.172,操作系統 RHAS3.0)和從節點(地址 9.181.87.176,操作系統 Debian)。如前文介紹,Nutch 的集羣能力主要利用了 Hadoop 的分佈式計算環境。下面介紹如何定義 Nutch 搜索引擎。

  1. 安裝 Nutch。首先下載 Nutch 安裝包。本示例採用 Nutch0.8.1。解壓下載到的 Nutch 0.8.1包到主節點某一工作目錄下。本文中的工作目錄使用 /workspace 。確認主從節點上都已安裝 SSH service package和 JDK1.4 或 JDK 1.5
  2. Nutch 設置。在 Nutch 的工作目錄下,用文本編輯器打開 conf 目錄下的文件 Nutch-site.xml,輸入 http.agent.name,http.agent.description,http.agent.url 和 http.agent.email 屬性集。注意 http.agent.ur 屬性需要填寫部署目標網站的域名地址 myNutch.com。清單 1 列出了修改完畢後的 Nutch-site.xml。

    清單 1 Nutch-site.xml
    <property>
    <name>http.agent.name</name>
    <value>Nutch-hadoop</value>
    <description>HTTP 'User-Agent' request header. MUST NOT be empty -
    please set this to a single word uniquely related to your organization.
    </description>
    </property>
    <property>
    <name>http.agent.description</name>
    <value>bydenver</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>myNutch.com</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>[email protected]</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>
  3. Hadoop 主節點設置。 用文本編輯器打開 conf 目錄下的文件 hadoop-site.xml,插入清單 2 所列出的屬性集。需要注意的是屬性 fs.default.name 和 mapred.job.tracker 設置爲主節點的IP地址(在本例中爲9.181.87.172)。

    清單 2 hadoop-site.xml文件
    <property>
    <name>fs.default.name</name>
    <value>9.181.87.172:9000</value>
    <description>
    The name of the default file system. </description>
    </property>
    <property>
    <name>mapred.job.tracker</name>
    <value>9.181.87.172:9001</value>
    <description>
    The host and port that the MapReduce job tracker runs at.
    </description>
    </property>
    <property>
    <name>mapred.map.tasks</name>
    <value>2</value>
    <description>
    define mapred.map tasks to be number of slave hosts
    </description>
    </property>
    <property>
    <name>mapred.reduce.tasks</name>
    <value>2</value>
    <description>
    define mapred.reduce tasks to be number of slave hosts
    </description>
    </property>
    <property>
    <name>dfs.name.dir</name>
    <value>/workspace/filesystem/name</value>
    </property>
    <property>
    <name>dfs.data.dir</name>
    <value>/workspace/filesystem/data</value>
    </property>
    <property>
    <name>mapred.system.dir</name>
    <value>/workspace/filesystem/mapreduce/system</value>
    </property>
    <property>
    <name>mapred.local.dir</name>
    <value>/workspace/filesystem/mapreduce/local</value>
    </property>
    <property>
    <name>dfs.replication</name>
    <value>2</value>
    </property>
  4. Hadoop 從節點設置。使用文本編輯器打開 conf 目錄下的 slaves 文件,輸入從節點的 IP 地址。如清單 3 所示。

    清單 3 slaves 文件
    9.181.87.176
  5. 抓取器設置。首先在 Nutch 工作目錄下創建目錄 urls,再新建文件 urllist.txt。編輯 urllist.txt文件,輸入 http://myNutch.com/targetWebApp。清單 4 列出了所使用的命令。最後需要編輯 conf 目錄下的 crawl-urlfilter.txt 文件,輸入 +^http://([a-z0-9]*/.)*myNutch.com/,如清單 5 所示。

    清單 4 創建 urllist 文件
    cd /workspace/Nutch-0.8.1
    mkdir urls
    echo http://myNutch.com/targetWebApp > urls/urllist.txt
    conf/crawl-urlfilter.txt



    清單 5 編輯crawl-urlfilter.txt 文件
    +^http://([a-z0-9]*/.)*myNutch.com/

抓取器抓取並分析

在使用 Nutch 抓取之前,首先需要啓動 Hadoop 服務。清單 6 列出了啓動 Hadoop 服務所採用的命令。隨後使用清單 7 中的命令從 myNutch.com 抓取網頁並解析,其中參數 “depth 3” 表示從網頁根路徑算起的鏈接深度;參數 “topN 10” 表示抓取器在每層需要獲取的最大頁面數目。開始抓取後,抓取器將在當前目錄下創建新目錄 crawl 作爲工作目錄。


清單 6 啓動 Hadoop 服務

bin/hadoop dfs -put urls urls
bin/hadoop dfs namenode –format



清單 7 抓取命令

bin/Nutch crawl urls -dir ./crawl -depth 3 -topN 10

 

對目標網站 targetWebApp 完成抓取後, 在 crawl 工作目錄下產生了五個子目錄: crawldb,linkdb,segments,indexes 和 index (見圖 6)。數據庫 crawldb 中包含頁面的數目等;linkdb 包含頁面在數據庫中的鏈接,這是抓取器真正抓取網站時由頁面的鏈接數目決定;Segments 數據庫按照時間戳分爲三個片斷,每個片斷的產生都經歷了 generate/fetch/update 三個過程;Indexes 數據庫包含了在 generate/fetch/update 過程中產生的 Lucene 索引;Index 數據庫包含了經合併處理後的 Lucene 索引。


圖 6 抓取器抓取結果
抓取器抓取結果

讀者也可以使用工具 Luke 去查看 Lucene 索引。 藉助 Luke,可以查看索引內容以及對索引查詢。圖 7 列出了 index 目錄下的合併後的索引。


圖 7 使用 Luke 查看 Lucene 索引
使用Luke查看Lucene索引

開發搜索應用

完成抓取後,現在將開發一個基於 Nutch 搜索 API 的應用 NutchApp,提供給用戶作爲搜索的接口。NutchApp 使用 Java 語言編寫,其實現首先創建 NutchConfiguration 對象,然後創建 NutchBean。這個 NutchBean 實例將用來處理用戶的搜索請求;根據請求參數,創建 query 對象,NutchBean 通過調用 search 方法來處理此 query 對象的請求。最終搜索結果以 Hits 集合。NutchApp 遍歷此 Hits 集合並打印結果到標準輸出。清單 8 列出了 NutchApp 的示例代碼。


清單 8 NutchApp的示例代碼

package org.myNutch;
import java.io.IOException;
import java.io.*;
import java.util.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.Nutch.searcher.*;
import org.apache.Nutch.util.*;
public class NutchApp {
/** For debugging. */
public static void main(String[] args) throws Exception {
String usage = "NutchBean query";
if (args.length == 0) {
System.err.println(usage);
System.exit(-1);
}
Configuration conf = NutchConfiguration.create();
NutchBean bean = new NutchBean(conf);
Query query = Query.parse(args[0], conf);
Hits hits = bean.search(query, 10);
System.out.println("Total hits: " + hits.getTotal());
int length = (int)Math.min(hits.getTotal(), 10);
Hit[] show = hits.getHits(0, length);
HitDetails[] details = bean.getDetails(show);
Summary[] summaries = bean.getSummary(details, query);
for ( int i = 0; i <hits.getLength();i++){
System.out.println(" "+i+" "+ details[i] + "/n" + summaries[i]);
}
}
}

 

接下來我們來運行 NutchApp。首先編譯 NutchApp.java 並打包。打包後的文件名爲 NutchApp.jar。隨後在 Nutch 命令下執行。見清單 9。


清單 9 編譯、打包和執行 NutchApp

Javac -cp "Nutch-0.8.1.jar;hadoop-0.4.0-patched.jar" src/org/myNutch/NutchApp.java -d lib
cd lib
jar cvf NutchApp.jar org/myNutch/NutchApp.class
cd ../
bin/Nutch org.myNutch.NutchApp Nutch

 

下面我們可以驗證我們開發的 Nutch 搜索引擎的使用效果。在搜索頁面搜索關鍵字輸入“Nutch”,NutchApp 返回的搜索結果如清單 10 所示。其中包括概要和詳細內容。


清單 10 NutchApp輸出

Total hits: 3
0 20061104142342/http://myNutch.com/targetWebApp/two.html
... 8 release of Nutch is now available. This is ... first release of Nutch
1 20061104142342/http://myNutch.com/targetWebApp/one.html
... 1 release of Nutch is now available. This is ...
2 20061104142342/http://myNutch.com/targetWebApp/three.html
... 2 release of Nutch is now available. This is ...

 

小結

通過本文的介紹,現在你已經知道如何使用 Nutch 開發集羣式的搜索引擎,並使用此搜索引擎對目標網站進行抓取和分析結果,以及如何提供搜索接口來響應用戶的搜索請求。事實上,搭建基於 Nutch 的搜索引擎是一個具有很大挑戰性的工作,因爲 Nutch 本身還在不斷的發展之中,另外目標網站的結構複雜度也不盡相同。所以,針對互聯網站點文檔格式日益複雜的需求,接下來你還需要花一些精力關注 Nutch 高級特性的進展。

參考資料

學習


獲得產品和技術


作者簡介

 

王飛鵬是 IBM 中國軟件開發中心的軟件工程師

 

李立是 IBM 中國研究院的研究員

 

王美華是 IBM 中國軟件開發中心的軟件工程師

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章