(黃獻德) Hsien-De Huang | E-Mail:TonTon (at) TWMAN.ORG | TonTon (痛痛)
Malware Analysis Network in Taiwan (MiT) | 惡意程式分析網在台灣 (抬丸郎)
Deep Learning (深度學習), Malware Analysis (惡意程式分析), Ontology (知識本體)
Android Reverse Engineering (Android 逆向工程), Type-2 Fuzzy Logic (第二型模糊邏輯)

ONE PIECE (海賊王)

ONE PIECE (海賊王)

2013年12月13日

DRBL-based Hadoop-1.2.1 整合 Nutch-1.7 及 Solr 4.5

嗯 ! nutch .... 這個應該也不需要說太多吧 ? 就是很有名的 open source 搜尋引擎啊 !

雖然有所謂的 CrawlZilla: https://code.google.com/p/crawlzilla/
我也曾經裝在 DRBL 上好好的玩了一下 ! 應用 Crawlzilla 和 DRBL 到 F102@ILT

至於DRBL-based 的 Hadoop 跟 Solr 則可以參考下面兩篇
但是有些功能用不太到,且需要記錄一些使用者行為 ...
所以只好自己來,那這篇重點在於怎樣在已經在 DRBL 裝好  Hadoop 後再加上 Nutch 和 solr !!!

新增使用者
# useradd nutch
# passwd nutch

切換到 nutch
# su - nutch

下載 nutch 及解壓縮
$ wget ftp://ftp.twaren.net/Unix/Web/apache/nutch/1.7/apache-nutch-1.7-bin.tar.gz
$ tar -zxf apache-nutch-1.7-bin.tar.gz
$ mv apache-nutch-1.7 nutch-1.7
$ mv nutch-1.7/conf ./nutch_conf

這邊再切換回root來複製
# cp /home/hadoop/hadoop-1.2.1/bin/* /home/nutch/nutch-1.7/bin/
# cp /home/hadoop/hadoop-1.2.1/conf/* /home/nutch/nutch_conf

上面的動作主要是把原本 hadoop 執行的相關設定都直接複製一份給 nutch 並且把設定檔跟執行檔分開,也就是以後可以直接刪除 nutch 也不會影響到原本已經正常的 hadoop

接著要做一些相關設定如下

$ vi nutch_conf/hadoop-env.sh



# export JAVA_HOME=/usr/lib/j2sdk1.5-sun
export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.45.x86_64
export HADOOP_HOME=/home/nutch/nutch-1.7
export HADOOP_CONF_DIR=/home/nutch/conf_nutch
export HADOOP_SLAVES=$HADOOP_CONF_DIR/slaves
export NUTCH_HOME=/home/nutch/nutch-1.7
export NUTCH_CONF_DIR=/home/nutch/conf_nutch
export HADOOP_LOG_DIR=/home/nutch/nutch-1.7/logs
export HIVE_CONF_DIR=$HADOOP_CONF_DIR
export HIVE_AUX_JARS_PATH=$HADOOP_HOME/lib
export HADOOP_HOME_WARN_SUPPRESS=1 #不新增會有 " HADOOP_HOME is deprecated " 錯誤



$ vi nutch_conf/core-site.xml



<property>
  <name>fs.default.name</name>
    <value>hdfs://192.168.0.100:9000</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/var/hadoop/nutch</value>
  </property>

$ vi nutch_conf/nutch-site.xml



<property>
  <name>http.agent.name</name>
  <value>nutch</value>
  <description>HTTP 'User-Agent' request header. </description>
</property>

<property>
  <name>plugin.folders</name>
  <value>../nutch-1.7/plugins</value> # 這個沒修正的話會有下面的錯誤
  <description>Directories where nutch plugins are located. </description>
</property>

Error Log 
INFO mapred.JobClient: Task Id : attempt_201312102129_0011_m_000000_0, Status : FAILED
java.lang.RuntimeException: Error in configuring object
        at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:93)
        at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:64)
        at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:117)
        at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:426)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:366)
        at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
        at java.security.AccessController.doPrivileged(Native Method)


接著這邊就是新增你的 client 端
$ vi nutch_conf/slaves



這邊是讓你編修抓取的設定
$ vi nutch_conf/regex-urlfilter.txt
$ cp nutch_conf/regex-urlfilter.txt ./nutch_conf/regex-urlfilter.txt.bak
$ cp nutch_conf/regex-urlfilter.txt ./nutch_conf/crawl-urlfilter.txt




到這邊就用 # drblpush -c /etc/drbl/drblpush.conf 來把設定檔全部複製到每台 client 端

接著請編輯 /etc/hosts,然後請把 server 重新開機,這個動作沒做的話下個指令會出問題


到這邊就可以 format 你的 HDFS 了
nutch-1.7/bin/hadoop namenode -format


接著就可以啟動 nutch 了,但因為是使用 DRBL 所以還要再修正把你的 ssh-key 複製給client以及修改 storage_ID等幾個動作

$ nutch-1.7/bin/start-all.sh

啟動一會後就可以關閉然後繼續修正 namespaceID 不同以及storageID沒出現的問題

$ nutch-1.7/bin/stop-all.sh


$ssh-copy-id kvm101 ... etc..

特別要注意的就是每台機器 storageID 要各為 hostname 而 namespaceID 則要全部一樣

