solr

来源:互联网 发布:2015年珠三角经济数据 编辑:程序博客网 时间:2024/06/07 11:39

概述

        Solr是基于Lucene(Solr版本基本也是随着Lucene走)开发的一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引,也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果.(网上有个solr教程,看完就对Solr有个大致的了解,结合教程学习Solr(6.5.1))

       了解Solr,先了解下搜索引擎是如何工作的.搜索引擎功能的总体体现图



          搜索应用程序需要执行的一些操作:

  • 获取原始内容 : 任何搜索应用程序的第一步是收集要进行搜索的目标内容  
  • 构建文档 : 从原始内容构建文档,让搜索应用程序可以很容易地理解和解释
  • 分析文档 : 在索引开始之前,将对文档进行分析.
  • 索引文档 : 当文档被构建和分析后,下一步是对它们建立索引,以便可以基于特定键而不是文档的全部内容来检索该文档.索引类似于在书开始页或末尾处的目录索引,其中常见单词以其页码显示,使得这些单词可以快速跟踪,而不是搜索整本书.
  • 用于搜索的用户接口 : 当索引数据库就绪,应用程序可以执行搜索操作.为了帮助用户进行搜索,应用必须提供用户接口,用户可以在其中输入文本并启动搜索过程
  • 构建查询 : 当用户做出搜索文本的请求,应用程序应该使用该文本来准备查询对象,然后可以使用该查询对象来查询索引数据库以获得相关的细节.
  • 搜索查询 : 使用查询对象,检查索引数据库以获取相关详细信息和内容文档.
  • 渲染结果 : 当收到所需的结果,应用程序应决定如何使用其用户界面向用户显示结果.


Solr详解

 Solr架构


         以下是Apache Solr的主要构建块(组件)

  • 请求处理程序 - 发送到Apache Solr的请求由这些请求处理程序处理.请求可以是查询请求或索引更新请求.根据这些请示的要求来选择请求处理程序.为了将请求传递给Solr,通常将处理器映射到某个URI端点,并且它将为指定的请求提供服务.
  • 搜索组件 - 搜索组件是Apache Solr中提供的搜索类型(功能).它可能是拼写检查,查询,构面,命中突出显示等.这些搜索组件被注册为搜索处理程序.多个组件可以注册到搜索处理程序.
  • 查询解析器 − Apache Solr查询解析器解析传递给Solr的查询,并验证查询的语法是否有错误.解析查询后.将它们转换为Lucene理解的格式.
  • 响应写入器 - Apache Solr中的响应写入器是为用户查询生成格式化输出的组件. Solr支持XML,JSON,CSV等响应格式.对每种类型的响应都有不同的响应写.
  • 分析器/分词器 - Lucene以令牌的形式识别数据.Apache Solr分析内容,将其分成令牌,并将这些令牌传递给Lucene.Apache Solr中的分析器检查字段的文本并生成令牌流.分词器将分析器准备的令牌流分解成令牌.
  • 更新请求处理器 - 每当向Apache Solr发送更新请求时,请求都通过一组称为更新请求处理器的插件(签名,日志记录,索引)运行.这个处理器负责修改,例如删除字段,添加字段等.

Solr术语

一般术语

     实例 - 就像一个tomcat实例或一个jetty实例,这个术语指的是在JVM中运行的应用程序服务器.Solr主目录提供对每个这些Solr实例的引用,一个或多个核心可以配置在每个实例中运行.

  • 核心(core) - 在应用程序中运行多个索引时,可以在每个实例中拥有多个核心,而不是每个核心的多个实例

  • 主目录(home) - 术语$SOLR_HOME是指主目录,其中包含有关内核及其索引,配置和依赖关系的所有信息

  • 碎片(Shard) - 在分布式环境中,数据在多个Solr实例之间进行分区,其中每个数据块可以称为碎片(Shard).它包含整个索引的子集.

SolrCloud术语

     SolrCloud指的在分布式环境中安装Solr,Solr以主从模式安装,在分布式环境下,索引在主服务器上创建,并且将其复制到一个或多个从服务器.

  • 节点(Node) - 在Solr云中,Solr的每个单个实例都被视为一个节点
  • 集群 - Solr云环境中的所有节点组合在一起构成集群
  • 集合 - 集群具有称为集合的逻辑索引
  • 碎片 - 碎片是集合的一部分,它具有一个或多个索引副本
  • 副本 - 在Solr Core中,在节点中运行的分片副本称为副本
  • 领导者(Leader) - 它也是碎片的副本,它将Solr Cloud的请求分发给剩余的副本
  • Zookeeper - 这是一个Apache项目,Solr Cloud用于集中配置和协调,管理集群和选择领导者

