原文:
SolrPerformanceFactors
Solr本身的性能不错,但是在使用过程中,还是会遇到一些使用错误,或是没考虑到的地方;在出现瓶颈时,可以首先考虑哪些点呢?下面就来看一下Solr官方的总结,个人觉得总结的很好。SOLR+LUCENE的官网还是挺给力的
对Schema设计的考虑
索引域的数量增长会很大程度的影响以下的内容:
引用
索引期间的内存使用
段的合并时间
优化(optimization)时间
如果设置omitNorms="true" ,则可以减小对这些影响
批注:如果设置Norms,则会影响评分的标准,但会大大的增大索引文件的大小,如果对该字段没有需求,建议关掉
存储域
通过查询结果获取存储域的值是一个相当大的开销。如果文档的数据特别大,或者一些数据存储到了分布式的磁盘中(需要更多的IO来查询域)时,那么花费将会很大。这在存储大数据时很容易被考虑到,尤其是整个文档内容的存储。
考虑将大数据的存储放到solr之外。如果非要这么做,那么可以考虑使用压缩域,这将会用CPU的开销来换取IO的开销。
如果你并不需要使用所有的存储域,允许延迟加载(enableLazyFieldLoading)将会是很好的方式,由于是对那些压缩的字段。
批注:延迟加载在查询期间很有用,尤其是需要对某些字段作额外的处理时,它既能减少内存使用,又加速了程序的处理。另外,尽量减小索引的大小绝对不是坏事。
SOLR配置考虑
mergeFactor
mergeFactor大致决定了段的数量。mergeFactor的值告诉lucene有多少个段需要进行合并。它可以被认为是一个基本的数量系统。
举个例子,如果你设置mergeFactor为10,每1000个文档时会创建一个新的段到硬盘中。当第10个段被添加时,所有的10个段将被合并为1个段 (包含10000个文档);当这样的10个文档被创建时,它们又会被合并为个包含100,000个文档的段,依次类推(当然也有上限)。这样,在任何时候,都不会有多余9个的段(相同索引大小情况下)存在。
该值在solrconfig.xml中的mainIndex设置(它会忽略indexDefaults)。
批注:关于合并的策略,请看我之前的博客:lucene内部的合并策略
mergeFactor Tradeoffs
高值的merge factor(比如25):
引用
Pro:一般会加快索引的速度
Con:低合并延迟,在查询时需要搜索更多的文件,所以会使查询变慢
低值的merge factor(比如2):
引用
Pro:更少的索引文件,加快查询的速度
Con:更多的文件合并,将使索引变慢
批注:一般来说不需要这么极端,设10即可。保证读速度的同时,也保证合并的速度。
HashDocSet最大值的考虑
SOLR1.4之后不支持了,不再描述。
cache中autoWarm数量的考虑
当一个新的searcher被打开时,它的cache可以从旧的searcher中重新加载或者自动预热(autowarmd)缓存的对象。autowarmCount是将被拷贝到新searcher中的对象的数量,你需要根据autowarm的时间来设置autowarmCount。如何使用autowarmCount,需要你根据时间和数量来设定。
批注:autoWarm即新的searcher会有多少数据被缓存,如果没有缓存,一些热点数据无疑会变得很慢。所以,合理的这是这个值,能大大加快查询的效率。
缓存命中率
在Solr的admin中监控缓存的统计。增加缓存的大小通常是提高性能的最好方法,尤其是你对一个指定的缓存类型作逐出操作时。请关注filterCache,它也被用来作solr的facetting。
批注:一个典型的场景是范围查询,类似fl=price:[100 TO 200]这样的情况,将数据该范围存储起来时,对其他的一些查询都可以复用这个缓存的数据,很高效。
对排序的域作明确的预热
如果你的工作大多基于排序的方式,那么你最好在“newSearcher”和“firstSearcher”时间监听器中添加明确的预热查询规则,这样FiledCache可以在用户的查询被执行前就将数据加载。
优化的考虑
你可能想在任何时候都可以优化你的索引。比如你创建索引后,就没有修改过它。
如果你的索引收到了一串需要更新的流,那么请考虑以下的因素:
引用
1. 如果过多的段被添加到索引中,那么查询的性能将会下降;lucene的段自动合并能将段的数量控制在一定范围
2. auto-warming的时间也会延长,它通常依赖于所做的查询
3. 优化后的第一次分布耗时比之后的分布耗时要长。具体请看
Collection Distribution
4. 在优化期间索引的问题大小会加倍,优化后会回到原始大小或更小
5. 如果可以,请确保没有并发的commit请求,否则会有很大的性能损失
在优化时所有的索引会放到唯一的段中;优化索引会避免“文件打开数过多”的问题。
这里有一篇关于该问题的文章:
ONJava Article
更新和提交的频率
如果slaves收到的数据过频,那么性能必然受损。为了避免这个问题,你必须了解slaver的更新机制,这样你才能更好的调整相关的参数(commit的数量/频率、snappullers、autowarming/autocount)以使新数据的写入不会那么频繁。
引用
1. 集合的快照会在客户端运行commit时建立,或者在optimization时;这依赖于在master上的postCommit或postOptimize的钩子方法
2. slaver上的Snappuller会运行corn去检查master上是否有新的快照,如果它找到新的版本,就会把它拿过来并install这些新的数据。
3. 当一个新的searcher被打开时,autowarming会先于Solr的查询请求之前完成。有了预热的缓存,查询的延迟将会小很多。
这里有三个相关的参数:
引用
快照的数量/频率:这取决于客户端的索引。因此,集合的版本号依赖于客户端的活跃度
snappluller:基于cron,他可以精确到秒级别。它们运行时,会获取最近它们没有的集合
缓存预热:在solrconfig.xml中配置
查询响应的压缩
在Solr返回xml应答给客户端之前对其进行压缩有时是值得做的。如果应答结果非常大,或者网络IO有限制,或者没有千兆网卡,请考虑使用压缩机制。
压缩会增加CPU的使用,并且Solr本身也是CPU密集型的应用,所以压缩会降低查询的性能。压缩会使文件减小到1/6的大小,使网络包减小到1/3的大小;相对的,查询的性能会降低15%左右。
请查看你的应用服务器的相关文档(tomcat、resion、jetty...)来获取关于压缩的信息。
索引的性能
一般情况下,一次更新多个文档比一个一个更新要快。
对于这种块级的更新方式,考虑使用
StreamingUpdateSolrServer.java,它提供多线程多连接的方式来更新流数据。
批注:StreamingUpdateSolrServer类相对CommonsHttpSolrServer要快很多,主要在于它将原本单个的文档写入变为了批量写入,加上多线程多连接的方式,性能上快了超多。我们的测试数据表明,至少要快4-6倍以上。
内存使用的考虑
OutOfMemoryErrors
如果你的solr实例没有足够的内存,那么JVM有时会抛出OutOfMemoryErrors。这并不会对数据有影响,并且solr也会试图优美的恢复它。任何 添加/删除/提交 的命令在异常抛出时都可能不成功;其他不利的影响也可能会产生。对应用而言,如果SimpleFSLock 的锁机制在使用的话,OutOfMemoryError 会导致solr丢失这个锁。如果这发生了,更新索引的结果将会是这样的异常:
SEVERE: Exception during commit/optimize:java.io.IOException: Lock obtain timed out: SimpleFSLock@/tmp/lucene-5d12dd782520964674beb001c4877b36-write.lock
如果你想在OOM时看堆的情况,请设置"-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/the/dump"
JVM内存的分配
针对这个错误的最简单方法,在JVM并没有完全使用你的物理内存时,考虑加大JVM的内存容量:
java -Xms512M -Xmx1024M -jar start.jar
影响内存使用的因素
你可能想去减小solr的内存使用。
一个方式就是减小文档的大小。
当运行add命令时,标准的xml更新请求会有两个限制:
引用
1. 所有的文档必须同时放入到内存中。通常,它的取值为sum(域的实际长度,maxFieldLength)。所以,调整maxFieldLength的大小可能会有帮助
2. 每个<field>...</field>标签都必须放入到内存中,而不管maxFieldLength
注意一些不同的add请求会在不同的线程中并发运行。越多的线程,就会导致越多的内存使用。
我的一些其他使用经验:
1.schema中的类型定义很重要,它直接影响了索引的性能
2.尽量少用filter,虽然它很好用,但是其hashSet的数量如果过多,很容易oom
3. cache的类,都用FastLRUCache吧,LRUCache还有锁,太慢了
4. 通过docId取doc的过程看似平常,但是量大了就是一个灾难,在这点需要根据实际场景考虑
5. 能用缓存的用缓存,不能用缓存的,尝试使用MMapDirectoryFactory,最好是SSD硬盘
6.其他,待想到了再补充
分享到:
相关推荐
该资源为本人亲自整理的报告,多线程代码未给出,不是太难我相信你能搞定。
solr安装和使用
Solr(Cloudera)使用手册
solr在做检索的时候时常需要得知他的性能参数,此处使用8G内存,双核处理器测试的结果
lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用lucene,solr的使用
solr的安装使用步骤
solr中文解析器以及使用文档,配合blog使用
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包...
centos7 环境 安装docker 并在docker 中部署solr 并使用
solr的使用
solr
solr 安装教程
6 solr性能调优 55 6.1 Schema Design Considerations 55 6.1.1 indexed fields 55 6.1.2 stored fields 55 6.2 Configuration Considerations 55 6.2.1 mergeFactor 55 6.2.2 mergeFactor Tradeoffs 56 6.3 Cache ...
solr
ES和solr都是基于Lucence的搜索框架,文档比较2中方案适合的不同场景和优劣
用于solr6.5的IK分词包,内含使用说明及配置文件
solr定时索引使用到的定时调度器jar包, 可使用于solr7.x版本
Solr基础使用
Solr 3.*pdf使用手册,欢迎下载
solr使用和原理 简单明了的介绍了solr的使用和原理,及其部署方式,适合初学者第一次部署