天天看點

一次針對批量查詢處理的優化

  客戶調用批量查詢接口對Solr核進行查詢時覺得查詢響應時間有些慢,接口的内部實作目前是順序執行每個查詢,再把結果彙總起來傳回給調用方。是以,考慮引入線程池對查詢接口的内部實作進行重構優化。

       先聲明一個大小可随之增長的線程池,

private ExecutorService executor = Executors.newCachedThreadPool();//查詢請求處理線程池

     然後是主線程方法的代碼:

     public List<Map<String, String>> queryEntityList(String entityCode, List<Long> idList) throws ServiceException {

複制代碼

        List<Map<String, String>> finalResult = null;

        if (idList == null || idList.size() == 0 || StringUtil.isBlank(entityCode)) {//參數合法性校驗

            return finalResult;

        }

        finalResult = new ArrayList<Map<String, String>>();

        List<Future<Map<String, String>>> futureList = new ArrayList<Future<Map<String, String>>>();

        int threadNum = idList.size();//查詢子線程數目

        for (int i = 0; i < threadNum; i++) {

            Long itemId = idList.get(i);

            Future<Map<String, String>> future = executor.submit(new QueryCallable (entityCode, itemId));

            futureList.add(future);

        for(Future<Map<String, String>> future : futureList) {

            Map<String, String> threadResult = null;

            try {

                threadResult = future.get();

            } catch (Exception e) { 

                threadResult = null;

            }

            if (null != threadResult && threadResult.size() > 0) {//結果集不為空

                finalResult.add(threadResult);

        return finalResult;

    }

    最後是具體負責處理每個查詢請求的Callable

 複制代碼

public class QueryCallable implements Callable<Map<String, String>> {

        private String entityCode = "";

        private Long itemId = 0L;

        public GetEntityListCallable(String entityCode, Long itemId) {

            this. entityCode = entityCode;

            this.itemId = itemId;

        public Map<String, String> call() throws Exception {

            Map<String, String> entityMap = null;

                entityMap = QueryServiceImpl.this.getEntity(entityCode, itemId);//先去hbase查基本資訊

            } catch (Exception e) {

                entityMap = null;

            return entityMap;

        通過線程池的使用,可以減少建立,銷毀程序所帶來的系統開銷,而且線程池中的工作線程可以重複使用,極大地利用現有系統資源,增加了系統吞吐量。

另外,今天也嘗試了另一種合并Solr索引的方法,直接通過底層的Lucene的API進行,而不是送出Http請求,具體方法如下:

java -cp lucene-core-3.4.0.jar:lucene-misc-3.4.0.jar org/apache/lucene/misc/IndexMergeTool ./newindex ./app1/solr/data/index ./app2/solr/data/index 

本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2011/12/29/2306775.html,如需轉載請自行聯系原作者