配置文件

  • solr.xml - 它是包含Solr Cloud相关信息,此文件是在$SOLR_HOME目录中.为了加载核心,Solr引用这个文件,这有助于识别它们.
  • solrconfig.xml − 此文件包含与请求处理和响应格式化相关的定义,核心特定配置,以及索引,配置,管理内存和提交.$SOLR_HOME目录中
  • managed-schema − 此文件包含整个模式以及字段和字段类型.$SOLR_HOME目录中
  • core.properties - 此文件包含特定于核心的配置.它被引用为核心发现,因为它包含核心的名称和数据目录的路径.它可以在任何目录中使用,会将此目录它视为核心目录。

Solr单机

搭建core

      solr入门
      Solr5版本之后,其自己内置一个jetty web服务(solr-webapp目录下),下载solr.zip解压之后,启动便可访问.
      环境:JDK1.8+Solr6.5.1
  • 使用命令行进入solr-6.5.1\bin下执行solr start,则启动成功,会给出提示Solr running on port 8983--(solr相关命令)
  • 访问http://localhost:8983 则进出solr操作页面
  • 创建core: 执行命令solr create -c jcg -d basic_configs    (参照solr-6.5.1\server\solr\configsets\basic_configs 生成一个core,或者直接将拷贝basic_configs到制定dir用通过ui的core amdin添加)
        在ui界面core admin栏可看到jcg的core,一个简单的core搭建完成.创建core的基本命令如下:
  1. -c <name> -要创建的核心或集合的名称(必需)。
  2. -d <confdir> -配置目录,在SolrCloud模式非常有用。
  3. -n <configName> -配置名称。这将默认为核心或集合的名称。
  4. -p <port> -本地Solr的实例的端口发送create命令; 默认脚本试图通过寻找运行Solr的实例来检测端口。
  5. -s <shards> -Number of shards to split a collection into, default is 1.
  6. -rf <replicas> -集合中的每个文件的份数。默认值是1。

安装索引

       本次示例使用示例solr-6.5.1\example\exampledocs 下的book.csv作为数据源进行索引,在solr-6.5.1\server\solr\jcg\conf下的managed-schema文件中创建Field约束
    <uniqueKey>id</uniqueKey><!-- Fields added for books.csv load--><field name="cat" type="text_general" indexed="true" stored="true"/><field name="name" type="text_general" indexed="true" stored="true"/><field name="price" type="tdouble" indexed="true" stored="true"/><field name="inStock" type="boolean" indexed="true" stored="true"/><field name="author" type="text_general" indexed="true" stored="true"/>
         book.scv中的字段有id,cat,name,price,inStock,author,series_t,sequence_i,genre_s,其中后面三个属于动态field配置,在managed-schema已经配置好
  <dynamicField name="*_i"  type="int"    indexed="true"  stored="true"/>    <dynamicField name="*_is" type="ints"    indexed="true"  stored="true"/>    <dynamicField name="*_s"  type="string"  indexed="true"  stored="true" />    <dynamicField name="*_ss" type="strings"  indexed="true"  stored="true"/>    <dynamicField name="*_l"  type="long"   indexed="true"  stored="true"/>    <dynamicField name="*_ls" type="longs"   indexed="true"  stored="true"/>    <dynamicField name="*_t"   type="text_general" indexed="true" stored="true"/>    <dynamicField name="*_txt" type="text_general" indexed="true" stored="true"/>    <dynamicField name="*_b"  type="boolean" indexed="true" stored="true"/>    <dynamicField name="*_bs" type="booleans" indexed="true" stored="true"/>    <dynamicField name="*_f"  type="float"  indexed="true"  stored="true"/>    <dynamicField name="*_fs" type="floats"  indexed="true"  stored="true"/>    <dynamicField name="*_d"  type="double" indexed="true"  stored="true"/>    <dynamicField name="*_ds" type="doubles" indexed="true"  stored="true"/>.......
          因为修改了managed-schema,所以需要从其solr服务,进入bin 目录下solr stop -all,solr start
          solr提供了一个操作添加索引的工具类simpleposttool(C:\Users\admin\Desktop\solr\solr-6.5.1\example\exampledocs\post.jar),进入post.jar所在目录,执行

         java -Dtype=text/csv -Durl=http://localhost:8983/solr/jcg/update  -jar post.jar   books.csv
         关于post.jar,java -jar post.jar -h 命令查看帮助(命令参考).
         执行完毕ui界面查看jcp 下的Overview就可以看到Statistics中看到统计的Num Docs = 10,即导入成功
         还有一种直接通过ui界面,在jcp 下Documents 中选择类型csv,输入数据上传即可(注意第一行必须是列名)

