Solr&Lucene cache简要汇总

简介: 假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。本文汇总Solr Lucene cache相关内容。撇开系统结构、架构这些整体性的分析,纯粹从使用方面做梳理。


撇开具体场景,将cache看做一个工具类,无上下文依赖的cache方法,这时LRUCache FastLRUcache LFUcache就是分析对象了,其中getputremove实现就是差异和性能所在。这一块具有很强的通用性。见分析1
分析1:基本cache

分析SolrLRUCacheFASTLRUCacheLFUCacheremove实现,调研开源cache EhCache

分析2:有上下文cache

分析LuceneBuffer


分析1对应源码参考Solr42的实现。

LRUcacheput 时候对LinkedHashMap做了synchronized处理,get时候也做了同步处理,putget之前都先对统计计数做++

Warm依赖SolrIndexSearcher来注入,也就是每一个IndexSearcher对象关联一个LRUcache

Warm过程是cache对象遍历拷贝过程。Warm项越多,warm时间越长,上一次的SolrIndexSearcher驻留时间越长,相关cache等资源内存逗留时间越长,压力上来后,会new SolrIndexSearcher,然后占用新的内存,恶性循环后,容易出现OOM

另外一种场景,就是查询一次占用时间更长的,也会不停的new SolrIndexSearcher,出现慢了以后恶性循环下的OOMload增加。

 

FastLURCache 支持异步线程cleanup

Only applicable for FastLRUCache. Default is set to false. If set to true, the cleanup will be run in a dedicated separate thread. Consider setting this to true for very large cache sizes, as the cache cleanup (triggered when the cache size reaches the upper water mark) can take some time.

Cache ConcurrentLRUCacheputget没有同步外层,回到

ConcurrentLRUCache, map ConcurrentHashMap,采取重入锁(ReentrantLock)是一种递归无阻塞的同步机制。有存活性判断。

LRUCacheFastLRUCache两种Cache实现是两种很不同的思路。两者的相同点是,都使用了现成的Map来维护数据。不同点是如何来淘汰数据。LRUCache(也就是LinkedHashMap)格外维护了一个结构,在做存取操作时同时更新该结构,优点在于淘汰操作是O(1)的,缺点 是需要对存取操作加互斥锁。FastLRUCache正相反,它没有额外维护新的结构,可以由ConcurrentHashMap支持并发读,但put 作中如果需要淘汰数据,淘汰过程是O(n)的,因为整个过程不加锁,这也只会影响该次put的性能,而FastLRUCache也可选成起独立线程异步执 行来降低影响。而另一个Cache实现Ehcache,它在淘汰数据就是同步的,不过它限定了每次淘汰数据的大小(通常都少于5个),所以同步情况下性能 不会太受影响。

 

LFUCache

SolrCache based on ConcurrentLFUCache implementation

* This implementation does not use a separate cleanup thread. Instead it uses the calling thread

* itself to do the cleanup when the size of the cache exceeds certain limits.

LFU替换实现,通过命中计数,LRU通过访问技术。使用TreeSet保存需要move的元素。第一阶段 遍历map,执行命中数减半,当treeSet元素小于wantoRemove的,add进入treeset,然后遍历tressset执行ConcurrentHashMap remove 操作。在没有达到wantuRemove数目前,Treeset会填满元素,接下来的元素,会与Treeset first元素也就最小的元素做比较,替换大的,小的进入。进入第二阶段之前,treeSet里面就是需要remove的元素了。


image.png

这一部分除了同样的属性:getputremove之外,就是cache这个具体媒介的分配源。也就是从heapoff heaplocale cache unsafe分配)、SSDCache分配来划分(不一定合理,凑合着理解了)。其中放置locale cache的很大一个特点就是GC看不到他,是说只有FGC heap对象回收,此时才会释放堆外内存,正常GC扫描过程不会对堆外内存做标记、碎片处理等工作,堆外内存主动申请、管理可以大大提升内存领用率。另外一个就是 locale cache在大块内存分配、缓存上有优势。面向字节存取,一般对象须有序列化和反序列化。不论那种形式存取本地cache的字节内容,最终都是需要相应一份堆内空间在计算过程中,也就是说本地cache一定是在堆cache之下。如果有序列化的,需要配合堆内cache执行反序列化获取的对象缓存,从而平衡解压与访问性能。参考测试性能
http://mentablog.soliveirajr.com/2012/11/which-one-is-faster-java-heap-or-native-memory/


分析2 源码参考solrlucen42 elasticsearch

image.png


从图中可以看到,cache从业务层逐渐向下,遍布各个需要性能提升的地方。在具体场景下:

warm控制、oom控制、分布式共享、以及具体场景下cache参数设置是业务环境下需要思考的。

对于上面的cache模块:

所有cache参数中配置的sizeitem数量,不是真实内存大小,所有大请求时候极易出现OOM

 

其中queryresultcache是排序后的结果、有状态的,

FilteQueryCacheDocuemntCache无状态,

FilteQueryCache可能存在“滞后”,当新文档到来后,cache没有warm copy 老的,而倒排链已经更新,发生频率低但存在这个风险,新的版本已经做bug修复。filterquery保存的是无排序的命中的doclist,对内存消耗相对较低些。

