solr亿万级索引优化实践-自动生成UUID
solr亿万级索引优化实践(三)
solrJ6.0提供的Java客户端主要有下面几种接口:HttpSolrClient,ConcurrentUpdateSolrClient,CloudSolrClient。下面分别对这三种接口做一个简单的比较。HttpSolrClient在定义的时候需要明确指定一个solr节点路径,他在提交数据的时候也只能提交到这个节点上;ConcurrentUpdateSolrClient接口在同样是指定具体solr节点路径的,但不一样的事,这是个异步提交的模式,即我们在对客户端添加数据的时候,客户端会将文档缓存到内存队列中,让队列中的数据达到一定数量时,客户端会自动一次性向solr服务器发起一个http请求;CloudSolrClient就比较简单了,这个在定义时只需要指定zookeeper地址就好了,因为solr节点注册时,会将节点信息同步到zookeeper中,在提交数据时,CloudSolrClient会和zookeeper进行通信,发现solr云中的索引库,然后利用LBHttpSolrClient来提交数据。通过对比发现,ConcurrentUpdateSolrClient和CloudSolrClient这两个接口比较优秀,后者比较适用于哈希路由的模式,而前者则比较适合指定路由的模式。
CloudSolrClient
public SolrClient CreateCloudSolrClient() {
CloudSolrClient csClient = new CloudSolrClient(zkUrl);
csClient.setZkConnectTimeout(zkConnectTimeOut);
csClient.setZkClientTimeout(zkClientTimeOut);
csClient.setDefaultCollection(collectionName);
csClient.setParallelUpdates(true);
csClient.setRequestWriter(new BinaryRequestWriter());
csClient.connect();
return csClient;
}
ConcurrentUpdateSolrClient
public SolrClient CreateHttpClient() {
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 128);
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 32);
params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, false);
params.set(HttpClientUtil.PROP_ALLOW_COMPRESSION, true);
params.set(HttpClientUtil.PROP_USE_RETRY, true);
HttpClient httpClient = HttpClientUtil.createClient(params);
httpLists.add(httpClient);
ConcurrentUpdateSolrClient client = new ConcurrentUpdateSolrClient(solrUrl + "/" + collectionName, 50, 1);
client.setConnectionTimeout(zkClientTimeOut);
client.setSoTimeout(zkConnectTimeOut);
client.setPollQueueTime(500);
client.setParser(new BinaryResponseParser());
client.setRequestWriter(new BinaryRequestWriter());
return client;
}
上篇文章介绍过,在多线程配合指定路由的模式下,集群的性能能够水平拓展,这个时候再配合ConcurrentUpdateSolrClient客户端,单个节点速度也会有比较大的提升。需要注意的是,有两个参数需要慎重设置,第一个是队列大小,这个指的是队列中最多存储多少个请求之后向服务器进行提交,另一个是线程数,表示内部开几个线程来提交数据。这两个参数需要根据自己应用程序的JVM来设置,如果设置的过大,会导致内存溢出。
由于是异步请求的方式,所以如果在建立索引的过程中出现了异常,异常信息是不会抛给应用程序的,后来通过调试源码发现,solrJ自己在内部处理了这个异常(其实什么都没做,预留了一个空方法),我们可以在选择修改源码来捕捉异常数据,或者将此异常抛出,由应用程序来捕捉异常,持久化异常数据。
在服务器端,我们也可以通过一些优化,来提高建立索引速度。
1
段合并
solr的索引是由段组成,更新索引的时候是写入一个段的信息,几个段共同组成一个索引,在solr优化索引的时候或其他的时候,solr的段是会合并的。所以我们可以对相关参数进行控制,对段的大小以及合并的频率进行调整,来提交系统资源利用效率。
mergeFactor这个参数是合并因子,只当内存中有N个文档时则合并成一个段,当存在N个段文件时则合并成一个新的段文件。
minMergeSize,指定最小的合并段大小,如果段的大小小于这个值,则可以参加合并。
maxMergeSize,当一个段的大小大于这个值的时候就不参与合并了。
maxMergeDocs,当文档数据量大于这个的时候,这个段就不参与合并了。
在实际场景中,应该根据物理机的资源,来配置这些参数,适量加大mergeFactor参数,来降低合并频率,频繁的段合并会消耗大量系统资源。
2 自动生成ID
在Solr中,每一个索引,都要有一个唯一的ID,类似于关系型数据库表中的主键。我们在创建文档的时候,需要自己生成一串UUID来标示文档,但是由于ID比较长,在索引过程中,会占用一些额外的网速和内存等资源,我们可以控制在服务器端让solr自己生成UUID,具体配置步骤如下:
1)修改schema.xml文件,将ID字段修改为UUID类型
<field name="id" type="uuid" indexed="true" stored="true" required="true" multiValued="false" />
<fieldType name="uuid" class="solr.UUIDField" indexed="true" />
2)配置solrconfig.xml文件,添加更新策略配置,生成UUID
<updateRequestProcessorChain name="uuid">
<processor class="solr.UUIDUpdateProcessorFactory">
<str name="fieldName">id</str>
</processor>
<processor class="solr.LogUpdateProcessorFactory" />
<processor class="solr.DistributedUpdateProcessorFactory" />
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
3)配置requestHandler
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">tika-data-config.xml</str>
<str name="update.chain">uuid</str>
</lst>
</requestHandler> <requestHandler name="/update" class="solr.UpdateRequestHandler">
<lst name="defaults">
<str name="update.chain">uuid</str>
</lst>
</requestHandler> <!-- for back compat with clients using /update/json and /update/csv -->
<requestHandler name="/update/json" class="solr.JsonUpdateRequestHandler">
<lst name="defaults">
<str name="stream.contentType">application/json</str>
<str name="update.chain">uuid</str>
</lst>
</requestHandler>
<requestHandler name="/update/csv" class="solr.CSVRequestHandler">
<lst name="defaults">
<str name="stream.contentType">application/csv</str>
<str name="update.chain">uuid</str>
</lst>
</requestHandler> <requestHandler name="/update/extract"
startup="lazy"
class="solr.extraction.ExtractingRequestHandler" >
<lst name="defaults">
<str name="xpath">/xhtml:html/xhtml:body/descendant:node()</str>
<str name="capture">content</str>
<str name="fmap.meta">attr_meta_</str>
<str name="uprefix">attr_</str>
<str name="lowernames">true</str>
<str name="update.chain">uuid</str>
</lst>
</requestHandler>
这样solr即可自动生成UUID,不需要再客户端额外生成。
solr亿万级索引优化实践-自动生成UUID的更多相关文章
- solr亿万级索引优化实践(四)
本篇是这个系类的最后一篇,但优化方案不仅于此,需要后续的研究与学习,本篇主要从schema设计的角度来做一些实践. schema.xml 这个文件的作用是定义索引数据中的域的,包括域名称,域类型,域是 ...
- 利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引)
利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引) ##应用情景 项目中有大量的SQL,尤其是涉及到统计报表时,表关联比较多,当初开发建表时也没搞好索引关联的,上线后 ...
- mybatis新增对象自动生成uuid方案
mybatis新增对象时, 使用拦截器自动生成uuid方案有了它不再去xml中手动添加selectKey了, 生成id方案实现类自行实现, 实现IdGenerator接口便可, 主要代码由公司同事编写 ...
- Explain执行计划与索引优化实践
一.何为explain执行计划? 使用explain关键字可以模拟优化器执行SQL语句,从而知道MySQL是如何使用索引来处理你的SQL查询语句以及连接表,可以分析查询语句或是结构的性能瓶颈,帮助我们 ...
- oracle 中使用触发器自动生成UUID
create or replace trigger tri_test before insert on test for each row declare begin if :new.uuid is ...
- Solr自动生成ID
在Solr中,每一个索引,都要有一个唯一的ID,类似于关系型数据库表中的主键.为了方便创建索引,需要配置自动生成的ID,即UUID. 一.配置schema.xml文件 添加uuid字段类型,修改字段i ...
- Solr4.0 如何配置使用UUID自动生成id值
原文链接http://blog.csdn.net/keepthinking_/article/details/8501058#comments 最近学习了Lucene,随便也学习了Solr,Solr规 ...
- Mysq 索引优化
MYSQL支持的索引类型 BTREE索引 特点: 通过引用以B+权的结构存储数据 能够加快数据的查询速度 更适合进行范围查找 应用: 全值匹配的查询 = 匹配最左前缀的查询 匹配列前缀查询 LIKE ...
- 让Elasticsearch飞起来!——性能优化实践干货
原文:让Elasticsearch飞起来!--性能优化实践干货 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog ...
随机推荐
- 解决LoadRunner超时错误
在录制Web协议脚本回放时超时情况经常出现,产生错误的原因也有很多,解决的方法也不同. 错误现象1:Action.c(16): Error -27728: Step download timeout ...
- PYTHON 爬虫笔记三:Requests库的基本使用
知识点一:Requests的详解及其基本使用方法 什么是requests库 Requests库是用Python编写的,基于urllib,采用Apache2 Licensed开源协议的HTTP库,相比u ...
- codeforces 463A Caisa and Sugar 解题报告
题目链接:http://codeforces.com/problemset/problem/463/A 题目意思:某个人有 s dollar的钱,有 n 种类型的糖果,第 i 种糖果的价值为 xi d ...
- 异步执行js脚本——防止阻塞
JS允许我们修改页面中的所有方面:内容,样式和用户进行交互时的行为. 但是js同样可以阻塞DOM树的形成并且延迟页面的渲染. 让你的js变成异步执行,并且减少不必要的js文件从而提高性能. JavaS ...
- CentOS环境 升级Python2.6.6至2.7.5
1.查看当前Python版本 # python -V Python 2.6.6 # python -V Python 2.6.6 2.下载Python2.7.5源码 # wget http://p ...
- BZOJ_1495_[NOI2006]网络收费_树形DP
BZOJ_1495_[NOI2006]网络收费_树形DP Description 网络已经成为当今世界不可或缺的一部分.每天都有数以亿计的人使用网络进行学习.科研.娱乐等活动.然而, 不可忽视的一点就 ...
- flask logger
Flask uses standard Python logging. All Flask-related messages are logged under the 'flask' logger n ...
- npm安装cnpm淘宝镜像
npm set registry https://registry.npm.taobao.org # 注册模块镜像 npm set disturl https://npm.taobao.org/d ...
- SSAS GUID 添加 行计数,非重复计数 等 遇到的莫名其妙的问题
在基于某个GUID 进行非重复性计数时 需要对GUID 转换类型,如:CAST(ColumnName as varchar(36)) 可参考:http://stackoverflow.com/ques ...
- IsPostBack深入探讨
1IsPostBack介绍 IsPostBack是Page类有一个bool类型的属性,用来判断针对当前Form的请求是第一次还是非第一次请求.当IsPostBack=true时表示非第一次请求,我们称 ...