ui界面的基本使用

         solr有个admin ui操作界面,操作简单易上手,值得拥有.比较关注的就是core里面的Query列

  • Request-Handler(qt): Request Handler in solrConfig.xml
  • q: 查询字符串(必须的),查询语法与lucene相似
  • fq: filter query 过滤查询.使用Filter Query可以充分利用Filter Query Cache,提高检索性能.作用:在q查询符合结果中同时是fq查询符合的(类似求交集),例如:q=mm&fq=date_time:[20081001 TO 20091031],找关键字mm,并且date_time是20081001到20091031之间的
  • sort: 排序.格式如下:字段名 排序方式;如advertiserId desc 表示按id字段降序排列查询结果
  • start,rows:表示查回结果从第几条数据开始显示,共显示多少条
  • fl: field list.指定查询结果返回哪些字段.多个时以空格“ ”或逗号“,”分隔.不指定时,默认全返回
  • df: default field默认的查询字段,一般默认指定。
  • Raw Query Parameters:key1=val1&key2=val2 格式
  • wt: write type.指定查询输出结果格式,我们常用的有json格式与xml格式.在solrconfig.xml中定义了查询输出格式:xml、json、python、ruby、php、phps、custom
  • indent: 返回的结果是否缩进,默认关闭,用 indent=true " on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。
  • debugQuery: 设置返回结果是否显示Debug信息。
  • hl: high light 高亮.hl=true表示启用高亮
  • hl.fl : 用空格或逗号隔开的字段列表(指定高亮的字段).要启用某个字段的highlight功能,就得保证该字段在schema中是stored.如果该参数未被给出,那么就会高 亮默认字段 standard handler会用df参数,dismax字段用qf参数.你可以使用星号去方便的高亮所有字段.如果你使用了通配符,那么要考虑启用 hl.requiredFieldMatch选项
  • hl.simple.pre:高亮前缀
  • hl.simple.pre : 高亮后缀
  • hl.requireFieldMatch: 如果置为tru,除非该字段的查询结果不为空才会被高亮.它的默认值是false,意味 着它可能匹配某个字段却高亮一个不同的字段.如果hl.fl使用了通配符,那么就要启用该参数.尽管如此,如果你的查询是all字段(可能是使用 copy-field 指令),那么还是把它设为false,这样搜索结果能表明哪个字段的查询文本未被找到
  • hl.usePhraseHighlighter:如果一个查询中含有短语(引号框起来的)那么会保证一定要完全匹配短语的才会被高亮
  • hl.highlightMultiTerm:如果使用通配符和模糊搜索,那么会确保与通配符匹配的term会高亮.默认为false,同时hl.usePhraseHighlighter要为true
  • facet:分组统计,在搜索关键字的同时,能够按照Facet的字段进行分组并统计
  • facet.query:Facet Query利用类似于filter query的语法提供了更为灵活的Facet.通过facet.query参数,可以对任意字段进行筛选
  • facet.field:需要分组统计的字段,可以多个
  • facet.prefix: 表示Facet字段值的前缀.比如facet.field=cpu&facet.prefix=Intel,那么对cpu字段进行Facet查询,返回的cpu都是以Intel开头的,AMD开头的cpu型号将不会被统计在内
  • spellcheck: 拼写检查

分词器

       solr分词在managed-schema中配置,已中文分词SmartChineseAnalyzer为例,下载lucene-analyzers-smartcn-6.5.1.jar放入solr-6.5.1\server\solr-webapp\webapp\WEB-INF\lib目录下,在managed-schema最后添加分词
 <!--测试分词-->    <fieldType name="text_china" class="solr.TextField">          <analyzer class="org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer"/>      </fieldType>    
        重启solr, 然后test


