SOLR使用手册之优化及拓展
solr性能优化:将索引放在内存中能有效的提升索引和搜索效率
此外大部分solr的性能优化配置都在solrconfig.xml中
主要内容有:使用的lib配置,包含依赖的jar和Solr的一些插件;组件信息配置;索引配置和查询配置,
下面详细说一下索引配置和查询配置.
一.索引配置
属性
描述
useCompoundFile
通过将很多 Lucene 内部文件整合到一个文件来减少使用中的文件的数量。这可有助于减少 Solr 使用的文件句柄数目,代价是降低了性能。除非是应用程序用完了文件句柄,否则 false 的默认值应该就已经足够。
ramBufferSizeMB
在添加或删除文档时,为了减少频繁的更些索引,Solr会选缓存在内存中,当内存中的文件大于设置的值,才会更新到索引库。较大的值可使索引时间变快但会牺牲较多的内存。如两个值同时设置,满足一个就会进行刷新索引.
maxBufferedDocs
mergeFactor
决定低水平的 Lucene 段被合并的频率。较小的值(最小为 2)使用的内存较少但导致的索引时间也更慢。较大的值可使索引时间变快但会牺牲较多的内存。
maxIndexingThreads
indexWriter生成索引时使用的最大线程数
unlockOnStartup
unlockOnStartup 告知 Solr 忽略在多线程环境中用来保护索引的锁定机制。在某些情况下,索引可能会由于不正确的关机或其他错误而一直处于锁定,这就妨碍了添加和更新。将其设置为 true 可以禁用启动锁定,进而允许进行添加和更新。
lockType
single: 在只读索引或是没有其它进程修改索引时使用.
native: 使用操作系统本地文件锁,不能使用多个Solr在同一个JVM中共享一个索引.
simple :使用一个文本文件锁定索引.
二.查询配置
属性
描述
maxBooleanClauses
最大的BooleanQuery数量. 当值超出时,抛出 TooManyClausesException.注意这个是全局的,如果是多个SolrCore都会使用一个值,每个Core里设置不一样的话,会使用最后一个的.
filterCache
filterCache存储了无序的lucene document id集合,1.存储了filter queries(“fq”参数)得到的document id集合结果。2还可用于facet查询3. 如果配置了useFilterForSortedQuery,那么如果查询有filter,则使用filterCache。
queryResultCache
缓存搜索结果,一个文档ID列表
documentCache
缓存Lucene的Document对象,不会自热
fieldValueCache
字段缓存使用文档ID进行快速访问。默认情况下创建fieldValueCache即使这里没有配置。
enableLazyFieldLoading
若应用程序预期只会检索 Document 上少数几个 Field,那么可以将属性设置为 true。延迟加载的一个常见场景大都发生在应用程序返回和显示一系列搜索结果的时候,用户常常会单击其中的一个来查看存储在此索引中的原始文档。初始的显示常常只需要显示很短的一段信息。若考虑到检索大型 Document 的代价,除非必需,否则就应该避免加载整个文档。
queryResultWindowSize
一次查询中存储最多的doc的id数目.
queryResultMaxDocsCached
查询结果doc的最大缓存数量, 例如要求每页显示10条,这里设置是20条,也就是说缓存里总会给你多出10条的数据.让你点示下一页时很快拿到数据.
listener
选项定义 newSearcher 和 firstSearcher 事件,您可以使用这些事件来指定实例化新搜索程序或第一个搜索程序时应该执行哪些查询。如果应用程序期望请求某些特定的查询,那么在创建新搜索程序或第一个搜索程序时就应该反注释这些部分并执行适当的查询。
useColdSearcher
是否使用冷搜索,为false时使用自热后的searcher
maxWarmingSearchers
最大自热searcher数量
queryResultWindowSize
因为查询参数是有start和rows的,所以某个QueryResultKey可能命中了cache,但start和rows却不在cache的
document id set范围内。当然,document id
set是越大命中的概率越大,但这也会很浪费内存,这就需要个参数:queryResultWindowSize来指定document id
set的大小。
queryResultMaxDocsCached
查询结果最大缓存文档数量
通过solr的管理界面可以看到当前缓存的配置及状态:
http://192.168.66.99:8080/solr/#/test_shard1_replica2/plugins/cache
实际场景中需要根据命中率,机器配置等来处理
关于缓存的介绍在单独一篇文章中: http://haiziwoainixx.iyunv.com/admin/blogs/2095473
三.solr拓展
olr是一个可扩展的服务,我们可以添加自己的包和类,在solr已经实现的default处理逻辑之上,再添加我们自己的搜索逻辑。
实现手段就是继承solr的基础类,重写或者改写新的Filter,Search Component以及Request Handler类,来取代solr默认的处理类或者与之并存。
1.定制Request Handler
默认的request handler直接得到你http里url带来的传参,然后就开始根据配置分发任务,
让各自的component去处理查询请求了。定制request handler的好处是,在这个步骤之中,
你可以再额外进行一些别的逻辑处理,比如你可以写写log,在得到SolrQueryRequest后,传入前查看处理一下里面的query,对SolrQueryResponse里得到的数据集再做些处理等等。
定制方式是自己继承StandardRequestHandler类(该类继承了SearchHandler),
package myplugin.handler;
import org.apache.solr.handler.StandardRequestHandler;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
public class MySearchHandler extends StandardRequestHandler {
public void handleRequestBody(SolrQueryRequest request,
SolrQueryResponse response) throws Exception {
super.handleRequestBody(request, response);
//TODO: whatever you want
}
}
并在solrconfig.xml里配置即可起效。
<requestHandler name="/test" class="myplugin.handler.MySearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
<str name="df">usergoods_mix</str>
</lst>
</requestHandler>
别忘了把自己的jar包放到webapp/的WEB-INF的lib目录下。solr也为我们定制了别的handler,比如DisMaxRequestHandler,LukeRequestHandler,MoreLikeThisHandler
和SpellCheckerRequestHandler等等。大家可以自己看看源码,知道他们分别做什么。都在org.apache.solr.handler内。
2.定制search component
对同一个request handler,可以按顺序配置多个search component,这些component会在handler类里各自得到自己的任务,
把SolrQueryRequest和SolrQueryResponse传承下去,在这个过程中,我们可以加入自己的component,定制我们想要的搜索结果和搜索逻辑
我简单把实现代码帖一下,主要还是通过继承基础类,最后配置到solrconfig.xml内。
public class MySearchComponent extends SearchComponent {
String query = null;
@Override
public void prepare(ResponseBuilder rb) throws IOException {
query = rb.req.getParams().get("q", "");
System.out.println("prepare: " + query);
}
@Override
public void process(ResponseBuilder rb) throws IOException {
if (query != null) {
rb.rsp.add("mytest", "zbf"); // <str name="mytest">zbf</str>
//System.out.println("process: " + map.get("mytest").toString());
}
}
@Override
public String getDescription() {
return "MySearchComponent";
}
@Override
public String getSource() {
return "";
}
@Override
public String getSourceId() {
return "";
}
@Override
public String getVersion() {
return "0.1";
}
}
主要就是在prepare()里获取到SolrQueryRequest里的查询query,在process()里自己处理,并且获取到前一次component处理得到的SolrQueryResponse,
里面可能会有已经排好序的查询数据集,你也可以做一些二次处理,简单过滤,重新排序等事情
<requestHandler name="/test" class="myplugin.handler.MySearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
<str name="df">usergoods_mix</str>
</lst>
<arr name="components">
<str>query</str>
<str>myComponent</str>
</arr>
</requestHandler>
<searchComponent name="myComponent" class="myplugin.component.MySearchComponent">
</searchComponent>
先声明自己的searchComponent,然后放入handler里使用起来,注意配置顺序,因为component是按顺序串接起来的。
3.定制Filter
他的作用就是如果你自己定制了Filter,你就可以按自己的方式处理字符串。
可以参考中文分词器的代码实现。
4.定制监听器
参考http://blog.csdn.net/duck_genuine/article/details/7862454
页:
[1]