zoukankan      html  css  js  c++  java
  • nutch和solr建立搜索引擎基础(单机版)

    nutch和solr建立搜索引擎基础(单机版)

    Nutch[1] 是一个开源Java实现的搜索引擎,它提供了我们运行自己的搜索引擎所需的全部工具,包括全文搜索和Web爬虫。
    Solr[2]是一个基于Lucene的全文搜索服务器,它对外提供类似于Web-service的API查询接口,是一款非常优秀的全文搜索引擎。

    为什么要整合nutch和solr?

    简单地讲,nutch重在提供数据源采集(Web爬虫)能力,轻全文搜索(lucene)能力;solr是lucene的扩展,亦是nutch的全文搜索的扩展。重在将nutch的爬取结果,通过其对外提供检索服务。

    一、版本选择

    1. nutch-1.13

    支持hadoop,可以通过hadoop,获得分布式爬虫的能力。本文重点介绍nutch的原力,关于分布式爬虫,将在后续章节中介绍。另外,nutch-2.x系列支持hbase,可以根据自身的需要灵活选择。需要说明的是两版的用法是不同的,nutch-2.x要更为复杂。在使用nutch-2.x之前,最好具备nutch-1.x的基础。

    2. Solr-6.6.0

    截止发稿时是最新版本,可参考官网的解释,这里没什么要说的。

    二、安装环境准备

    1. 系统环境

    Ubuntu14.04x64 或 Centos6.5x64, 应用程序采用二进制安装,不要求编译环境

    2. java环境

    vim /etc/profile
    # set for java
    export JAVA_HOME=/opt/jdk1.8.0_111  #二进制包已经解压安装到该路径
    export PATH=$PATH:$JAVA_HOME/bin
    export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib
    export _JAVA_OPTIONS="­Xmx2048m ­XX:MaxPermSize=512m ­Djava.awt.headless=true"
    

    注:java的安装方法选择二进制包即可,本文不再赘述

    3. nutch+solr环境

    vim /etc/profile
    export NUTCH_RUNTIME_HOME='/opt/apache-nutch-1.13'
    export PATH=$NUTCH_RUNTIME_HOME/bin:$PATH
    export APACHE_SOLR_HOME='/opt/solr-6.6.0'    #单引号不能少
    export PATH=$APACHE_SOLR_HOME/bin:$PATH
    export CLASSPATH=.:$CLASSPATH:$APACHE_SOLR_HOME/server/lib
    

    source /etc/profile #加载到环境

    三、solr的安装与配置

    solr的安装(二进制包)

    wget http://mirror.bit.edu.cn/apache/lucene/solr/6.6.0/solr-6.6.0.tgz
    cat solr-6.6.0.tgz |(cd /opt; tar xzfp -)
    solr status  #注:如果执行结果不正常,执行`source /etc/profile`和检查该文件的内容
    No Solr nodes are running.
    #启动solr服务
    solr start -force   #-force:强制以root身份执行,生产环境请勿使用该参数
    #停止solr服务
    solr stop
    

    安装完毕。

    solr的配置

    cd ${APACHE_SOLR_HOME}
    cp -r server/solr/configsets/basic_configs server/solr/configsets/nutch
    cp ${NUTCH_RUNTIME_HOME}/conf/schema.xml server/solr/configsets/nutch/conf
    mv server/solr/configsets/nutch/conf/managed-schema server/solr/configsets/nutch/conf/managed-schema.backup
    #启动solr服务
    solr start
    #创建nutch core
    solr create -c nutch -d server/solr/configsets/nutch/conf/ -force #-force:强制以root身份执行,生产环境请勿使用该参数
    
    创建过程并非一帆风顺,整个过程充满了各种bug,从这个角度考虑,生产环境中有必要更换到solr的稳定版,好在这些坑已经趟过:
    
    问题1:Caused by: Unknown parameters: {enablePositionInc rements=true}
    具体信息:
    Copying configuration to new core instance directory:
    /opt/solr-6.6.0/server/solr/nutch
    Creating new core 'nutch' using command:
    http://localhost:8983/solr/admin/cores?action=CREATE&name=nutch&instanceDir=nutch
    ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: Unknown parameters: {enablePositionIncrements=true}
    解决办法:
    vim  server/solr/configsets/nutch/conf/schema.xml 找到并去掉enablePositionIncrements=true
    
    问题2:ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: defaultSearchField has been deprecated and is incompatible with configs with luceneMatchVersion >= 6.6.0.  Use 'df' on requests instead.
    解决办法:
    vim server/solr/configsets/nutch/conf/solrconfig.xml 将luceneMatchVersion版本修改为6.2.0
    
    问题3:org.apache.solr.common.SolrException: fieldType 'booleans' not found in the schema
    解决办法:
    vim /opt/solr-6.6.0/server/solr/configsets/nutch/conf/solrconfig.xml
    找到booleans,替换成boolean,如下:
    <lst name="typeMapping">
        <str name="valueClass">java.lang.Boolean</str>
        <str name="fieldType">boolean</str>
    </lst>
    Then it will work..
    
    问题3以后,会发生多起类似事件,如下:
    ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: fieldType 'tdates' not found in the schema
    ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: fieldType 'tlongs' not found in the schema
    ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: fieldType 'tdoubles' not f ound in the schema
    参照问题3的方法,一次性去掉''中关键字的复数形式即可。
    
    问题4:ERROR:
    Core 'nutch' already exists!
    Checked core existence using Core API command:
    http://localhost:8983/solr/admin/cores?action=STATUS&core=nutch
    解决办法:
    solr delete -c nutch       #删除core 'nutch'
    如果删除完,还提示这个错误,这是由于每次修改完配置文件,需要重启下solr服务,更新下状态。
    
    最终的执行结果:
    solr create -c nutch -d server/solr/configsets/nutch/conf/ -force
    Copying configuration to new core instance directory:
    /opt/solr-6.6.0/server/solr/nutch
    
    Creating new core 'nutch' using command:
    http://localhost:8983/solr/admin/cores?action=CREATE&name=nutch&instanceDir=nutch
    
    {
      "responseHeader":{
        "status":0,
        "QTime":3408},
      "core":"nutch"}
    执行成功!
    
    在浏览器中访问
    http://localhost:8983/solr/#/
    可以看到名称为nutch的core
    

    solr的安全设置

    1. realm.properties

    cd /opt/solr-6.6.0/server
    cat etc/realm.properties
    #
    # 这个文件定义用户名,密码和角色
    #
    # 格式如下
    #  <username>: <password>[,<rolename> ...]
    #
    #userName: password,role
    yourname: yourpass,admin
    

    2. solr-jetty-context.xml

    cat contexts/solr-jetty-context.xml
    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
    <Configure class="org.eclipse.jetty.webapp.WebAppContext">
      <Set name="contextPath"><Property name="hostContext" default="/solr"/></Set>
      <Set name="war"><Property name="jetty.base"/>/solr-webapp/webapp</Set>
      <Set name="defaultsDescriptor"><Property name="jetty.base"/>/etc/webdefault.xml</Set>
      <Set name="extractWAR">false</Set>
      <Get name="securityHandler">
        <Set name="loginService">
            <New class="org.eclipse.jetty.security.HashLoginService">
                <Set name="name">Solr Admin Access</Set>
                <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
            </New>
        </Set>
      </Get>
    </Configure>
    

    3. WEB-INF/web.xml

    vim solr-webapp/webapp/WEB-INF/web.xml
      <!-- Get rid of error message -->
      <security-constraint>
        ...
      </security-constraint>
    
      <security-constraint>
        <web-resource-collection>
            <web-resource-name>Solr auth enticated application</web-resource-name>  <!--描述-->
            <url-pattern>/</url-pattern>  <!-- 验证的网页的位置-->
          </web-resource-collection>
           <auth-constraint>
              <role-name>admin</role-name>  <!-- 验证的角色,别写成用户名,如有多个角色可以写多个role-name 标签-->
           </auth-constraint>
       </security-constraint>
       <login-config>
              <auth-method>BASIC</auth-method>  <!-- 关键-->
              <realm-name>Solr Admin Access</realm-name>
      </login-config>
    
    </web-app>
    
    重启solr服务
    solr stop && solr start -force
    
    在浏览器中访问solr
    http://localhost:8983/solr/nutch/
    可以看到要求登录的界面
    

    四、nutch的安装与配置

    nutch的安装(二进制包)

    wget http://mirrors.hust.edu.cn/apache/nutch/1.13/apache-nutch-1.13-bin.tar.gz
    cat apache-nutch-1.13-bin.tar.gz |(cd /opt; tar xzfp -)
    nutch -help   #注:如果执行结果不正常,执行`source /etc/profile`和检查该文件的内容
    

    安装完毕。

    nutch的配置

    以爬取http://nutch.apache.org站点为例,配置如下:

    1. 配置nutch-site.xml

    vim $NUTCH_RUNTIME_HOME/conf/nutch-site.xml
    <property>
     <name>http.agent.name</name>
     <value>My Nutch Spider</value>
    </property>
    
    #配置indexer-solr插件
    #我的方法是替换indexer-elastic为indexer-solr插件
    sed -i 's/indexer-elastic/indexer-solr/g' $NUTCH_RUNTIME_HOME/conf/nutch-site.xml
    #注意:官方文档不是像我这样做的,请按照我的方法配置,或者注释掉indexer-elastic,否则会深受其害,踩坑过程后面会说
    

    2. 建立URL列表

    #为方便修改配置文件,选择conf文件夹作为数据的存储路径
    cd $NUTCH_RUNTIME_HOME/conf
    mkdir -p urls       #存储要爬取的URLS列表,每行只写一个url,可以多行
    cd urls
    echo 'http://nutch.apache.org/' > seed.txt  #地址可以是静态的链接,也可以是动态的链接
    

    3. 设置url的正则匹配规则

    vim regex-urlfilter.txt
    将光标移到文件末尾,将下列内容:
    # accept anything else
    +.
    替换为:
    # accept anything else
     +^http://([a-z0-9]*.)*nutch.apache.org/ #这将包含带有域名前缀的url,比如,http://3w.nutch.apache.org
    

    4. 允许抓取动态内容

    vim crawl-urlfilter.txt regex-urlfilter.txt

    替换:
      # skip URLs containing certain characters as probable queries, etc.
      -[?*!@=]
    为:
      # accept URLs containing certain characters as probable queries, etc.
      +[?=&]
    

    注: conf下有各种配置文件,涉及各种爬取规则和正则过滤器。将在后续的文章中详细说明

    五、爬取和检索的过程

    1. nutch爬取程序的概念组成

    抓取程序自动在用户指定目录下面建立爬取目录,其目录下可以看到crawldb,segments,linkdb子目录

    1. crawldb(爬虫数据库)

    crawldb目录下面存放下载的URL,以及下载的日期、过期时间

    2. linkdb-链接数据库

    linkdb目录存放URL的关联关系,是下载完成后分析时创建的,通过这个关联关系可以实现类似google的pagerank功能

    3. segments-一组分片

    segments目录存储抓取的页面,这些页面是根据层级关系分片的。既segments下面子目录的个数与获取页面的层数有关系,如果指定“-depth”参数是10层,这个目录下就有10层,结构清晰并防止文件过大。
    segments目录里面有6个子目录,分别是:

    “crawl_generate” 生成要获取的一组URL的名字,既生成待下载的URL的集合
    “crawl_fetch” 包含获取每个UR L的状态
    ”content“ 包含从每个URL检索的原始内容
    “parse_text” 包含每个URL的解析文本(存放每个解析过的URL的文本内容)
    “parse_data” 包含从每个URL分析的外部链接和元数据
    “crawl_parse” 包含用于更新crawldb的outlink URL(外部链接库)
    

    2. nutch的爬取流程说明

    爬取过程包括

    injector -> generator -> fetcher -> parseSegment -> updateCrawleDB -> Invert links -> Index -> DeleteDuplicates -> IndexMerger
    
    1. 根据之前建好的URL列表文件,将URL集注入crawldb数据库---inject
    2. 根据crawldb数据库创建抓取列表---generate
    3. 执行抓取,获取网页信息---fetch
    4. 执行解析,解析网页信息---parse
    5. 更新数据库,把获取到的页面信息存入数据库中---updatedb
    6. 重复进行2~4的步骤,直到预先设定的抓取深度。---这个循环过程被称为“产生/抓取/更新”循环
    7. 根据sengments的内容更新linkdb数据库---invertlinks
    8. 建立索引---index
    

    3. solr查询流程包括

    1. 用户通过用户接口进行查询操作
    2. 将用户查询转化为solr查询
    3. 从索引库中提取满足用户检索需求的结果集

    六、爬取和检索的实例

    1. Inject

    nutch inject crawl/crawldb urls

    2. Generate

    nutch generate crawl/crawldb crawl/segments

    3. Fetching

    s1=`ls -d crawl/segments/2* | tail -1`
    echo $s1
    nutch fetch $s1
    

    4. Parse

    nutch parse $s1

    5. updatedb

    nutch updatedb crawl/crawldb $s1

    6. 循环抓取

    重复2-4的过程,抓取下一层页面
    演示过程中,为了节约时间,我们约定一个参数,只抓取前 top 1000 的页面

    nutch generate crawl/crawldb crawl/segments -topN 1000
    s2=`ls -d crawl/segments/2* | tail -1`
    echo $s2
    nutch fetch $s2
    nutch parse $s2
    

    updatedb:
    nutch updatedb crawl/crawldb $s2

    重复2-4的过程,抓取下下层的页面
    同样只取前1000个页面进行抓取

    nutch generate crawl/crawldb crawl/segments -topN 1000
    s3=`ls -d crawl/segments/2* | tail -1`
    echo $s3
    nutch fetch $s3
    nutch parse $s3
    

    updatedb:
    nutch updatedb crawl/crawldb $s3

    这样我们总共抓取了三个层级深度的页面

    ls crawl/segments/
    20170816191100  20170816191415  20170816192100
    

    nutch invertlinks crawl/linkdb -dir crawl/segments

    8. Indexing into Apache Solr(推送solr index)

    nutch index -Dsolr.server.url=http://用户名:密码@localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deleteGone
    #这里的“用户名:密码”是solr的jetty下的
    值得一提的是,如果按照官方标准语法,上面命令会变为:
    nutch index -Dsolr.auth.username="yourname" -Dsolr.auth.password="yourpassword" -Dsolr.server.url=http://localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deleteGone
    这里会提示语法错误,在官网和google上还没有更好的解决办法。我已经把上面的方法更新到
    http://lucene.472066.n3.nabble.com/Nutch-authentication-problem-to-solr-td4251336.html#a4351038
    可能其它版本没有这个问题。
    最终的推送结果如下:
    nutch index -Dsolr.server.url=http://xxx:xxx@localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deleteGone
    Segment dir is co mplete: crawl/segments/20170816191100.
    Indexer: starting at 2017-08-17 18:22:26
    Indexer: deleting gone documents: true
    Indexer: URL filtering: true
    Indexer: URL normalizing: true
    Active IndexWriters :
    SOLRIndexWriter
    	solr.server.url : URL of the SOLR instance
    	solr.zookeeper.hosts : URL of the Zookeeper quorum
    	solr.commit.size : buffer size when sending to SOLR (default 1000)
    	solr.mapping.file : name of the mapping file for fields (default solrindex-mapping.xml)
    	solr.auth : use authentication (default false)
    	solr.auth.username : username for authentication
    	solr.auth.password : password for authentication
    
    
    Indexing 1/1 documents
    Deleting 0 documents
    Indexer: number of documents indexed, deleted, or skipped:
    Indexer:      1  indexed (add/update)
    Indexer: finished at 2017-08-17 18:22:32, elapsed: 00:00:05
    

    9. 在solr上查询

    在浏览器中访问solr
    http://localhost:8983/solr/

    10. 通过脚本自动完成1-9

    crawl -i -D solr.server.url=http://用户名:密码@localhost:8983/solr/ urls/ crawl/ 2

    参考

    https://wiki.apache.org/nutch/NutchTutorial#Install_Nutch
    [1]https://wiki.apache.org/nutch/
    [2]https://wiki.apache.org/solr/

    本文系作者原创,转载请注明出处。如您阅读的是转载,请最好再看下原文,原文随时会更新和勘误的。

    @Gordon_chang
    1997年毕业于北京联合大学,先后在中国万网,新媒传信,亚信等公司工作,现在在一家创业型公司担任云计算与大数据运维方面的 PM & Engineer。 专注于以下四个领域: 分布式存储 分布式数据库 云计算 大数据 重点通过技术架构与性能优化(底层)实现基于私有云的大数据平台能力

  • 相关阅读:
    网络中常用的各种协议(针对TCP/IP协议组)
    报错注入小技巧
    2017swpu-ctf总结
    2017EIS高校运维大赛ctf wirteup
    discuz 3.x ssrf分析
    ssrf漏洞分析
    xxe漏洞分析
    phpcms9.6 注入分析
    74cms漏洞分析
    关于npm
  • 原文地址:https://www.cnblogs.com/gordonchang/p/7421076.html
Copyright © 2011-2022 走看看