SolrCloud

    参考SolrCloud

     SolrCloud基本概念:

  • Cluster集群:一组Solr节点,逻辑上作为一个单元进行管理,整个集群使用同一套Schema和SolrConfig
  • Node节点:一个运行Solr的JVM实例
  • Collection:在SolrCloud集群中逻辑意义上的完整的索引,常常被划分为一个或多个Shard.这些Shard使用相同的config set,如果Shard数超过一个,那么索引方案就是分布式索引
  • Core:也就是Solr Core,一个Solr中包含一个或者多个SolrCore,每个Solr Core可以独立提供索引和查询功能,Solr Core额提出是为了增加管理灵活性和共用资源.SolrCloud中使用的配置是在Zookeeper中的,而传统的Solr Core的配置文件是在磁盘上的配置目录中
  • Config Set:Solr Core提供服务必须的一组配置文件,每个Config Set有一个名字.必须包含solrconfig.xml和schema.xml,初次之外,依据这两个文件的配置内容,可能还需要包含其他文件.Config Set存储在Zookeeper中,可以重新上传或者使用upconfig命令进行更新,可以用Solr的启动参数bootstrap_confdir进行初始化或者更新
  • Shard分片:Collection的逻辑分片.每个Shard被分成一个或者多个replicas,通过选举确定那个是Leader
  • Replica:Shard的一个拷贝.每个Replica存在于Solr的一个Core中
  • Leader:赢得选举的Shard replicas,每个Shard有多个replicas,这几个Replicas需要选举确定一个Leader.选举可以发生在任何时间.当进行索引操作时,SolrCloud将索引操作请求传到此Shard对应的leader,leader再分发它们到全部Shard的replicas.

SolrCloud中完整索引(Collection)的逻辑图

       在SolrCloud模式下,Collection是访问Cluster的入口.Collection是一个逻辑存在的东西,可以跨Node,在任意节点上都可以访问Collection.Shard也是逻辑存在的.因此Shard也是可以跨Node的,一个Shard下面可以包含0个或者多个replica,但1个Shard下面只能包含一个leader

SolrCloud的工作模式

     SolrCloud中包含有多个Solr Instance,而每个Solr Instance中包含有多个Solr Core,Solr Core对应着一个可访问的Solr索引资源Replica,当Solr Client通过Collection访问Solr集群的时候,便可以通过Shard分片找到对应的replica即SolrCore,从而就可以访问索引文档了


搭建solr

      本次搭建使用从数据中读取数据

搭建solr 连接数据库conf

  • 拷贝server\solr\configsets\data_driven_schema_configs下的conf文件夹在configsets目录下
  • 数据库建表
