惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
美团技术团队
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
V
Visual Studio Blog
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
有赞技术团队
有赞技术团队
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
月光博客
月光博客
宝玉的分享
宝玉的分享
小众软件
小众软件
MongoDB | Blog
MongoDB | Blog
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
J
Java Code Geeks
博客园_首页
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
Vercel News
Vercel News
博客园 - 聂微东

博客园 - Phinecos(洞庭散人)

火车票秒杀攻略 go-home源码分析----一款针对12306的火车票订票软件 一个简单的MongoDB操作类 Solr Cache使用介绍及分析 每日学习笔记(26) 每日学习笔记(25) 每日学习笔记(24) 深入剖析SolrCloud(四) 深入剖析SolrCloud(三) 深入剖析SolrCloud(二) 深入剖析SolrCloud(一) 技术宅---我的网上抢火车票攻略(终极秒杀版) 技术宅---我的网上抢火车票攻略 每日学习笔记(23) 一次内存泄露问题的排查 每日学习笔记(22) 每日学习笔记(21) 每日学习笔记(20) 每日学习笔记(19)
一次针对批量查询处理的优化
Phinecos(洞庭散人) · 2011-12-29 · via 博客园 - Phinecos(洞庭散人)

    客户调用批量查询接口对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;
            try {
                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