es多线程调用,线程阻塞超时RuntimeException

      最近做多职位简历召回时,使用多线程进行es数据召回,发现每次es召回的时间大概在1000ms,甚至导致RuntimeException。linux机器cpu核数等于8

 一、分析原因

 1、单线程进行es数据召回,耗时30ms左右,猜猜是由于多线程导致的

 2、切回线程池多线程执行es数据召回,每条数据耗时1000ms左右,此时线程池配置如下:       

private static ExecutorService THREAD_POOL = new ThreadPoolExecutor(40,40, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),    		
			new ThreadFactoryBuilder().setNameFormat("es-recall-%d").build());

 3、减少核心线程数,执行es数据召回,每条数据执行耗时在100ms左右,确定是由于多线程请求,导致es召回耗时变大,甚至超时,此时线程池配置如下:   

private static ExecutorService THREAD_POOL = new ThreadPoolExecutor(10,	10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),    		
			new ThreadFactoryBuilder().setNameFormat("resume-nsupin-recall-%d").build());

   查阅官方文档,确认是由于多线程引起es查询线程阻塞导致的,官方解释以及解决方案,如下:    

线程池
许多人喜欢调整线程池。无论什么原因,人们都对增加线程数无法抵抗。索引太多了?增加线程!搜索太多了?增加线程!节点空闲率低于 95%?增加线程!

Elasticsearch 默认的线程设置已经是很合理的了。对于所有的线程池(除了 搜索 ),线程个数是根据 CPU 核心数设置的。 如果你有 8 个核,你可以同时运行的只有 8 个线程,只分配 8 个线程给任何特定的线程池是有道理的。

搜索线程池设置的大一点,配置为 int(( 核心数 * 3 )/ 2 )+ 1 。

你可能会认为某些线程可能会阻塞(如磁盘上的 I/O 操作),所以你才想加大线程的。对于 Elasticsearch 来说这并不是一个问题:因为大多数 I/O 的操作是由 Lucene 线程管理的,而不是 Elasticsearch。

此外,线程池通过传递彼此之间的工作配合。你不必再因为它正在等待磁盘写操作而担心网络线程阻塞, 因为网络线程早已把这个工作交给另外的线程池,并且网络进行了响应。

最后,你的处理器的计算能力是有限的,拥有更多的线程会导致你的处理器频繁切换线程上下文。 一个处理器同时只能运行一个线程。所以当它需要切换到其它不同的线程的时候,它会存储当前的状态(寄存器等等),然后加载另外一个线程。 如果幸运的话,这个切换发生在同一个核心,如果不幸的话,这个切换可能发生在不同的核心,这就需要在内核间总线上进行传输。

这个上下文的切换,会给 CPU 时钟周期带来管理调度的开销;在现代的 CPUs 上,开销估计高达 30 μs。也就是说线程会被堵塞超过 30 μs,如果这个时间用于线程的运行,极有可能早就结束了。

人们经常稀里糊涂的设置线程池的值。8 个核的 CPU,我们遇到过有人配了 60、100 甚至 1000 个线程。 这些设置只会让 CPU 实际工作效率更低。

所以,下次请不要调整线程池的线程数。如果你真 想调整 , 一定要关注你的 CPU 核心数,最多设置成核心数的两倍,再多了都是浪费

    原文链接:https://www.elastic.co/guide/cn/elasticsearch/guide/current/dont-touch-these-settings.html

 二、重新设置线程池核心线程大小,es数据召回耗时在60ms左右   

private static final int CPU = Runtime.getRuntime().availableProcessors();
private static ExecutorService THREAD_POOL = new ThreadPoolExecutor(CPU,CPU, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),    		
			new ThreadFactoryBuilder().setNameFormat("resume-nsupin-recall-%d").build());

  

   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值