作者:战斗民族就是干 

  转载请注明地址:http://www.cnblogs.com/prayers/p/8982141.html

  本篇文章我们来了解一下solr的性能方面的调优,分为Schema优化、索引更新与提交调优、索引合并性能调优、Solr缓存、Solr查询性能优化

Schema优化

  1、index=true比index=false在索引时占用更多的内存、索引合并和优化时间更长,索引体积也响应变的更大,如果你不需要针对该域进行检索,可以设置为index=false

  2、如果不关心Term在文档中出现的次数对最终文档的影响可以设置omitNorms=true,即取消标准化因此对score的影响。它能减少磁盘空间的占用并加快索引速度

    3、如果你不需要对该域进行高亮,你还可以设置omitPositions=true进一步减小索引体积

  4、如果只需要利用倒排索引结构根据指定的Term找到对应的document,不需要计算Term在Document中的出现频率来考虑每个索引文档的权重,那么还可以设置omitTermFreqAndPositions=true即忽略TF计算以及Term在TermVector中的位置信息,这样能够进一步减小索引体积

  5、对于stored属性而言,在响应结果集中通过FL参数返回stored=true的域的执行开销很大,因为域值需要存储到硬盘写IO,查询时提取域值需要磁盘读IO,如果不需要存储可以设置stored=false,进一步优化索引的体积

  6、如果你想要存储的域值长度并不大, 但是为了能够缓解提取存储域带来的磁盘IO,此时可以设置compressed=true即启用域值数据压缩。开启compressed会降低磁盘IO但会增大CUP开销

  7、如果并不是一直都需要使用存储域,你可以设置域延迟加载,尤其是当你开启了域值数据压缩。设置延迟加载开启延迟加载之后,要返回的字段会被SetNonLazyFieldSelector立即加载,其他的域为延迟加载。启用域延迟加载,需要在solrconfig.xml中进行如下配置  

<enableLazyFieldLoading>false</enableLazyFieldLoading>

  8、如果你的域值很大,可以使用ExternalFileField域(外部文件),他不支持solr查询,只能用于显示和function计算,还可以将域值储存在外部系统,比如redis等,当需要域值的时候根据solr的UniqueKey去缓存中提取

  9、对于Java里的日期时间类型的数据,建议你使用Solr里的date域类型,如果你需要进行日期时间范围区间查询,那么建议使用Solr里的date域类型,而不是使用string域类型

  10、可以对facet域、排序域设置为docValue=true,它将会生成一个额外的正排表,会提升分面和排序的效率

  

索引更新与提交调优

  1、不建议使用显示硬提交,建议在solrConfig里面配置自动软/硬提交方式

   2、客户端在提交索引文档的时,建议使用批量软提交的方式添加索引文档

   3、单机模式下,在提交索引的时候建议使用ConcurrentUpdateSolrClient类,对于solrCloud模式下建议使用CloudSolrClient类来更新或提交索引

   4、默认情况下,solr会将document的每个域域值进行索引,当在对一些大文档进行索引的时候,因为创建索引过程中solr需要将document缓存在内存中,如果域的域值很大,内存占用就很大,可能触发更频繁的GC,GC可能会导致暂停索引创建过程,对一些大文本域使用的域类型配置LimitTokenCountFilterFactory来限制实际索引的文本长度,从而减少索引过程中内存占用

   5、在创建索引的时候,需要对文本进行分词处理时,建议配置停止词来剔除掉无用的噪音词,从而减少索引体积,同时还可以避免噪音词印象最终的检索结果

   6、禁用CompoundFile(复合)文件:开始复合文件虽然可以减少段文件个数,但是它会使得你的索引创建时间增加7%~33%,具体配置如下  

<useCompoundFile>false</useCompoundFile>
<mergePolicy class=”org.apache.lucene.index.TieredMergePolicy”>
<float name=”noCFSRatio”>0.0</float>
</mergePolicy>

   7、如果索引速度经过一系列优化还是比较慢,建议可以使用MapReduce框架,利用多台机器的资源并行创建solr索引,从而加快索引速度

