知识点
相关文章
更多最近更新
更多solr4.0 的缓存策略
2019-03-27 01:00|来源: 网路
solr的缓存策略分3种
LRUCache:使用LinkedHashMap来保存缓存,覆盖了removeEldestEntry方法,并提供了预热方法:
public void warm(SolrIndexSearcher searcher, SolrCache<K,V> old) { if (regenerator==null) return; long warmingStartTime = System.currentTimeMillis(); LRUCache<K,V> other = (LRUCache<K,V>)old; // warm entries if (isAutowarmingOn()) { Object[] keys,vals = null; // Don't do the autowarming in the synchronized block, just pull out the keys and values.
// 先获取旧缓存的锁 再导入
synchronized (other.map) { int sz = autowarm.getWarmCount(other.map.size()); keys = new Object[sz]; vals = new Object[sz]; Iterator<Map.Entry<K, V>> iter = other.map.entrySet().iterator(); // iteration goes from oldest (least recently used) to most recently used, // so we need to skip over the oldest entries.
// 最久的跳过
int skip = other.map.size() - sz; for (int i=0; i<skip; i++) iter.next(); 导入 for (int i=0; i<sz; i++) { Map.Entry<K,V> entry = iter.next(); keys[i]=entry.getKey(); vals[i]=entry.getValue(); } } // autowarm from the oldest to the newest entries so that the ordering will be // correct in the new cache. for (int i=0; i<keys.length; i++) { try {
// 这一步是最终预热的过程 boolean continueRegen = regenerator.regenerateItem(searcher, this, old, keys[i], vals[i]); if (!continueRegen) break; } catch (Throwable e) { SolrException.log(log,"Error during auto-warming of key:" + keys[i], e); } } } warmupTime = System.currentTimeMillis() - warmingStartTime; }
org.apache.solr.search.SolrIndexSearcher.initRegenerators(this); 这行代码决定了solr的每种缓存的加载的具体方式 一共3种 在solrconfig的构造函数里执行
具体的函数:
public static void initRegenerators(SolrConfig solrConfig) { if (solrConfig.fieldValueCacheConfig != null && solrConfig.fieldValueCacheConfig.getRegenerator() == null) { solrConfig.fieldValueCacheConfig.setRegenerator( new CacheRegenerator() { public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache, SolrCache oldCache, Object oldKey, Object oldVal) throws IOException { if (oldVal instanceof UnInvertedField) { UnInvertedField.getUnInvertedField((String)oldKey, newSearcher); } return true; } } ); } if (solrConfig.filterCacheConfig != null && solrConfig.filterCacheConfig.getRegenerator() == null) { solrConfig.filterCacheConfig.setRegenerator( new CacheRegenerator() { public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache, SolrCache oldCache, Object oldKey, Object oldVal) throws IOException { newSearcher.cacheDocSet((Query)oldKey, null, false); return true; } } ); } if (solrConfig.queryResultCacheConfig != null && solrConfig.queryResultCacheConfig.getRegenerator() == null) { final int queryResultWindowSize = solrConfig.queryResultWindowSize; solrConfig.queryResultCacheConfig.setRegenerator( new CacheRegenerator() { public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache, SolrCache oldCache, Object oldKey, Object oldVal) throws IOException { QueryResultKey key = (QueryResultKey)oldKey; int nDocs=1; // request 1 doc and let caching round up to the next window size... // unless the window size is <=1, in which case we will pick // the minimum of the number of documents requested last time and // a reasonable number such as 40. // TODO: make more configurable later... if (queryResultWindowSize<=1) { DocList oldList = (DocList)oldVal; int oldnDocs = oldList.offset() + oldList.size(); // 40 has factors of 2,4,5,10,20 nDocs = Math.min(oldnDocs,40); } int flags=NO_CHECK_QCACHE | key.nc_flags; QueryCommand qc = new QueryCommand(); qc.setQuery(key.query) .setFilterList(key.filters) .setSort(key.sort) .setLen(nDocs) .setSupersetMaxDoc(nDocs) .setFlags(flags); QueryResult qr = new QueryResult(); newSearcher.getDocListC(qr,qc); return true; } } ); } }
先看一下:fieldValueCacheConfig 这个配的是facet分组查询时用的缓存
solrconfig里是默认注释掉的
在SolrConfig类里的代码:
public SolrConfig(SolrResourceLoader loader, String name, InputSource is)
throws ParserConfigurationException, IOException, SAXException 方法里初始化
CacheConfig conf = CacheConfig.getConfig(this, "query/fieldValueCache");
if (conf == null) {
Map<String,String> args = new HashMap<String,String>();
args.put("name","fieldValueCache");
args.put("size","10000");
args.put("initialSize","10");
args.put("showItems","-1");
conf = new CacheConfig(FastLRUCache.class, args, null);
}
看网上的资料说:
FacetComponent 在根据某个field的词时,会用到fieldValueCache,key是facet.field的值,value是UnInvertedField,
UnInvertedField这个类主要负责完成把field域每个词Term,以及词Term在所有文档field域的频率,即出现的次数。保存在一个数组中,创建的UnInvertedField保存在fieldValueCache缓存中,
得到UnInvertedField后,调用UnInvertedField的getCounts方法,跟查询到的document ID 做交集,如果不是查询结果的document ID,,则该Field的词的个数为0,除此之外,还对field出现的词做一个排序,solr的FacetComponet有两种排序选择,分别是count和index,count是按每个词出现的次数,index是按词的字典顺序。如果查询参数不指定facet.sort,solr默认是按count排序。
UnInvertedField的具体以后再说,接着说加载缓存的过程
documentCache和queryResultCache是用的LRUCache
documentCache 是在每次调用
public StoredDocument doc(int i, Set<String> fields) throws IOException 方法时自动追加缓存
if (documentCache != null) {
documentCache.put(i, d);
}
return d;
未完 待续 下一篇主要介绍预热的过程
一种是FastLRUCache
LFUCache
转自:http://www.cnblogs.com/zhang-mohan/archive/2013/01/21/2869619
相关问答
更多-
用java操作solr时候,commit的时候有没有返回值来表示插入成功或者失败[2022-08-28]
1. commit 有返回值的 UpdateResponse updateResponse = solrServer.commit();int status = updateResponse.getStatus()这里的 status 可以拿到操作执行的状态 ,0表示 成功 if (status != 0) { log.error("Some horrible error has occurred, status is:" + status); } 2. try{ UpdateResponse addBea ... -
最近我一直在使用DotNetNuke来开发Web应用程序,并且每次实施缓存解决方案时都会考虑许多事情。 所有用户都需要查看缓存的内容吗? 每一部分内容的变化频率如何? 我可以缓存整个页面吗? 我是否需要手动清除缓存? 我可以为整个站点使用单个缓存机制,还是需要多个解决方案? 如果信息过时,会产生什么影响? I have been working with DotNetNuke most recently for web applications and there are a number of thing ...
-
@ nikano的答案是正确的,如果你想在将URLSession用作Siesta的底层网络库时控制它的缓存行为。 一般来说,Siesta让底层网络做到了。 即使与Siesta一起使用,对URLSession有效的选项URLSession保持不变。 Siesta 本身是一个可观察的内存缓存。 它的核心设计特征之一是,它可以让您对所看到,缓存或新鲜的数据进行细粒度控制 - 这一点至关重要。 你可以使用两者。 如果你想在内存中看到本地缓存的数据,你的“仅限本地”,只需要一个资源: resource.latestD ...
-
除了其他原因,为什么否是一个答案,也是变化的粒度。 Lucene(底层库)以只读形式存储数据。 Solr在其上添加了可更新的文档,但是使它们可见仍然是一个繁重的操作。 Solr的最新版本通过软提交使其变得更容易和更快,但是使可见变化的代价仍然是非常重要的。 因此,它实际上没有针对更新/缓存单个值进行优化。 数据结构针对多文档更新进行了优化,然后通过缓存超过该临时只读状态进行快速搜索。 In additions to other reasons why No would be an answer, is al ...
-
排球缓存更新策略(Volley cache update strategy)[2022-07-04]
有两个主要选项:1。使用纯默认的http缓存(默认的volley实现或者volley使用的任何hhtp堆栈之一)2。使用您自己的自定义缓存,您可以在其中准确定义缓存的方式和内容 我将详细介绍选项1.因为它似乎你使用了这个。 当您缓存响应时,通常不需要外部信息何时更新它们,因为信息包含在返回的缓存标头中。 所以响应(例如一篇文章)可以是:1)缓存有效缓存 - 在这种情况下没有请求进入网络层2)缓存的女巫需要重新验证 - 在这种情况下你可能会收到新版本的没有正文的响应或304响应,这意味着当前缓存有效并且仍然可 ... -
缓存策略(Caching strategy)[2022-02-17]
我假设你在其他地方过滤这个列表......否则这就是一个列表。 在点击数据库之前点击新的,更精简的静态缓存的最简单方法是通过单个方法传递所有请求: public yourClass GetDesiredObject(string lkupValue) { if (yourCachedHashtable.ContainsKey(lkupValue)) { return yourCachedHashtable[lkupValue] } else { //Hit the d ... -
使用Solr缓存自动完成(Cached autocomplete with Solr)[2023-04-28]
我能够确定我的返回函数出了什么问题:我没有在结果中正确循环。 最好的方法是使用map函数迭代它们。 $("#Keyword").autocomplete({ minLength: 3, source: function(request, response) { $query = "http://127.0.0.1:8080/solr/terms/?jsoncallback=?&terms=true&terms.prefix=" + $("#Keyword").val(); ... -
BaseTokenFilterFactory在Solr 4.0中的位置是什么?(Where did BaseTokenFilterFactory go in Solr 4.0?)[2022-12-05]
使用solr 4.0, BaseTokenFilterFactory现在是org.apache.lucene.analysis.util.TokenFilterFactory ,所以你可以检查一下 。 With solr 4.0 the BaseTokenFilterFactory is now org.apache.lucene.analysis.util.TokenFilterFactory, so you can check on this. -
缓存策略,AFNetworking(Cache strategy, AFNetworking)[2022-03-06]
AFNetworking具有图像内存缓存功能。 如果你有100张图片可能适合你,可能不适合你。 您还应该在这里阅读有关NSURLCache的信息 - http://nshipster.com/nsurlcache/ 。 如果你使用NSURLCache,你不必考虑缓存 - 当你开始下载已经缓存的东西时,系统只会给你下载文件。 更新:下载数据的时间到期由服务器设置响应。 但您可以通过NSURLConnectionDelegate方法编辑或忽略它。 例: - (NSCachedURLResponse *)conn ... -
除了新功能之外,Solr 3.6和Solr 4.0之间是否有任何重大差异? 我发现这个问题很奇怪,至少可以说。 错误修复和新功能是发布的全部内容! 您可以在此处查看 Solr版本的完整更新日志。 不要忘记Solr和Lucene是一致发布的,所以你还需要在两个项目中寻找相关的变化。 我可以安全地使用我在Solr 4.0中的现有查询(在Solr 3.6中工作的查询)吗? 查询应该没问题,但索引 - 可能不是。 引用另一篇SO帖子中的 javanna: 索引格式已更改,但Solr将负责升级索引。 一旦用旧索引启动 ...