DocuementCache 保存的是document id 对于的document store field的内容。如果删除了doc,查询的时候会过滤,从而不会访问到。依然存在风险是当document的某些text域很大,可能几个docuement就撑爆了内存。

RangeFieldCache大块分配和主动释放,这一块是针对翻页、大内存申请时候的优化。

FieldValueCache内存消耗最大、命中率最高通常。

最底层bytes OS page FScache等对用户来说要求透明的。其中索引写和merge时候,dataBuffer大小不一样的。默认是1024,而merge时候是4096.

lucene 4*以后,面向bytereffieldvaluecache缓存的是byte 对象,命中率和内存利用率都极大提升。

elasticsearch org.apache.lucene.store.buffer.ByteBufferDirectory中,实现了基于堆外内存初始化索引。

 

DocSetCache

DocSetCacheModule里面初始化SimpleDocSetCache 针对SegmentReader

 

IdCache

IdCacheModule里面初始化SimpleIdCache 针对IndexReader层的缓存


Queryparsercache针对shard搜索时候,同一个结点,此时query解析共享

Indexcache\Filtecache都有相应的场景

--------------------------------------------------------------

至此,基本上认识了cache的具体工具类应该关心的getputremove实现,以及业务场景下,solr lucene elasticsearch中 在cache层做的实现。这些都是值得学习、借鉴的。另外,开源的Ehcache cache 独立设计上,有不少亮点,值得深入学习。这里推荐文档:

 

http://raychase.iteye.com/blog/1545906

目录
相关文章
|
9月前
|
XML 搜索推荐 安全
lucene、solr、es的区别以及应用场景
@[TOC](目录) Lucene、Solr 和 Elasticsearch(ES) 都是基于 Lucene 引擎的搜索引擎,它们之间有相似之处,但也有一些不同之处。 Lucene 是一个低级别的搜索引擎库,它提供了一种用于创建和维护全文索引的 API,以及一些搜索和排序算法。Lucene 主要用于构建自定义搜索引擎,例如在 Java 应用程序中使用。 Solr 是 Lucene 的一个扩展,它提供了一个完整的搜索引擎框架,包括了索引、搜索、排序、过滤等功能。Solr 旨在为大规模数据集提供高性能的全文搜索功能,因此它支持分布式搜索、实时搜索和自定义排序和过滤器等功能。 Elasticsear
133 0
|
存储 自然语言处理 索引
Lucene&&Solr中的域(Filed)总结
Lucene&&Solr中的域(Filed)总结
81 0
Lucene&&Solr中的域(Filed)总结
|
存储 SQL 编解码
Solr-lucene 使用案例大全
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。 本文sole lucene的使用案例汇总。
191 0
|
算法 Java Maven
Lucene&solr 4 实践(4)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。本部分主要分析FST,快乐理解lucene fst包的源码细节和来龙去脉。
119 0
|
自然语言处理 算法 Apache
Lucene&solr 4 实践(5)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。这部分先通透FST的原理和构造方法,方便理解lucene FST、Builder两个核心对象,从而彻底看清基于图的lucene4索引、查询的发展脉络。至于读懂后有神马用,自个琢磨啊! 看懂估计要死伤不少脑细胞哦!
196 0
|
自然语言处理 索引
Lucene&solr 4 实践(3)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。本部分主要是针对FSA FST做前期知识储备和基本概念扫盲。FST是lucene4 solr4 的索引和查询的核心! 下面的内容来自多个出去,出去就不一一列举。
88 0
Lucene&solr 4 实践(3)
|
编解码 缓存 自然语言处理
Lucene&Solr 4 实践(2)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。在第一部分,还不完善基础上,进入第二部分吧。结合源码来认识lucene! 重点是:从需求到方案到实践编码到结果、从原理到实现、从结构到细节、从总体认识到西部深入。
81 0
|
自然语言处理 Java API
Lucene&solr 4 实践(1)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。Solr&Lucene 4.0 好,很好,很强大。对于从lucene2.0 solr0.9 就关注,一直过来的人来讲, 4.X序列除了的架构、风格、API改变了很多很多,更重要的是业务的优化口子更多了,专业知识要求更高。整个架子的容量、包容性、以及适应信息检索的科研,直接上来demo运行easy、深入会很难。需要整理了解的知识点太多了。
78 0
|
自然语言处理 算法 架构师
Lucene&solr 4 实践(8)
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。Lucene 5 有哪些点对大数据倒排索引和检索有优势 1.索引懒加载lazy加载,意味着按时间段或者其他分割的数据可以按需加载 2.FST词典结构以及基于图的索引、查询,使得内存消耗更低 3.异步合并,使得增量索引合并时的“索引整理”开销或者对查询影响更小 4.commitpoint 视图下reader自动更新,使得大规模数据的虚拟分组、全量切换更加方便。
116 0
|
SQL 机器学习/深度学习 自然语言处理
全面解剖 Solr query 到lucene query
假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。围绕从顶之下,从粗到西的关系认识solr 查询流程和实现细节。最低下定位到queryparse的实现。整个过程围绕信息检索这一思路展开,而不是工程实现来看这个问题。目的从整体结构上认识查询这一块的抽象。这样有具体需求的时候,可以知晓参照按个query、从哪个点注入系统中比较省事,而无需侵入solr、lucene底层。
229 0
全面解剖 Solr query 到lucene query