背景
目前在公司,实现solr的一个菜名推荐模块的时候,遇到了一个困扰了好几天的问题,就是当实现了模块的逻辑代码并确认功能实现后,在部署测试后发现了一个bug,就是多次查询结果均重复第一次查询的结果。
问题排查
首先想到是不是之后的几次查询并没有真正调用到实现的逻辑,所以在本地IDEA中远程调试服务器上代码,发现当在solr中查询时,确实进入到逻辑代码中打得断点,而且确实传递了不同的query参数到方法中,只是返回的结果依旧不符合预期,只是重复第一次的结果。
再次考虑到是不是solr的某些缓存机制,将多条查询结果识别为了同一条,并直接返回了缓存中的结果。想到这个结果后,我开始了漫长的单步调试过程,希望定位到可能有问题的代码中,并同时在查找关于solr缓存的相关内容。
最后在solr的conf文件中,定位到了相关缓存代码
<query>
<maxBooleanClauses>1024</maxBooleanClauses>
<filterCache class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<!-- 加上这段,会有多次查询结果相同的问题-->
<queryResultCache class="solr.LRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<documentCache class="solr.LRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<cache name="perSegFilter"
class="solr.search.LRUCache"
size="10"
initialSize="0"
autowarmCount="10"
regenerator="solr.NoOpRegenerator" />
测试时发现当删掉中间标注的一段时,查询正常,所以确认是由于queryResultCache缓存将不同的query判断为同一个key,所以之后的查询均直接调用第一次缓存的结果。
发现这个结果后,查看queryResultCache的key是由什么确定的。
package org.apache.solr.search;
public QueryResultKey(Query query, List<Query> filters, Sort sort, int nc_flags) {
this.query = query;
this.sort = sort;
this.filters = filters;
this.nc_flags = nc_flags;
int h = query.hashCode();
Query filt;
if(filters != null) {
for(Iterator var6 = filters.iterator(); var6.hasNext(); h += filt.hashCode()) {
filt = (Query)var6.next();
}
}
this.sfields = this.sort != null?this.sort.getSort():defaultSort;
SortField[] var10 = this.sfields;
int var11 = var10.length;
for(int var8 = 0; var8 < var11; ++var8) {
SortField sf = var10[var8];
h = h * 29 + sf.hashCode();
}
this.hc = h;
}
以上就是queryResultCache的key的定义类,其中key的hashcode就是hc属性。由定义可知,
int h = query.hashCode();
this.hc = h;
,经过单步调试,发现不同的query查询后,在此处得到的hc都是一样的,所以精确定位了问题出在自定义的query的hashcode生成中。
FreqQuery entends bitQuery extends Query
在超类Query中,定义方法
@Override
public int hashCode() {
return getClass().hashCode();
}
继承的子类均没有覆写hashcode()方法,所以每个query的hashcode均相同。
定位问题后,修改方法也就很简单了,在FreqQuery中覆写此方法,注意做到各query的区分,同时也要保证相同query能命中缓存,此处我采用query的hashcode作为query的hashcode。修改完成后,提交代码,部署应用,发现结果和预期相同了。
远程调试的教程
https://www.cnblogs.com/wy2325/p/5600232.html
浅谈solr缓存
http://www.cnblogs.com/phinecos/archive/2012/05/24/2517018.html
分享到:
相关推荐
配置solr出现404,试过很多方法解决不了,这有配置好的现成的,在wen.xml中将solrhome路径改成你创建的solrhome的路径
NULL 博文链接:https://gcgmh.iteye.com/blog/434772
solr创建索引并查询,希望能够帮助有需要的人。。。
NULL 博文链接:https://mozhenghua.iteye.com/blog/2275318
视频详细讲解,需要的小伙伴自行网盘下载,链接见附件,永久有效。 Solr它是一种开放源码的...4.Solr缓存 5.Spring Data Solr 章节五:综合案例,电商网站搜索页面 1.关键字搜索 2.搜索面板展示 3.分页 4.排序 5.高亮
6.Solr缓存 18 6.1 filterCache 18 6.2 queryResultCache 18 6.3 documentCache 19 7.solrj wiki 19 7.1 SolrJ/Solr cross-version compatibility 19 7.2 Setting the classpath 20 7.2.1 Maven 20 7.3 ...
solr一部分常见的问题及解决方法
solr查询语法,solr常用查询语法汇总。
Solr是一个开源搜索平台,用于构建搜索应用程序。Solr可以和Hadoop一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,...
solr乱码解决方法,excel文件,贴图说明。
主要讲解了 solr客户端如何调用带账号密码的solr服务器调用,实现添加索引和查询索引,以及分组查询
solr.warsolr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包...
solr
6.8 Query Response Compression 57 6.9 Embedded vs HTTP Post 57 6.10 RAM Usage Considerations(内存方面的考虑) 57 6.10.1 OutOfMemoryErrors 57 6.10.2 Memory allocated to the Java VM 57 7 FAQ 58 7.1 ...
支持solr5.5 solr6.0中IK分词需要的资料
solr
函数查询(Function Query)-通过关于一个域的数值或顺序的函数对打分进行影响 性能优化 1.2.4 核心 可插拔的查询句柄(Query Handler)和可扩展的 XML 数据格式 使用唯一键的域能够增强文档唯一性 能够...
SolrQueryComponent 轻松构建Solr查询 SolrQueryComponent使用查询构建器API帮助构建Solr / Lucene / ElasticSearch查询。 它独立于具体的客户端库,并且可以与或。...use InterNations \ Component \ Solr \ Query \
使用java实现solr-7.1.0的api和solr最新支持的sql查询.使用java实现solr-7.1.0的api和solr最新支持的sql查询.
http://blog.csdn.net/pztyz314151/article/details/52027519 中图片visio制作