Create TableCREATE TABLE `t` (  `id` int(11) NOT NULL auto_increment,  `name` varchar(20) default NULL,  `number` varchar(20) default NULL,  `update_time` datetime default NULL,  PRIMARY KEY  (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8
修改solrconfig.xml
   <!--lib下添加  --> <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-.*\.jar" />   <!--requestHandler下添加  --> <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">        <lst name="defaults">           <str name="config">data-config.xml</str>        </lst>   </requestHandler>  
  • 修改managed-schema
     <!--field下添加,分别对应数据库--><field name="name" type="string" indexed="true" stored="true"/><field name="number" type="int" indexed="true" stored="false"/><field name="updateTime" type="date" indexed="true" stored="true"/>  
  • 新建data-config.xml
<?xml version="1.0" encoding="UTF-8"?>  <dataConfig>      <dataSource name="source1" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/test" user="root" password="123" batchSize="-1" />    <document>          <entity name="t" pk="id"  dataSource="source1"                   query="select * from  t"                  deltaImportQuery="select * from t where id='${dih.delta.id}'"                  deltaQuery="select id from t where updateTime> '${dataimporter.last_index_time}'">             <field column="id" name="id"/>           <field column="name" name="name"/>             <field column="number" name="number"/>             <field column="update_time" name="updateTime"/>       </entity>    </document>  </dataConfig>
  • 添加mysql-connector-java-5.1.39.jar至server\solr-webapp\webapp\WEB-INF\lib(因为用ui界面导入数据,需要此包,注意版本,有的版本jar会报错)
         对data-config.xml一些说明:
  • dataSource是数据库数据源.Entity就是一张表对应的实体,pk是主键,query是查询语句.Field对应一个字段,column是数据库里的column名,后面的name属性对应着Solr的Filed的名字.其中solrdata是数据库名,t是表名
  • 其中deltaQuery是增量索引,原理是从数据库中根据deltaQuery指定的SQL语句查询出所有需要增量导入的数据的ID号.然后根据deltaImportQuery指定的SQL语句返回所有这些ID的数据,即为这次增量导入所要处理的数据.核心思想是:通过内置变量“${dih.delta.id}”和 “${dataimporter.last_index_time}”来记录本次要索引的id和最近一次索引的时间

搭建zookeeper集群(三台zookeeper):

  • 下载zookeeper.zip(我用的3.4.10版本),解压
  • 将conf目录下zoo_sample.cfg更改为zoo.cfg
  • 修改zoo.cfg内容(clientPort要不相同,三个分别问2181,2182,2183)
#dataDir=/data:内存数据库快照地址,事务日志地址(除非由 dataLogDir 另行指定)#dataLogDir=/datalog:事务日志目录,可以使用专用的设备,以避免事务日志与快照之间的竞争。#server.x=[hostname]:nnnnn[:nnnnn], etc#集群配置中,在dataDir目录下必须有一个myid文件,其中的值就是数字x,范围是1-255。第一个nnnnn是与leader通讯使用,第二个nnnnn是选举leader使用,electionAlg等于0时不需要此参数dataDir=C:/Users/admin/Desktop/solr/zookeeper1/dataclientPort=2181server.1=127.0.0.1:20881:30881server.2=127.0.0.1:20882:30882server.3=127.0.0.1:20883:30883
  • 在data目录下新建一个myid文件(三个zookeeper分表为1,2,3)
  • 按照以上做法另外复制两份
        为防止防火墙的干扰,关闭防火墙,依次进入bin 目录启动zookeeper(zkServer.cmd start),注:要查看zookeeper处于leader还是follower可借用nc.exe,将nc.exe放置C:\Windows\System32目录下,cmd执行echo stat|nc 127.0.0.1 2181查看其返回的mode即可

搭建solrCloud(三台solr)

  • 进入solr bin目录下修改solr.in.cmd修改端口号(一次为8983.8984,8985)与zk_host
set SOLR_PORT=8983set ZK_HOST=127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
  • 创建config set 并更新至zookeeper,进入solr 的server\scripts\cloud-scripts目录下,执行zkcli -zkhost 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183 -cmd upconfig -confdir ..\..\solr\configsets\conf -confname configB
参数简介:zkhost   zookeeper的服务地址cmd命令类型confdir配置的目录confname配置名称
  • 检查zookeeper的存储情况,进入zookeeper的bin 目录下执行
zkCli -server 127.0.0.1:2181ls /configs/newconfig可以看到configB
  • 按照以上(只需操作第一步即可)另外复制两份
  • 启动一个solr(solr start -cloud) 创建collection,可使用http的形式,或者使用ui界面,使用url形式,执行:http://localhost:8984/solr/admin/collections?action=CREATE&name=collB&numShards=3&replicationFactor=3&collection.configName=configB&maxShardsPerNode=9
name:将被创建的集合的名字numShards:集合创建时需要创建逻辑碎片的个数replicationFactor:分片的副本数.replicationFactor(复制因子)为 3 意思是每个逻辑碎片将有 3 份副本maxShardsPerNode:默认值为1,每个Solr服务器节点上最大分片数(4.2新增的)注意三个数值:numShards、replicationFactor、liveSolrNode(当前存活的solr节点),一个正常的solrCloud集群不容许同一个liveSolrNode上部署同一个shard的多个replic,因此当maxShardsPerNode=1时,numShards*replicationFactor>liveSolrNode时,报错。因此正确时因满足以下条件:numShards*replicationFactor<liveSolrNode*maxShardsPerNodecreateNodeSet:如果不提供该参数,那么会在所有活跃节点上面创建core,如果提供该参数就会在指定的solr节点上创建core
       在solr目录下会生成replica1 也就是一个core,每个core都存储有数据(同一个shard下存储相同),不同的shard存储不同(分布式存储)

  • 导入数据,http://localhost:8983/solr/#/collB/dataimport//dataimport,执行Execute
       对以上部署需要注意一些细节注意:
  • 在一个solr1上创建collection,在其他solr服务可以访问(生成solr1的代理,因此solr1必须开启)
  • 在solr1上创建的collection,其存储只会存在在solr1服务器上,其他solr服务生成solr1的代理进行访问
  • 生成的shard多个时,则为分布式索引,请求是转发给每个shard,对shard响应进行汇总返回.设置shard数量也十分重要(主要针对大索引)
  • 一个collection对应一个config set,创建的replica(包括备份)存在一个solr服务器上(分布式索引并不跨服务器),因此需要考虑对同一个collection在多个solr上同时部署
  • 生成的一个个replica相当与一个个core(只有一个shard时,多个shard则不同),同一个shard下replica存储内容是一样的,有一个leader,其余为备份


     最终的效果


     查询:http://localhost:8983/solr/#/collB/query  执行Execute Query 会查询相应数据,其查询基本流程