Solr在Linux中的产品化安装
目前服务器上安装的solr版本:5.3.1,不同于测试和研究,如果要把solr产品化部署,需要将其安装成一个服务。在solr压缩包中的bin/目录下有一个脚本文件**install_solr_service.sh**,负责solr的安装,并注册为自启动的service。
1. 环境准备
首先需要创建一个solr用户,并赋予其相应的权限:
groupadd zpsolr
useradd -g zpsolr zpsolr
passwd zpsolr
chown -R zpsolr:zpsolr /var/solr /usr/local/solrcloud/
同时也建立两个目录,用于将solr的安装文件与动态文件区分出来:
-
/var/solr, 动态文件目录,存在索引数据,日志等,与solr的安装目录不同,便于以后管理和升级
-
/usr/local/solrcloud,使用脚本安装时的缺省安装目录,安装文件会自动为solr目录建立一个软链接,指向对应的solr安装目录,便于以后的升级(solr -> /usr/local/solrcloud/solr-5.3.1)
此时/usr/local目录的文件类似下面的结构:
lrwxrwxrwx. 1 zpsolr zpsolr 31 12月 11 18:20 solr -> /usr/local/solrcloud/solr-5.3.1
drwxr-xr-x. 9 zpsolr zpsolr 4096 12月 11 18:20 solr-5.3.1
drwxr-xr-x. 3 zpsolr zpsolr 4096 12月 11 01:27 tmp
drwxr-xr-x. 4 zpsolr zpsolr 4096 12月 11 00:57 zookeeper
2. 安装服务脚本
solr中提供了在服务器上安装solr服务的相关脚本,注意需要root权限才可以安装成功:
sudo bash ./bin/install_solr_service.sh ../solr-5.3.1.tgz -i /usr/local/solrcloud -d /var/solr -u zpsolr -s solr -p 8983
这里就指定了solr安装目录,数据和配置文件目录,使用用户,服务名称以及默认http端口等信息,其中的solr脚本参数说明:
- -d 动态文件目录,缺省为“/var/solr”
- -i solr加压安装目录,缺省为“/opt”
- -p 工作/监听端口,缺省为“8983”
- -s 安装成Linus服务的名字,缺省为“solr”
- -u 运行solr的用户名,如果用户不存在,会自动创建,缺省为“solr”
服务安装完成后,就可以通过service的方式来对solr服务进行启动/停止操作:
sudo service solr start/stop/status ...
3. solr基本目录结构
├── data
│ ├── brand
│ │ ├── core.properties
│ │ └── data(solr索引数据目录)
│ ├── conf
│ │ └── dataimport.properties
│ ├── lib
│ │ ├── mmseg4j-core-1.10.0.jar
│ │ ├── mmseg4j-solr-2.3.0.jar
│ │ ├── mysql-connector-java-5.1.37.jar
│ │ ├── solr-1.0.0.jar
│ │ ├── solr-dataimporthandler-5.3.1.jar
│ │ └── solr-dataimporthandler-extras-5.3.1.jar
│ ├── solr.xml
├── logs
│ ├── solr-8983-console.log
│ ├── solr_gc.log
│ ├── solr.log
├── log4j.properties
├── logs
├── solr-8983.pid
└── solr.in.sh
3.1 solr.in.sh
该文件用户配置solr启动的模式,对应的java虚拟机参数等信息,对应的solrHome等信息:
SOLR_PID_DIR=/var/solr
SOLR_HOME=/var/solr/data
LOG4J_PROPS=/var/solr/log4j.properties
SOLR_LOGS_DIR=/var/solr/logs
SOLR_PORT=8983
solr从5版本后就已经加入了集群模式,在solr.in.sh文件中配置ZK_HOST,就会以solrCloud模式启动,不同的solr节点可以注册到同一个zookeeper目录上,这样就会组成一个集群。
3.2 data
data目录中存放了比较关键的各个collection配置,每个collection以文件夹的方式存放,collection中存放了对应的配置目录以及数据目录,配置目录中会存在对应的描述文件。
但如果是solrCloud模式,collection是统一建立的,而且在建立之前必须要将所有的配置事先上传到zookeeper上,对于上传和下载collection,可以使用solrcloud中提供的脚本就可以:
/usr/local/solrcloud/solr/server/scripts/cloud-scripts/zkcli.sh -zkhost 127.0.0.1:9983 -cmd upconfig -confname my_new_config -confdir server/solr/configsets/basic_configs/conf
/usr/local/solrcloud/solr/server/scripts/cloud-scripts/zkcli.sh -cmd downconfig -zkhost 192.168.1.162:2181,192.168.1.163:2181,192.168.1.165:2181/solrcloud -confname evaluation -confdir .
单机模式下,配置文件仅存放在data/conf目录下即可。
4. Solr整体结构
一般情况下,solr与其他应用集成的应用场景如下图所示:
内容关系系统中从数据源(一般为Database)获得数据,索引至solr服务中,便于终端用户使用solr服务从文档列表中查询出对应的信息。
Solr中提供了 RestAPI, 可用于常用的solr操作,例如典型的 创建collection,增加replica,增加shard等,基本的url为:http://:/solr。
每个solr实例中,都有一个solr.xml文件,指定了Solr Server的实例位置,对于每个solr core,都存在
- core.properties:为每个core定义其名称,属于哪个集合(collection);
- conf/solrconfig.xml,控制更高的行为,可以指定其他位置来存储数据信息;
- conf/schema.xml,在5.5版本中已经更名为managed-schema,其中描述了需要solr索引的内容配置,在其中可以将一个Document定义为多个field的属性集合,这些field属性定义了solr处理器如何处理field值以及query field值;
- data目录中包含了各种索引后的文件。
注意在SolrCloud模式中,并没有包含conf目录,这些被保存在了zookeeper中以便能够夸服务器使用。
从Solr的视角来看,基本的信息单元是文档Document,文档是由一部分描述信息组成,具体来说,是一些字段的集合。而字段可以包含不同类型的数据,具体化到一双鞋子的名称,颜色,尺码,都属于这个鞋子(Document)的字段(Field)。
当向Solr中增加一个文档(Document),Solr就会提取文档中的字段(Field)信息,并将其保存至索引(Index)中;当真正执行查询时,Solr就会可以快速地查询索引(index)并返回匹配的记录。
4.1 Field Analysis
就是solr如何对传进来的数据进行处理,如构建索引。假设有个个人简介的Field,他里面包括了很多单词,我们需要在构建索引完之后,通过检索某个单词就能查询到这个人,那么我们就需要对每个单词都进行索引,但是,一句话有很多语气助词,如果 a an or and not ,这些词我们又不需要为他们建索引,在构建索引的时候,需要排除出去。哪些单词我们要建索引,那些又不需要建立,这个分析的过程我们称为Field Analysis。
4.2 Field Type
solr如何去处理某个field的数据,以及这个Field在查询的时候处理。一个Field Type包括如下四部分信息:
- 名字,name;
- 实现类名,也就是solr中真正的类型的类名;
- 如果FieldType是TextFiled类型,即还有analysis属性;
- 属性;
拷贝字段(copy field),可以将所有的全文字段复制到一个字段中,便于后续对其进行统一的检索处理;你可能想让document的一些字段可以多次使用。solr 有一个字段复制机制,可以提交多个不同类型字段集中到一个字段。字段复制主要涉及两个概念,source和destination,一个是要复制的字段,另一个是要复制到哪个字段。其实说的简单一点,比如现在你要查询包涵“Java”的博客, 那么你肯定要查内容,标题是否包含Java,但是solr不能像SQL那样,where tittle like ‘%Java%’ or content like ‘%Java%’. 这个时候copyField就派上用场了, 定义一个新字段,将title和content 复制到这个新字段,索引的时候,直接从这个新字段查询,这样就达到目地了。 这便是copyField的典型应用场景。
动态字段(dynamic field),可以不用指定具体字段的名称,只要定义字段名称的规则,例如name为 *_i
,那么所有以_i结尾的字段都符合该定义。动态字段(Dynamic fields)允许 solr 索引没有在 schema 中明确定义的字段。这个在忘记定义一些字段时很有用。动态字段可以让系统更灵活,通用性更强。动态字段和常规字段类似,除了它名字中包含一个通配符外,在索引文档时,一个字段如果在常规字段中没有匹配时,将到动态字段中匹配。假设schema中定义了一个叫*_i
的动态动态字段,如果要索引一个叫 cost_i 的字段,但是 schema 中不存在 cost_i 的字段,这样 cost_i 将被索引到*_i
字段中。动态字段也是定义在 schema.xml 文件中,和其他字段一样,它也有个名词,字段类型,和属性。
4.3 schema.xml文件
schema.xml这个配置文件的根本目的是为了通过配置告诉Solr如何建立索引,而到了V5版本,该文件已经被conf/managed-schema代替,文件的格式是一样的。
solr的数据结构如下:
* document:一个文档、一条记录
* field:域、属性
solr通过搜索某个或某些field,返回若干个符合条件的document,或者按搜索的score排序返回。如果跟数据库对比,document相当于数据库的表,field相当于表中的字段。而schema.xml就是为了定义一个表的结构(定义各个field的名字、类型、约束、等等)。
schema.xml的基本结构如下:
<schema>
<types>
<fields>
<uniqueKey>
<copyField>
</schema>
常用的配置说明:
- field:定义一个document中的各个fields
- name:必填。该field的名字。前后都有下划线的name是系统保留的名字,比如“_version_”
- type:必填。类型,对应于fieldType的name
- default:该field的缺省值
- indexed:true/false,是否为该field建立索引,以让用户可以搜索它、统计它(facet)
- stored:true/false,定义这个field是否可以返回给查询者
- multiValued:true/false,是否可以容纳多个值(比如多个copyField的dest指向它)。如果是true,则该field不能被排序、不能作为uniqueKey
- required:true/false,告诉solr这个field是否接受空值,缺省为false
- docValues:true/false,建立document-to-value索引,以提高某些特殊搜索的效率(排序、统计、高亮)
copyField:把一个field的内容拷贝到另外一个field中。一般用来把几个不同的field copy到同一个field中,以方便只对一个field进行搜索 - source:被拷贝的field,支持用通配符指定多个field,比如:*_name
- dest:拷贝到的目的field
- maxChars:最大字符数
uniqueKey:指定一个field为唯一索引
fieldType:定义field的类型,包括下面一些属性 - name:必填,被field配置使用
- class:必填,filedType的实现类。solr.TextField是路径缩写,“等价于”org.apache.solr.schema.TextField"
- multiValued:?
- positionIncrementGap:指定mutiValued的距离
- ananlyzer:如果class是solr.TextField,这个配置是必填的。告诉solr如何处理某些单词、如何分词,比如要不要去掉“a”,要不要全部变成小写……
- type:index或query
- tokenizer:分词器,比如:StandardTokenizerFactory
- filter:过滤器,比如:LowerCaseFilterFactory
dynamicField:用通配符定义一个field来存在没有被field定义的漏网之鱼 - name:使用通配符,比如“*_i”,来处理类似“cost_i”之类的field
4.4 理解分析器(Analysers),分词器(Tokenizers)和过滤器(Filters)
字段分析器在文档(document)被索引时,以及查询发生时被调用。分析器会检查文本中的字段,产生token流;分词器可以将一段文本数据分解成词汇单元,或者token;过滤器可以检查一段token流并决定是否做一些保留,转换,抛弃,分解等行为,分词器和过滤器可以以某种顺序(管道或是链条)来组合成分析器。
对于文本数据(solr.TextField),solr在建立索引和搜索的时候需要拆分它们、并做一些相应的处理(比如英文要去掉介词、转成小写、单词原形化等,中文要恰当地要分词)。这些工作,一般由Analyzers、Tokenizers、和Filter来实现,这些都是在fieldType中进行配置的。
- ananlyzer:告诉solr在建立索引和搜索的时候,如何处理text类型的内容,比如要不要去掉“a”、去掉介词、去掉复数,要不要全部变成小写等等……它在schema.xml文件中配置,可以直接指定一个类给它;也可以由tokenizer和filter的组合来实现;
- type:可选参数,index或query,表名这个配置是在建立索引还是在搜索的时候使用;
- tokenizer:分词器,比如:StandardTokenizerFactory;
- filter:过滤器,比如:LowerCaseFilterFactory,小写转换;
Analyzer负责把文本field转成token流,然后自己处理、或调用Tokenzier和Filter进一步处理,Tokenizer和Filter是同等级和顺序执行的关系,一个处理完后交给下一个处理。
Tokenizer和Filter的区别:
- Tokenizer:接收text(通过从solr那里获得一个reader来读取文本),拆分成tokens,输出token stream
- Filter:接收token stream,对每个token进行处理(比如:替换、丢弃、不理),输出token stream
因此,在配置文件中,Tokenizer放在第一位,Filter放在第二位直到最后一位。
一个Tokenizer处理文本的例子:
输入:"Please, email john.doe@foo.com by 03-09, re: m37-xq."
输出:"Please", "email", "john.doe", "foo.com", "by", "03", "09", "re", "m37", "xq"
5. Solr数据导入
DIH用于从数据库中抓取数据并创建索引,其中包括一系列相关的概念:
- Datasource:数据源,包括获取数据必需的信息:数据位置(url)、数据库driver、登录账号和密码
- Entity:相当于数据库的一个视图,可以从一个表或联表查询获得
- Processor:数据处理器,负责从数据源中获取数据、处理、然后加入到索引中
- Transformer:数据转换器,可选,负责修改数据、创建新的field、或根据需要把一条记录变成多条记录
要使用data import handler,首先需要在solrconfig.xml中添加requestHandler(从命名来看,requestHandler更像是用于请求处理器,提供暴露solr向外的服务接口, /dataimport跟/select属于平级)。
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">db-data-config.xml</str>
</lst>
</requestHandler>
config参数负责指定DIH配置文件的位置,如果需要添加jar包依赖,需要在该文件中增加lib标签:
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-.*\.jar" />
DIH配置文件的格式为:
根节点:
- dataSource
- type: 数据源类型,如:JdbcDataSource(缺省值),采用SqlEntityProcessor
- driver: 数据库驱动,如:com.mysql.jdbc.Driver
- convertType:
- url: 数据库url
- user: 你懂的
- password: 你懂的
- document
- entity
- name: 随便起的一个标志,可以给嵌套的entity使用,比如${item.id}(假设name=“item”)
- query: 拉取所有数据的语句
- deltaQuery: 拉取delta数据的语句,如:deltaQuery=“select * from xxx where last_modified > ‘${dataimporter.last_index_time}’”
- field: 指定 dataSource 的 field 和 solr 的field的对应关系,如:
- entity: 嵌套的entity,定义一些一对多的数据。可以使用父entity的name作为条件,比如:where item_id=‘${item.id}’
- transformer: 指定transformer对象,多个的话用逗号分开
- entity
通过HTTP请求(POST或GET)执行各种DIH操作:请求格式:http://:/ solr/ / dataimport? command=,其中的各种如下:
- abort:停止当前正在进行的操作
- delta-import:调用deltaQuery拉取数据。可以带上几个额外的参数:&clean=true&commit=true等等(和full_import相同)
- full-import:调用query拉取所有数据。请求会马上返回,后台有新线程执行重建索引的操作。可以通过status操作查询状态。额外参数:
- clean:缺省为true。是否在开始重建索引前清除旧索引
- commit:缺省为true。是否提交操作请求
- debug:缺省为false。debug模式,不会commit操作。如果同时需要commit,得带上commit=true参数
- entity:缺省为所有的entity。可以指定某一个或多个entity
- optimize:缺省为true。是否需要在完成操作后优化索引
- reload-config:如果修改了配置文件,执行这个命令使它生效
- status:返回各种统计数据、以及DIH的当前状态
6. SolrCloud迁移数据
如果将solrCloud向solr单点迁移的话,比较简单,直接将在zookeeper上的配置download到本地,将其放在在本地保存到conf目录即可(注意,zk的目录结构与本地会有所不同),然后在solr.in.sh中去掉ZK_HOST一行或将其注释掉,重启即可。
但如果将solr单点组成solrCloud,会有所不同,而且也会比较麻烦,原因是组成的solrCloud集群可能会有一些服务器明明可以提供服务,但在clusterstatus中会显示失败(down状态),此时就需要先将replica删除。
在api中可以先删除replica,注意需要提供replica name,在本地文件中的 core.properties,
name=brand_brand_replica1
shard=brand
collection=brand
coreNodeName=core_node2
其中coreNodeName就是对应的replicaName,通过REST API中的DELETE URL即可。
对于solr服务节点,均为CPU消耗型,最好部署在8核CPU上,其中在solr.in.sh中JVM_OPTS设置为3096M(不可以设置过大,否则会导致一次FullGC的过程太慢)。
下一篇: 发热的食物应该吃什么好
推荐阅读
-
在Linux系统中的时间转化方法详细介绍
-
在PHP中运行Linux命令并启动SSH服务的例子
-
在VMware虚拟机中安装redhat linux操作系统图文详解教程
-
在VMware虚拟机中安装Linux(Fedora16)的方法
-
虚拟机中的Linux安装VMware Tools的方法
-
虚拟机VMware中安装VMware Tools for Linux的方法(Fedora16)
-
在VMware中为Linux系统安装vmware tools的详解教程
-
在win10和linux上分别安装Python虚拟环境的方法步骤
-
Linux下Docker CE使用从包中安装的方式详解
-
linux下安装tomcat安装及配置教程(在linux中怎么安装tomcat)