一、 前提
1. 什么是全文检索
全文检索是一种将文件中所有文本与检索关键词匹配的文字资料检索方法,比如我们将一本书的作者、出版日期、出版社、章节、章节内容都存于数据库中,那么我们输入任何一个词,可以将该书中任意与该此匹配的信息检索出来,我们输入“张三”,可能我们找到的是作者张三,也可能是某章节的一段内容中含有张三。我们在日常生活中用的最多的全文检索莫过于使用Windows的搜素功能,不信?没注意?现在来试试吧!
2. 什么是Solr
Solr是一种企业级的全文检索服务器,对外提供RESTFul风格的API,基于Lucene搜索引擎为内核。我们都知道Lucene是用来做索引的,solr在Lucene基础上做了很多封装和优化。我们在solr上可以随时配置、扩展我们data schema,自由决定我们的field的存储和索引策略,配置我们的分词策略,查询我们需要的数据格式。
3. Lucene
在细说Solr之前,还是先得说说Lucene。Lucene是一个给全文检索服务提供搜素引擎的工具包,它独立于平台且免费开源,目前已经应用到越来越多的系统当中,比如IBM的Eclipse编辑器和其商业的WebSphereWEB服务器软件都采用了Lucene作为其全文搜素功能的引擎。Lucene具有以下几个特点:
1) 独立于平台
2) 已倒排索引为核心算法,索引实现分块和子索引库
3) 面向对象,便于扩展
4) 设计独立于语言和文件格式的文本分析接口,便于扩展;
5) 查询接口丰富;
我们来看下它的架构图:
再看下在应用程序中的应用
4. Solr能干什么
二、 Solr介绍
目前使用的最新版本是Solr4.6.0,下载地址:
http://www.apache.org/dyn/closer.cgi/lucene/solr/4.6.0
1. 架构
2. 功能
1) 索引内容以schema的形式进行灵活配置,字段支持基本类型和自定义类型;
2) 字段支持自定义索引的分词方式;
3) 查询支持多种表达式;
4) 查询支持分页,其实行号和页大小;
5) 查询支持RESTFul风格,支持多种数据响应格式:JSON/xml等;
6) 对于查询结果根据查询关键词,可对字段进行分组统计;
7) 对于查询结果,可根据分词结果进行高亮;
8) 对于查询支持缓存设置;
9) 写数据支持缓存设置和批量写;
10) 写数据支持事务;
11) 删除数据支持指定id删除或表达式删除;
12) 4.x版本上solrcloud支持分布式计算;
13) 集群环境下,支持配置文件集中部署和共享,共享信息保存在zookeeper中;
14) 分布式下支持分片管理,每个分片1个leader节点;
15) 每个leader节点支持多个replicate节点;
16) 单节点支持主从复制;
17) 所有操作记载日志,支持故障恢复
3. Api
1) Ping:获取solr服务状态
例如:http://162.168.1.32:6060/solr/collection1/admin/ping?wt=json
2) 分词:获取在指定字段下进行关键词分析结果
3) 查询:指定关键词查询结果
4) 分组
查询url后拼接facet=on&facet.field=你要分组的字段
5) 高亮
查询url后拼接hl=on&hl.fl=你要高亮的字段
6) 更新
指定id删除:
指定查询表达式删除:
更新指定文档:
http://162.168.1.32:9090/solr/collection1/update?wt=json(POST),数据体
{add:
{
boost: 1,
commitWithin: 1000,
doc: {
rowkey:crd_10193620,
domain:sina.com,
ip:100.100.100.100
},
overwrite: true
}
}
4. SolrJ
请使用最新版本solr-solj-4.6.0,详细代码请参考fulltext工程solr部分:
https://10.45.136.237/svn/ZY/ZTOWLS/branch/V2.0.2/code/web/owls-solr/fulltext
5. 数据测试
1) 服务器配置
Solr服务器:16 CPU,系统30G内存,JVM 2G内存
客户端:2 CPU、系统3G ,JVM 1G内存
2) Solr 存储结构
名称 | 类型 | 是否存储 | 是否必须 | 是否索引 | 分词器 |
Rowkey | String | 是 | 是 | 是 | IK |
Ip | String | 是 | 是 | 是 | IK |
Domain | Text | 是 | 否 | 是 | IK |
Operator | Text | 是 | 否 | 是 | IK |
Address | Text | 是 | 否 | 是 | IK |
3) 测试数据
单条数据采样:
Rowkey | Ip | Domain | Address | Operator |
Cdr_10000000000011 | 192.168.1.1 | - | 江苏省南京市 | 电信 |
详细测试数据
单线程测试环境下1000w条数据 | |
项目 | 存储(MB) / 时间(ms) |
数据复制及导入 | 约18分钟 |
索引存储容量 | 556MB |
查询江苏电信关键字返回数据时间 | 1114ms |
查询江苏联通关键字返回数据时间 | 484ms |
查询江苏移动关键字返回数据时间 | 298ms |
|
|
|
|
单线程测试环境下1亿条数据 | |
项目 | 存储(MB) / 时间(ms) |
数据复制及导入 | 约3.3小时 |
索引存储容量 | 5926MB = 5.7GB |
查询江苏电信关键字返回数据时间 | 11339ms |
查询江苏联通关键字返回数据时间 | 4924ms |
查询江苏移动关键字返回数据时间 | 3078ms |
备注:上面的测试基于solr服务的原始配置,没有经过任何优化。solr服务器启动后由于上下文的加载和句柄连接池的创建等,第一次查询比较耗时,第二次及以后的无缓存数据下的查询为solr服务器的正常响应时间。
三、 Solr集群
从solr4.x版本上支持分布式集群功能,使用hadoop家族的zookeeper作为作为协作调度者,具有以下几个特色功能:
n 集中式的配置信息;
n 自动容错
n 近实时搜索
n 查询自动负载均衡
最新使用的solrCloud是基于Solr4.6版本上的,Zookeeper使用3.4.5版本。
1. 架构
2. Zookeeper
首先你得启动一个zookeeper实例,这里以162.168.1.33:2181部署的实例来说,在单个solr节点WEB容器启动的时间增加下列虚拟机参数:
-DzkRun 运行zookeeper,并且该节点是leader
-DzkHost 集群中zookeeper的服务器位置,多个集群之间用半角英文输入法下的逗号分隔,如162.168.1.33:2181
-Dbootstrap_confdir 集群集中管理的配置信息,如/home/mr/solr/fulltext-solr-data-8080/collection/conf
-Dcollection.configName 集群显示的配置名称,如:yourconfig
-DnumShards 只是集群当中的分片数,即分布式的leader节点数
-DShardId 指定节点所在的分片
-DzkClientTimeout 连接集群zookeeper的超时时间
3. 分片
在solrcloud中,所有分布式节点以片的形式存在,每个分片独自管理自己的数据和计算。在每个分片中有且必须有个leader节点,可有多个replicate节点,可以指定节点所在的分片。当某leader节点宕机后,zookeeper会选择当前分片下的一个活动的replicate节点来作为新的leader节点服务。通过集群环境写数据时,数据会被均匀的负载到各分片节点上。
4. 复制
在生产环境中,我们不能抱着每个分片主节点的稳定性,因此当一个leader节点宕机后,就应该由其备份节点来提供服务,提供容错机制。
首先在leader节点的solrconfig.xml配置上增加配置:
将enable配置为true,默认为false。配置<str name=”replicateAfter”>节点只是复制除非机制,commit--在数据提交后复制,startup--在leader服务启动后就复制。
其次在slave复制节点solrconfig.xml配置上增加配置:
将enable配置为true,默认为false。配置<str name=”masterUrl”>为master节点所在地址。
Solrconfig.xml中所有配置支持配置文件配置,在solrcore.properties中配置你要写入的配置:
5. 数据测试
1) 集群配置
Zookeeper[162.168.1.33]:16 CPU,系统30G内存
Solr主节点[162.168.1.33]:16 CPU,系统30G内存,JVM 2G内存
Solr节点[162.168.1.32]:16 CPU,系统32G内存,JVM 2G内存
客户端:2 CPU、系统3G ,JVM 1G内存
2) Solr存储
名称 | 类型 | 是否存储 | 是否必须 | 是否索引 | 分词器 |
Rowkey | String | 是 | 是 | 是 | IK |
Ip | String | 是 | 是 | 是 | IK |
Domain | Text | 是 | 否 | 是 | IK |
Operator | Text | 是 | 否 | 是 | IK |
Address | Text | 是 | 否 | 是 | IK |
3) 测试数据
单条数据采样:
Rowkey | Ip | Domain | Address | Operator |
Cdr_10000000000011 | 192.168.1.1 | - | 江苏省南京市 | 电信 |
详细测试数据
单线程测试环境下1亿条数据 | |
项目 | 存储(MB) / 时间(ms) |
数据复制及导入 | 约3.8小时 |
索引存储容量 | 162.168.1.32 3011MB 162.168.1.33 3008MB 总存储大约5.8GB |
查询江苏电信关键字返回数据时间 | 7082ms |
查询江苏联通关键字返回数据时间 | 3328ms |
查询江苏移动关键字返回数据时间 | 2038ms |