索引合并性能调优  

   1、降低索引合并频率:索引合并之后能加快Solr查询性能,但是索引合并是一个执行开销很大的操作,因此你需要在保证查询性能的前提下,尽量的降低索引合井的频率

  2、加大ramBufferSizeMB和maxBufferedDocs参数值,并且尽量降低显式提交的频率:索引提交除了用户显式的执行commit操作之外,ramBufferSizeMB或者maxBufferedDocs参数达到限定的阔值之后也会自动触发索引提交。 因此,为了降低索引合并的频率, 应该加大ramBufferSizeMB和maxBufferedDocs参数值,并且尽量降低显式提交的频率,比如采用批量commit,或者直接在solrconfig刀nl 中配置自动提交并控制自动提交的频率,避免显式提交

  3、增大mergeFactor参数值:加大mergeFactor参数值确实可以加快索引创建速度,降低索引合并频率但是同时它也会降低你的Solr查询响应速度

Solr缓存

  Solr中缓存都是由SolrIndexSearcher实例来管理的,一个SolrIndexSearcher实例对应一套缓存体系,如果你新建立一个SolrIndexSearcher实例,那么之前的SolrIndexSearcher全部会失效,当你数据量很大的时候,增量很频繁的时候对缓存的依赖很大,这个之后你需要在新建SolrIndexSearcher进行缓存预加载,术语叫预热

  solr默认的4中缓存类型

  1、filterCache

    用于缓存Filter Query从硬盘提取出来的Document的无序ID ,下次执行相同的FieldQuery就直接会命中缓存。Solr会默认为每一个FilterQuery提供FilterCache.

  应用场景:

  1)  缓存所有FilterQuery返回的结果集,solr会将主Q查询的结果集和Filter缓存的无序Document ID set集合取交集

  2)  当facet.method=enum时候会命中Filter缓存

  3)  如果solrconfig.xml中配置了<useFilterForSortedQuery/>true</useFilterForSortedQuery>,那么对于Solr排序操作也会使用Filter缓存。

  4)  Filter缓存通常还会用于其他Solr查询,比如facet.query、 group.query

  不适用场景

  价格区间、时间区间查询:全品类价格区间太多,时间精确到秒。如果对每一个价格区间的FilterQuery都启用FilterCache需要大量的内存支撑,另外由于区间太复杂,缓存命中率也会大大下降,所以这个时候我们可以类似这样的FilterQuery禁用Filter缓存

  2、documentCache

  DocumentCache(即文档缓存):用于储存已经从磁盘上提取出来的Lucence中的document对象。Document缓存保存的最大项数:应该大于返回结果集中可能的最大值*查询的最大并发量。 这样做的目的是因为为了确保solr不在从磁盘上提取索引文档,但是随着doc数目越来也多,documentCache占用的内存就会越来越大

  当你开启了document缓存并且开启了延迟加载,那么indexReader所提取的对象仅仅包含fl参数指定的Field,其他的Field会被延迟加载,这么做可以减少document缓存对内存的占用,当延迟加载的域,被后续请求到,那么indexReader会临时从硬盘加载该域

  还需要注意的是document缓存并不能进行缓存预热,也就意味这次当打开了一个SolrIndexSearcher的时候,缓存并不会提前进行加载,因为document缓存使用的是lucence内部的document ID,当索引数据变化了之后,该ID也会发生变化

  3、queryResultCache

  QueryResult缓存(查询结果集缓存):用于缓存查询的TOP N结果集的有序的Document ID,按照排序域进行排序。查询结果集缓存的内存占用明显要比Filter小,因为只有q,fq,sort参数同时一致的查询才会命中缓存

  4、fieldValueCache

  fieldValueCache(即域值缓存):与lucence中的fieldCache相似,但是不同的是FieldValueCache支持每个document对应多个值(多值域的多个值域,或者单值域因分词产生多个Term)。此缓存多用于facet查询,缓存的key为域的名称,value为docid到多个值的映射的数据结构。如果solrconfig.xml中没有定义<fieldValueCache>,那么Solr会自动为你生成一个size=10, max Size= 10 000,无autowarm的<fieldValueCache>

  

  HTTP缓存:除了可以在后台服务层启用Solr缓存之外,你还可以在前端HTTP协议层启用HTTP缓存,对于没有更新的资源,可以直接从HTTP缓存中直接返回,避免了同样的查询请求频繁请求服务器,这能在一定程度上减轻Solr Server的负载压力。如果想要开启HTTP缓存,配置如下:  

