国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

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

2019-11-14 23:59:19
字體:
來源:轉載
供稿:網友
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進行索引。代碼如下:

  

import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.UUID;import org.apache.solr.client.solrj.SolrServer;import org.apache.solr.client.solrj.SolrServerException;import org.apache.solr.client.solrj.impl.HttpSolrServer;import org.sPRingframework.context.applicationContext;import org.springframework.context.support.ClassPathxmlApplicationContext;import org.springframework.util.StringUtils;import com.tianditu.search.v2.POI;public class ImportPOI implements IJobDef{private SolrServer server;private DatasourceConfig jdbcConfig;private SolrConfig solrConfig;private POIImportConfig poiConfig;public DatasourceConfig getJdbcConfig() {return jdbcConfig;}public void setJdbcConfig(DatasourceConfig jdbcConfig) {this.jdbcConfig = jdbcConfig;}public SolrConfig getSolrConfig() {return solrConfig;}public void setSolrConfig(SolrConfig solrConfig) {this.solrConfig = solrConfig;}public POIImportConfig getPoiConfig() {return poiConfig;}public void setPoiConfig(POIImportConfig poiConfig) {this.poiConfig = poiConfig;}/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubApplicationContext context = new ClassPathXmlApplicationContext("app-spring.xml");ImportPOI importTool = (ImportPOI) context.getBean("importPOITool");importTool.submit(new JobDoneCallBack() {public void onCallback(JobStatus status) {// TODO Auto-generated method stubSystem.out.println(status.getStatus());System.out.println(status.getMessage());}},new JobTimer() {public void onTimeUpdate(long timeCost) {// TODO Auto-generated method stubSystem.out.println("solr提交一次,距任務開始已耗時:"+timeCost/(1000*60)+"分鐘");}});}public SolrServer getServer() {return server;}public void setServer(SolrServer server) {this.server = server;}public boolean importPOI(HashMap<String, Object> params){return false;}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)){//---------citycodeString[] 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;};public void submit(JobDoneCallBack callback,JobTimer timer) {if(solrConfig==null){throw new IllegalArgumentException("SolrJ未正確配置.");}if(jdbcConfig == null){throw new IllegalArgumentException("JDBC未正確配置.");}if(poiConfig == null){throw new IllegalArgumentException("POI配置文件未正確配置.");}Connection con = null;Statement pst = null;ResultSet rs = null;SolrServer  ss = null;JobStatus status = new JobStatus();status.setName("ImportPOI");status.setStatus("failure");int i = 0;int c = 0;long start = System.currentTimeMillis();try {Class.forName(jdbcConfig.getDriverClass()).newInstance();con = DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUserName(), jdbcConfig.getPassWord());int batchSize = Integer.valueOf(poiConfig.getImportRecordSize());ss = new HttpSolrServer(solrConfig.getSolrUrl());if(poiConfig.isDeleteOnstartup()){ss.deleteByQuery("*:*");ss.commit();}if(jdbcConfig.getDriverClass().toString().contains("MySQL")){//mysqlpst =  (com.mysql.jdbc.Statement) con.createStatement(ResultSet.FETCH_FORWARD,ResultSet.CONCUR_READ_ONLY);pst.setFetchSize(1);((com.mysql.jdbc.Statement) pst).enableStreamingResults();}else{pst =  con.createStatement();}rs = pst.executeQuery(poiConfig.getImportSQL());POI p = null;List<POI> pois = new ArrayList<POI>();while(rs.next()){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);ss.commit();pois.clear();c++;i=0;}else{i++;}}ss.addBeans(pois);ss.commit();long end = System.currentTimeMillis();status.setStatus("success");status.setMessage("處理成功,總耗時:"+(end-start)/1000*60+"分鐘");status.setTimeCost((end-start)/1000*60);} catch (SQLException e) {// TODO Auto-generated catch block//e.printStackTrace();status.setMessage(e.toString());} catch (ClassNotFoundException e) {// TODO Auto-generated catch block//e.printStackTrace();status.setMessage(e.toString());} catch (InstantiationException e) {// TODO Auto-generated catch block//e.printStackTrace();status.setMessage(e.toString());} catch (IllegalaccessException e) {// TODO Auto-generated catch block//e.printStackTrace();status.setMessage(e.toString());} catch (SolrServerException e) {// TODO Auto-generated catch block//e.printStackTrace();status.setMessage(e.toString());} catch (IOException e) {// TODO Auto-generated catch block//e.printStackTrace();status.setMessage(e.toString());}finally{try {if(rs!=null){rs.close();}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {if(pst!=null)pst.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {if(con!=null)con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(callback!=null){callback.onCallback(status);}}//return false;};}

  整個過程是讀取數據庫,將數據轉成DTO,然后通過SolrServer.addBeans插入solr server,調用SolrServer.commit進行索引提交(就可以查詢結果)。

  從數據庫中讀取轉換過程代碼如下:

  

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)){//---------citycodeString[] 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索引過程代碼:

  

List<POI> pois = new ArrayList<POI>();while(rs.next()){//遍歷JDBC ResultSetp = 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);//發向SolrServerss.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;            }

 ?。▊渥ⅲ篍mbededSolrServer保證程序運行在Solr服務器上,是無法通過http方法的,使用場景通常是兩個core,一個用此方法,完成以后,swarp一下這個core,讓其對外提供檢索服務)

文章轉載,請注明出處:http://m.survivalescaperooms.com/likehua/p/4465514.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 台湾省| 普兰店市| 临夏市| 嵩明县| 贞丰县| 白银市| 西充县| 济阳县| 湘潭县| 蓝山县| 龙口市| 宜春市| 肥西县| 新邵县| 桃园市| 吴川市| 东台市| 当涂县| 隆德县| 宁阳县| 滦平县| 合川市| 阳山县| 青岛市| 察哈| 武宣县| 金山区| 宕昌县| 措勤县| 都江堰市| 故城县| 清徐县| 迁安市| 子洲县| 彩票| 蓝山县| 濮阳县| 南汇区| 尉犁县| 毕节市| 江川县|