Solrj和Solr DIH索引效率对比分析

测试软件环境:

    1、16G windows7 x64  32core cpu 。

    2、jdk 1.7  tomcat 6.x  solr 4.8

数据库软件环境:

    1、16G windows7 x64  32core cpu 。

    2、Oracle 11g 

一、Solr默认索引工具DIH。

  使用Solr DIH索引数据,一千九百万数据,耗时45分钟左右,每秒钟6500条/s,合计39w条每分钟。

  相关jvm最大堆内存为4G,solr index config使用默认参数。

  Solr DIH 导入截图:

  

  导入2500w条数据总耗时一个小时左右

  

  索引字段,总共15个左右

  

  (备注:字段越少,字段值越小,索引的速度也越快,因此优化Solr查询和索引效率,schema设计显得尤为重要)

二、Solrj API 索引数据。

  使用Solrj api效率稍差,合计30w每秒,耗时一个多小时。

  Solr Server配置参数同上。在客户端机器上,读取数据库数据,使用Solrj api进行索引。代码如下:

  

  整个过程是读取数据库,将数据转成DTO,然后通过SolrServer.addBeans插入solr server,调用SolrServer.commit进行索引提交(就可以查询结果)。

  从数据库中读取转换过程代码如下:

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private  POI  getPOI(ResultSet rs)  throws  SQLException{
     POI poi =  new  POI();
     
     poi.setId((UUID.randomUUID()).toString());
     poi.setName(rs.getString( "nameforStore" ));
     poi.setAddress(rs.getString( "addressforStore" ));
     
     String lat = rs.getString( "lat" );
     
     if (lat!= null &&!lat.equalsIgnoreCase( "null" )&&lat.length()> 0 ){
         poi.setLat(Double.valueOf(lat));
     }
     
     String lon = rs.getString( "lon" );
     
     //poi.setLon(rs.getDouble("lon"));
     
     if (lon!= null &&!lon.equalsIgnoreCase( "null" )&&lon.length()> 0 ){
         poi.setLon(Double.valueOf(lon));
     }
     
     poi.setNid(rs.getString( "DOCID" ));
     
     String totalCity = rs.getString( "totalcity" );
     if (!StringUtils.isEmpty(totalCity)){ //---------citycode
         String[] cities = totalCity.split( " " );
         List<String> cs =  new  ArrayList<String>();
         for (String c:cities){
             cs.add(c);
         }
         poi.setCities(cs);
     }
     
     String types = rs.getString( "type" );
     if (!StringUtils.isEmpty(types)){ //type-----------------
         String[] typea = types.split( " " );
         List<String> t =  new  ArrayList<String>();
         for (String c:typea){
             t.add(c);
         }
         //poi.setCities(cs);
         poi.setTypes(t);
     }
     
     return  poi;
};

  SolrJ索引过程代码:

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
List<POI> pois =  new  ArrayList<POI>();
 
while (rs.next()){ //遍历JDBC ResultSet
     
     p = getPOI(rs);
     
     //ss.addBean(p);
     pois.add(p);
     if (i>=batchSize){ //定量批量索引逻辑
         long  commitT = System.currentTimeMillis();
         //System.out.println("已耗时:"+(commitT-start)/1000*60+"分钟");
         timer.onTimeUpdate((commitT-start));
         //System.out.println("提交一次");
         ss.addBeans(pois); //发向SolrServer
         ss.commit();
         pois.clear();
         c++;
         i= 0 ;
     } else {
         i++;
     }
     
}
ss.addBeans(pois); //做最后提交
ss.commit();

  分析:

    1、性能差别主要在哪里?

    答:方案一和方案主要差别在于,方案一访问数据之后直接调用Solr内部UpdateHandler,直接将数据放入索引。而方案二,调用SolrJ索引数据,多了一道网络IO。而且,方案二,在solrj索引之前,先将数据转换为DTO,然后Solrj将DTO转换为SolrInputDocument对象,然后SolrInputDocument对象转换成solr rest 接口所需字符串,中间有多处转换,也存在性能损耗(备注:调用Solrj addBeans批量导入索引的方法是提高性能的方式,如果一个一个的提交,性能会更差,http请求更多)。

    2、怎么优化?

    答:问题一的分析,就是问题二的答案。主要那么多数据实体转换那块,主要遵守:1、使用调用接口尽量简单,使用ResultSet直接转换成SolrInputDocument对象,少一些数据转换。2、使用数组等数据结构,替换掉目前的List<Bean>。

    3、使用Solr EmbededSolrServer直接创建索引是否能提高效率?

    答:经过测试EmbededSolrServer 可以提高索引效率,大约是DIH的一倍多。使用方式如下代码所示: 

复制代码
    private SolrServer getSolrServer(){
        // System.setProperty("solr.solr.home", "R:\\solrhome1\\solr\\POI\\"); 
         CoreContainer coreContainer = new CoreContainer("R:\\solrhome1\\solr\\");
         coreContainer.load();//初始化
//         while(!coreContainer.isLoaded("POI")){
//             System.out.println("loading...");
//         }
         System.out.println(coreContainer.getAllCoreNames());
         server = new EmbeddedSolrServer(coreContainer,"POI");
        return server;
        
    }
复制代码

  (备注:EmbededSolrServer保证程序运行在Solr服务器上,是无法通过http方法的,使用场景通常是两个core,一个用此方法,完成以后,swarp一下这个core,让其对外提供检索服务)

    文章转载,请注明出处:http://www.cnblogs.com/likehua/p/4465514.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值