<httpCaching never304=”false”>
<cacheControl>max-age=30, public</cacheControl>
</httpCaching>

或者

<httpCaching lastModifiedFrom=”openTime” etagSeed=”Solr”>
<cacheControl>max-age=30, public</cacheControl>
</httpCaching>

  never304参数设置为false 即表示开启Solr中的HTTP缓存,默认never304=true即禁用HTTP缓存。 Solr中的HTTP缓存只支持GET和HEAD请求,不支持POST请求。 SolrHTTP缓存兼容HTTPI.O和HTTPl.l协议头信息。

  你还可以在solrconfig.xml 配置firstSearcher和newSearcher事件监昕器来自动触发缓存自动预热。

  newSearcher用于当一个新的IndexSearcher实例被创建时,除了从旧IndexSearcher实例自动预热一部分缓存之外,还可以显式的指定一个查询来对缓存进行预热。 当某个查询耗时很长时,你可以提前通过newSearcher监昕器进行预热,这样后续你再执行该慢查询时会直接命中缓存。

  firstSearcher表示当一个新的IndexSearcher实例正在被初始化并且当前没有旧的Index Searcher实例用于新的IndexSearcher实例进行缓存自动预热,此时你需要显式的指定一个查询来自动预热缓存。 这个firstSearcher主要用于配置Solr刚启动时执行什么查询并放入缓存。 因为Solr刚启动时,缓存肯定是空的,为了保证刚启动的一段时间内的查询性能高效,因此你需要配置firstSearcher来提取预热。

  当使用que可Result缓存时,你还可以额外添加<queryResultWindowSize>配置来对其进行优化。 当一个查询被执行,返回的DocumentID会被收集,比如查询匹配的documentID是[10, 19)之间,如果queryWindowSize= 50,那么DocumentID [0, 50] 会被收集并缓存,在此范围内的Document将会命中缓存

Solr查询性能优化

  1、如果你的查询需要在三个域上进行查询,此时可以用copyField将三个域合并成为一个域,在合并之后的域上进行查询。因为在单个域上进行查询比在N个域上进行查询效率要高。但是使用copyField之后,你无法为每个单独的域进行加权

  2、应该优先让那些能够过滤掉大部分索引文档的FilterQuery先执行

  3、在对数字域进行范围查询的时候,可以调整precisionStep来对rangeQuery进行优化。precisionStep默认值是4,这个值越大,分解出来的索引前缀索引就越多,数字范围查询越快,但是会增大索引体积

  查询方面的优化点还有很多,需要针对不同的场景不同的去分析使用。大部分是在学习solr的过程中自己就可以体会到的,所以在这里不在赘述了

  

  

