Java SOLR 7+;/Lucene 7&x2B;以及DelegatingCollector和PostFilter的性能问题
这就是我面临的情况 我正在从SOLR 4迁移到SOLR 7。 SOLR 4在Tomcat 8上运行,SOLR 7在内置Jetty 9上运行。 最大的核心包含约1800000个文档(约3GB) 迁移进行得很顺利。但有些事困扰着我 我有一个PostFilter,根据预先选择的列表只收集一些文档。 以下是org.apache.solr.search.DelegatingCollector的代码:Java SOLR 7+;/Lucene 7&x2B;以及DelegatingCollector和PostFilter的性能问题,java,solr,lucene,Java,Solr,Lucene,这就是我面临的情况 我正在从SOLR 4迁移到SOLR 7。 SOLR 4在Tomcat 8上运行,SOLR 7在内置Jetty 9上运行。 最大的核心包含约1800000个文档(约3GB) 迁移进行得很顺利。但有些事困扰着我 我有一个PostFilter,根据预先选择的列表只收集一些文档。 以下是org.apache.solr.search.DelegatingCollector的代码: @Override protected void doSetNextReader(LeafReaderCo
@Override
protected void doSetNextReader(LeafReaderContext context) throws IOException {
this.reader = context.reader();
super.doSetNextReader(context);
}
@Override
public void collect(int docNumber) throws IOException {
if (null != this.reader && isValid(this.reader.document(docNumber).get("customid")))
{
super.collect(docNumber);
}
}
private boolean isValid(String customId) {
boolean valid = false;
if (null != customMap) // HashMap<String, String>, contains the custom IDs to keep. Contains an average of 2k items
{
valid = customMap.get(customId) != null;
}
return valid;
}
因此,问题是:
它在SOLR 4上运行得非常快,平均QTime等于30。
但现在在SOLR 7上,速度非常慢,平均QTime大约为25000强>
我想知道是什么原因导致了如此糟糕的表现
使用非常简化的(或者我应该说是透明的)collect函数(见下文),不会出现降级。此测试只是为了将服务器/平台从等式中排除
@Override
public void collect(int docNumber) throws IOException {
super.collect(docNumber);
}
我的猜测是,自从Lucene7以来,API访问文档的方式发生了巨大的变化,但我不确定是否理解了所有内容。
我从这篇文章中得到:
我想这与我所面临的问题有关。
但我不知道如何升级/更改我的PostFilter和/或DelegatingCollector以恢复良好的性能
如果任何LUCENE/SOLR专家能够提供一些提示或线索,我们将不胜感激。
提前谢谢
附言:
在核心模式中:
<field name="customid" type="string" indexed="true" stored="true" required="true" multiValued="false" />
现在QTime的平均值降到了1100,这比Solr4好得多,但距离我使用Solr4时的30还要远
不确定是否有可能进一步改进,但任何其他建议/意见仍然非常受欢迎。
/干杯使用筛选查询而不是后期筛选 这个答案并不试图提高后置过滤器的性能,而是使用了一种不同的方法。然而,我得到的结果(因子10)比对后过滤器的任何改进都要好 在此处签出我的代码: 增加
maxboolean子句
访问您的solrconfig.xml。添加或调整
元素包含值为10024的子元素maxbooleansclauses
10024
这将允许您添加大型筛选器查询,而不是后期筛选器
将所有CustomID添加为筛选器查询
这个查询非常庞大,但性能要好得多
fq=customid:(0_001 1_001 2_001 3_001 4_001 5_001 ... 4999_001 5000_001)
与后过滤器相比,执行时间的比较
post filter需要5.000个ID 320毫秒,而filter查询则需要22毫秒才能获得相同数量的ID。根据Toke Eskildsen关于Solr用户邮件列表的建议,在一个与您的问题非常类似的线程中,我得到了从300毫秒到100毫秒的响应时间。请随意链接到邮件列表。也许他们还有进一步的建议 这些措施是最有效的
- 在
dosetnextrader
- 使用
获取上述信息org.apache.lucene.index.DocValues
- 在解析查询期间,将给定的
对象预处理为字符串
org.apache.lucene.util.BytesRef
public DelegatingCollector getFilterCollector(索引搜索器搜索器){
返回新的DelegatingCollector(){
私有分类的DDOCVALUES分类的DDOCVALUES;
@凌驾
受保护的void dosetnextrader(LeafReaderContext上下文)引发IOException{
super.dosetnextrader(上下文);
//存储对SortedDocValue的引用
//使用org.apache.lucene.index.DocValues来执行此操作
sortedDocValues=DocValues.getSorted(context.reader(),“customid”);
}
@凌驾
公共void collect(int docNumber)引发IOException{
if(sortedDocValues.advanceExact(docNumber)&&isValid(sortedDocValues.binaryValue())){
super.collect(单据号);
}
}
私有布尔值isValid(BytesRef customId){
返回customSet.contains(customId);
}
};
}
在QParserPlugin
的扩展中,我将给定的字符串
转换为org.apache.lucene.util.BytesRef
@覆盖
公共QParser createParser(字符串qstr、SolrParams localParams、SolrParams params、SolrQueryRequest req){
返回新的QParser(qstr、localParams、params、req){
@凌驾
公共查询解析()抛出语法错误{
intidcount=localParams.getInt(“count”,2000);
HashSet customSet=新的HashSet(idCount);
对于(int id=0;id
您是否尝试连接探查器并查看时间花在哪里?这会让你对问题的根本原因有一个很好的了解。谢谢你的建议。我无法完全分析虚拟机,所以我尝试用日志查找内容。。。实际上是这个.reader.document(docNumber).get(“customid”)
部分占用了大部分处理时间。在调试模式下运行查询时,所有的时间都花在process.query部分。我已经用collect函数的新代码编辑了这个问题。事情进展得更快,但仍然比SOLR/Lucene的上一个版本慢。我试图复制您的问题,但没有成功。请检查我的来源:或者张贴一个减少的样本与问题,你有。感谢有一个研究这一点。你的消息来源看起来和我的差不多。我在你的测试中看到你正在添加180000个文档。您可以使用1800000个文档重试吗?(这大约是我的Solr core中的数量……所有索引文件夹的重量约为3 GB)。
<queryParser name="MyPostFilter" class="solrpostfilter.MyQueryPaser"/>
@Override
public void collect(int docNumber) throws IOException {
if (null != reader)
{
SortedDocValues sortedDocValues = reader.getSortedDocValues("customid");
if (sortedDocValues.advanceExact(docNumber) && isValid(sortedDocValues.binaryValue().utf8ToString()))
{
super.collect(docNumber);
}
}
}
fq=customid:(0_001 1_001 2_001 3_001 4_001 5_001 ... 4999_001 5000_001)