solr亿万级索引优化实践-自动生成UUID

solr亿万级索引优化实践(三)

原创 2017年03月14日 17:03:09

本篇文章主要介绍下如何从客户端solrJ以及服务端参数配置的角度来提升索引速度。

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,不需要再客户端额外生成。

原文地址:https://www.cnblogs.com/Lxiaojiang/p/8639204.html

时间: 2024-10-11 21:53:53

solr亿万级索引优化实践-自动生成UUID的相关文章

mybatis新增对象自动生成uuid方案

mybatis新增对象时, 使用拦截器自动生成uuid方案有了它不再去xml中手动添加selectKey了, 生成id方案实现类自行实现, 实现IdGenerator接口便可, 主要代码由公司同事编写, 我进行改造 使用时可以在id字段上添加@Id注解, 也可以在getId方法上添加或者不添加, 但是主键名字必须是id, 类型必须是String @Target({ METHOD, FIELD }) @Retention(RUNTIME) public @interface Id { Class<

excel中 自动生成UUID

转自http://www.tceic.com/g02k4g7ll56527j3240i844769kgk009581hg29i.html 1.Excel 生成 guid,uuid 格式:600d65bc-948a-1260-2217-fd8dfeebb1cd:=CONCATENATE(IF(RANDBETWEEN(1,2)=1,CHAR(RANDBETWEEN(0,9)+48),CHAR( RANDBETWEEN(0,5)+97)),IF(RANDBETWEEN(1,2)=1,CHAR(RAND

oracle 中使用触发器自动生成UUID

create or replace trigger tri_test before insert on test for each row declare begin if :new.uuid is null then :new.uuid:=sys_guid(); end if; end tri_test;

Solr自动生成ID

在Solr中,每一个索引,都要有一个唯一的ID,类似于关系型数据库表中的主键.为了方便创建索引,需要配置自动生成的ID,即UUID. 一.配置schema.xml文件 添加uuid字段类型,修改字段id的类型. <field name="id" type="uuid" indexed="true" stored="true" required="true" multiValued="fals

让Elasticsearch飞起来!——性能优化实践干货

原文:让Elasticsearch飞起来!--性能优化实践干货 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/wojiushiwo987/article/details/85109769 0.题记 Elasticsearch性能优化的最终目的:用户体验爽. 关于爽的定义--著名产品人梁宁曾经说过"人在满足时候的状态叫做愉悦,人不被满足就会难受,就会开始寻求.如果这个人在寻求中,能立刻得到

mysql性能优化-慢查询分析,优化索引最佳实践

数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显,我们究竟应该如何对MySQL数据库进行优化? 下面我就从MySQL对硬件的选择.MySQL的安装.my.cnf的优化.MySQL如何进行架构设计及数据切分,查询与索引优化分析等方面来说明这个问题. (一)服务器物理硬件的优化 在挑选硬件服务器时,我们应该从下面几个方面着重对MySQL服务器的硬件配置进行优化,也就是说将项目中的资金着重投入到如下几处: 1.磁盘寻道能力(磁盘I/O),我们现在用的都是SAS15000转的硬盘,

ECshop网点程序优化-自动生成类目页Keywords、Desciption Meta

ECshop支持针对每个新建的类目自定义Keywords.Description Meta信息,好处就不用说了,帮助SEO或者让浏览者了解这是什么页面,但如果有几百个类目的时候,人工去写这些类目又有点累人(咱不干体力劳动的 活),花了点时间,写了个自动生成Keywords.Description的PHP脚本,支持四级分类,原理是子类目包含爸爸类目.爷爷类目...到顶 级类目名作为关键词,然后一句描述的话,包含这些类目的名称.大家可以根据自己需要简单的修改. 用法,在你的后台类目,默认是Admin

让博客园博客自动生成章节目录索引

一个好的博文除了博文的质量要好以外,好的组织结构也能让读者阅读的更加舒服与方便,我看园子里面有一些园友的博文都是分章节的,并且在博文的前面都带有章节的目录索引,点击索引之后会跳转到相应的章节阅读,并且还可以回到目录顶端,其中 Fish Li 的博文就是这种组织,当然这种结构如果是在写博文的时候人工设置那是非常麻烦的,无疑是增加了写作人的工作量.如果能自动生成章节索引岂不是节省了一大堆工作量.本来想通过FireBug看看Fish Li源码是怎么实现的,但是好像js是加密过的.那我就自己动手了,其实

eclipse优化,日志自动生成

1.每次创建一个类,都要新写    private static Logger log = LoggerFactory.getLogger(SyncNewFileThread.class); 麻烦,于是改了下创建类的模板 来自为知笔记(Wiz)eclipse优化,日志自动生成,布布扣,bubuko.com