solr研磨之性能调优的更多相关文章

  1. MySQL性能优化总结___本文乃《MySQL性能调优与架构设计》读书笔记!

    一.MySQL的主要适用场景 1.Web网站系统 2.日志记录系统 3.数据仓库系统 4.嵌入式系统 二.MySQL架构图: 三.MySQL存储引擎概述 1)MyISAM存储引擎 MyISAM存储引擎 ...

  2. web前端性能调优

    最近2个月一直在做手机端和电视端开发,开发的过程遇到过各种坑.弄到快元旦了,终于把上线了.2个月干下来满满的的辛苦,没有那么忙了自己准备把前端的性能调优总结以下,以方便以后自己再次使用到的时候得于得心 ...

  3. [网站性能2]Asp.net平台下网站性能调优的实战方案

    文章来源:http://www.cnblogs.com/dingjie08/archive/2009/11/10/1599929.html 前言    最近帮朋友运营的平台进行了性能调优,效果还不错, ...

  4. Asp.net平台下网站性能调优的实战方案(转)

    转载地址:http://www.cnblogs.com/chenkai/archive/2009/11/07/1597795.html 前言 最近帮朋友运营的平台进行了性能调优,效果还不错,所以写出来 ...

  5. 第0/24周 SQL Server 性能调优培训引言

    大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...

  6. sqlserver性能调优第一步

    相信不少的朋友,无论是做开发.架构的,还是DBA等,都经常听说“调优”这个词.说起“调优”,可能会让很多技术人员心头激情澎湃,也可能会让很多人感觉苦恼,不知道如何入手.当然,也有很多人对此不屑一顾,因 ...

  7. JavaScript:内存泄露、性能调优

    1.在进行JS内存泄露检查之前,先要了解JS的内存管理: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Manageme ...

  8. hadoop 性能调优与运维

    hadoop 性能调优与运维 . 硬件选择 . 操作系统调优与jvm调优 . hadoop运维 硬件选择 1) hadoop运行环境 2)  原则一: 主节点可靠性要好于从节点 原则二:多路多核,高频 ...

  9. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解

    摘要: JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望 ...

随机推荐

  1. Android项目开发填坑记-9patchPng报错

    如果阅读体验不佳,请使用–> Github版 背景 之前写了一篇文章Android必知必会–NinePatch图片制作详细介绍了Android 9Patch图片的制作和一些Demo展示,这次说明 ...

  2. Error处理:Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack tra

    [2014-04-20 20:59:23 - MyDetectActivity] Dx  trouble writing output: already prepared [2014-04-20 20 ...

  3. SSH深度历险(三) EJB Session Bean有状态和无状态的区别与联系

    刚开始对两种sessionbean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后,会发现,事实 ...

  4. MySQL聚簇索引的使用介绍

    MySQL聚簇索引保证关键字的值相近的元组存储的物理位置也相同(所以字符串类型不宜建立聚簇索引,特别是随机字符串,会使得系统进行大量的移动操作),且一个表只能有一个聚簇索引.因为由存储引擎实现索引,所 ...

  5. Cocos2D iOS之旅:如何写一个敲地鼠游戏(四):创建TexturePacker自动脚本

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  6. 部署Openfire3.9.3源码部署

    1,下载Openfire3.9.3源码代码:http://www.igniterealtime.org/downloads/index.jsp 2,具体的配置请参考http://blog.csdn.n ...

  7. PA 项目任务创建资源

    -- 创建资源 DECLARE p_project_id NUMBER := 155233; p_task_id NUMBER := 244639; p_resource_list_member_id ...

  8. Linux进程-进程的创建

    今天学习了Linux的进程创建的基本原理,是基于0.11版本核心的.下面对其作一下简单的总结. 一.Linux进程在内存中的相关资源   很容易理解,Linux进程的创建过程就是内存中进程相关资源产生 ...

  9. Touch Handling in Cocos2D 3.x(六)

    使英雄变成可触碰的对象 这是另一个非常有用的特性.很多用户需要捡起已经存在的英雄然后满屏幕移动它们.让我们按以下步骤实现该功能: 如果用户触摸屏幕空白位置,一个新的英雄将被创建 如果用户触摸一个已经存 ...

  10. Swift基础之PickerView(时间)选择器

    代码讲解:(后面有额外代码讲解) 首页设计UIPickerView的样式设计: leftArray = ["花朵","颜色","形状"]; ...