接著要準備開始跟 solr 整合,第一步是要調用 nutch 的 scheml 給 solr 使用
# mv /solr/collection1/conf/schema.xml /solr/collection1/conf/schema.xml.org
# cp /home/nutch/conf_nutch/schema-solr4.xml /solr/collection1/conf/schema.xml

然後編輯這個檔案並且在  </fields> 之前新增一行
# vi /solr/collection1/conf/schema.xml
<field name="content" type="text" stored="true" indexed="true"/>

$ nutch-1.7/bin/nutch crawl urls/urls.txt -solr http://192.168.0.100:8080/solr/collection1 -threads 20 -depth 2 -topN 3

完成這個以後呢 ! 記得注意一下自己的 $HADOOP_HOME 是不是剛剛設置的值
( 我在這邊卡了一個晚上才發現啊 ! Orz)

$  nutch-1.7/bin/hadoop fs -ls
$ nutch-1.7/bin/hadoop fs -ls /user/nutch/crawl-20131212025853


$ nutch-1.7/bin/nutch solrindex http://192.168.0.100:8080/solr/ crawl-20131212025853/crawldb -linkdb crawl-20131212025853/linkdb crawl-20131212025853/segments/*


Error Log

Job 跑了很久後卻失敗了 ? 

reduce 卡在 16%

java.lang.RuntimeException: Error while running command to get file permissions : java.io.IOException: Cannot run program "/bin/ls": error=11, 資源暫時無法取得
 at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
 at org.apache.hadoop.util.Shell.runCommand(Shell.java:200)
 at org.apache.hadoop.util.Shell.run(Shell.java:182)


這個問題搞了我超久的 ... 我前前後後反覆測試跑了兩天吧才找到解法 ... 參考下面說法


答案就是卡在 CentOS 上會有開啟檔案或者是執行線程預設的 1024 的限制 ... 所以需要用 每台機器上下

# ulimit -n 65535

在 /etc/security/limits.conf 最后增加如下

* soft nofile 65535 
* hard nofile 65535

然後確認一下是不是已經變為 65535
# ulimit -n
65535

但只是這樣會發現 CentOS 6.4 下一次重開機後就又變回來 1024,所以編輯這個檔案刪掉 root 上面那行 1024,就可以完整搞定啦 !

# vi /etc/security/limits.d/90-nproc.conf
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

* soft nproc 1024
root       soft    nproc     unlimited


或者說如果出現的訊息是這樣的話
org.apache.solr.common.SolrException: Bad Request
Bad Request
request: http://192.168.0.100:8080/solr/update?wt=javabin&version=2
 at org.apache.solr.client.solrj.impl.CommonsHttpSolrServer.request(CommonsHttpSolrServer.java:430)


http://wiki.apache.org/nutch/NutchTutorial#A6._Integrate_Solr_with_Nutch

參考上面這個的說明是這樣寫的 !!!


或者是在做 index 後你可能發現你的 solr 是空的 ?


仔細看會發現上面的訊息,請編輯下面的檔案並且新增黃底紅字

$ vi conf_nutch/nutch-site.xml
<property>
  <name>plugin.includes</name>
  <value>protocol-(http|httpclient)|urlfilter-regex|parse-(text|html|js|ext|msexcel|mspowerpoint|msword|oo|pdf|rss|swf|zip)|index-(more|basic|anchor)|indexer-solr|query-(more|basic|site|url)|response-(json|xml)|summary-basic|scoring-opic|urlnormalizer-(pass|regex|basic)</value>
  <description> Regular expression naming plugin directory names</description>
 </property>

同時在跑的過程如過另外下 jps 是可以看到這樣的 !
$ jps
20194 JobTracker
22464 Jps
19900 NameNode
20106 SecondaryNameNode
22412 IndexingJob

如果是看 50030 的話可以看到這樣的畫面

完整跑完一個 JOB 應該是下面這樣的畫面的 !


最後再補一些相關指令

$ nutch-1.7/bin/hadoop fs -put ./nutch-1.7/urls/nutn.txt ./   #把檔案上傳到HDFS
$ nutch-1.7/bin/nutch crawl nutn.txt -dir crawlnutn -depth 3 -topN 100  # 開始爬取
$ nutch-1.7/bin/hadoop fs -ls   #檢視 HDFS 的資料
$ nutch-1.7/bin/nutch solrindex http://192.168.0.100:8080/solr/ crawlnutn/crawldb -linkdb crawlnutn/linkdb crawlnutn/segments/*  #把爬取好的資料輸入到 solr 做 index


如果中間發現某一台 client 的 hadoop 掛了可以用這樣來單獨啟動它
[nutch@KVM ~]$ ssh kvm108 nutch-1.7/bin/hadoop-daemon.sh start datanode
starting datanode, logging to /home/nutch/nutch-1.7/libexec/../logs/hadoop-nutch-datanode-KVM108.out
[nutch@KVM ~]$ ssh kvm108 nutch-1.7/bin/hadoop-daemon.sh start tasktracker
starting tasktracker, logging to /home/nutch/nutch-1.7/libexec/../logs/hadoop-nutch-tasktracker-KVM108.out
[nutch@KVM ~]$ ssh kvm108 jps
2611 TaskTracker
2687 Jps
2498 DataNode