Solr索引的建立和优化

目前我知道Solr建索引有2种方法,这里介绍一下:

 第一种就是我们常用的SolrServer.add(Collection<SolrInputDocument>),下面介绍一个各种SolrServer.

* HttpSolrServer,这个是我们最常用的就不说了

* ConcurrentUpdateSolrServer, 这个是创建和更新时使用,查询时不要用。保存了一个HttpSolrServer,用多线程技术并发向服务端提交索引数据,提高建索引的速度。

* LBHttpSolrServer, 这个保存了多个HttpSolrServer,进行负载均衡,提交查询时会判断哪个Server的压力最小,向那个Server提交请求。和上面相反,查询时使用,创建和更新索引时不建议使用。

* CloudSolrServer, 这个保存了一个LBHttpSolrServer,查询时和LBHttpSolrServer类似,但创建和更新索引时,在客户端会根据索引信息提交到对应的服务端。而HttpSolrServer是在服务端判断索引需要提交到哪个对应服务端,然后进行转发

* EmbeddedSolrServer,这个本地Server,单机使用,索引是保存在本地

  这种建索引的方法,除EmbeddedSolrServer外,客户端除了发送数据外,服务端做了剩余的全部工作,想要提高建索引速度,就2个方案,1客户端用多线程提交索引,提高数据发送速度,但这个还取决于服务端接收数据的速度,服务端在高负荷的时候,速度就不会再提高了。2增加服务端节点数,这个就不说了,主要看硬件资源

    另一种并不常见,我看了solr-map-reduce部分的代码才发现的。把建索引的过程分为了2步,

* 第一步利用EmbeddedSolrServer先在本地创建索引文件,这样客户端就分担了大部分的服务端的工作,

* 第二步利用合并索引的功能把本地索引文件提交到服务端,这里有个关键问题,就是合并索引时不再是http方式,而是磁盘目录的方式,所以本地索引文件位置必须对服务端是可见,所以要把本地索引文件共享出来,可以用NFS的方式,另一种方法就是用hdfssolr源码里是用的hdfs

  这种建索引的方法,好处是客户端分担了不少服务端的压力,而不像前一种,除了发送数据外,其他时间都闲置了。我们可以用多线程技术,对数据分片,让客户端一边建索引,服务端同时合并已经建好的本地索引,性能大幅度的提升了。

    下面贴2段关键代码,从solr源码里考出来的。

创建EmbeddedSolrServer

public EmbeddedSolrServer createEmbeddedSolrServer(Path solrHomeDir, FileSystem fs, Path outputShardDir)
          throws IOException {

        if (solrHomeDir == null) {
          throw new IOException("Unable to find solr home setting");
        }
        System.out.println("Creating embedded Solr server with solrHomeDir: " + solrHomeDir + ", fs: " + fs + ", outputShardDir: " + outputShardDir);

        Path solrDataDir = new Path(outputShardDir, "data");
        String dataDirStr = solrDataDir.toUri().toString();

        SolrResourceLoader loader = new SolrResourceLoader(solrHomeDir.toString(), null, null);

        System.out.println(String
            .format(
                "Constructed instance information solr.home %s (%s), instance dir %s, conf dir %s, writing index to solr.data.dir %s, with permdir %s",
                solrHomeDir, solrHomeDir.toUri(), loader.getInstanceDir(),
                loader.getConfigDir(), dataDirStr, outputShardDir));

        // TODO: This is fragile and should be well documented
        System.setProperty("solr.directoryFactory", HdfsDirectoryFactory.class.getName()); 
        System.setProperty("solr.lock.type", "hdfs"); 
        System.setProperty("solr.hdfs.nrtcachingdirectory", "false");
        System.setProperty("solr.hdfs.blockcache.enabled", "false");
        System.setProperty("solr.autoCommit.maxTime", "600000");
        System.setProperty("solr.autoSoftCommit.maxTime", "-1");
        
        CoreContainer container = new CoreContainer(loader);
        container.load();
        
        Properties props = new Properties();
        props.setProperty(CoreDescriptor.CORE_DATADIR, dataDirStr);
        
        CoreDescriptor descr = new CoreDescriptor(container, "core1", solrHomeDir.toString(), props);
        
        SolrCore core = container.create(descr);
        
        if (!(core.getDirectoryFactory() instanceof HdfsDirectoryFactory)) {
          throw new UnsupportedOperationException(
              "Invalid configuration. Currently, the only DirectoryFactory supported is "
                  + HdfsDirectoryFactory.class.getSimpleName());
        }

        EmbeddedSolrServer solr = new EmbeddedSolrServer(container, "core1");
        return solr;
      }

 合并索引

    public Request call() {
        Request req = new Request();
        LOG.info("Live merge " + dir.getPath() + " into " + mergeUrl);
        final HttpSolrServer server = new HttpSolrServer(mergeUrl);
        try {
            CoreAdminRequest.MergeIndexes mergeRequest = new CoreAdminRequest.MergeIndexes();
            mergeRequest.setCoreName(name);
            mergeRequest.setIndexDirs(Arrays.asList(dir.getPath().toString() + "/data/index"));
            try {
                mergeRequest.process(server);
                req.success = true;
            } catch (SolrServerException e) {
                req.e = e;
                return req;
            } catch (IOException e) {
                req.e = e;
                return req;
            }
        } finally {
            server.shutdown();
        }
        return req;
    }

 

posted on 2016-08-24 12:28 攻城狮+程序猿 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/herohawk/p/5802439.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值