ThreadPool中的java.lang.Thread和线程性能问题

时间:2019-03-29 06:24:09

标签: multithreading apache-kafka threadpool executorservice consumer

Kafka客户应用程序具有严重的延迟(在高峰时段无法足够快地使用kafka事件)。 kafka主题有120个分区,使用者组共有30个主机,每个主机有两个使用者,因此每个使用者都使用2个kafka分区。我们使用的主机是具有32核的AWS C5.9xlarge实例。每个使用者都放在一个java.lang.Thread中,并且在每个线程中创建了一个带有250个线程的ThreadPool。

我们已经验证了CPU /内存/ IO都不是瓶颈。然后,我们将250名工人增加到500名工人,但延迟保持不变。然后,我们又改回了250名工作人员,但每台主机从2个增加到4个消费者。结果,每个消费者从一个kafka分区消费。现在问题解决了,延迟降低到了非常低的水平。

我的问题是,为什么在Threadpool中从250增加到500并没有帮助,但是每台主机从2到4的消费者增加却有所帮助?

private class ConsumerThread extends Thread {
    public ConsumerThread(StremProcessor processor) {
      this.processor = processor;
      this.consumer = new KafkaConsumer()
    }
    @Override
    public void run() {
        ExecutorService executor = Executors.newFixedThreadPool(250);
        while (true) {
          Data data = consumer.poll()
          executor.invokeAll(getTasks(data, processor)); //processor is 
        }    
    }
}

2 个答案:

答案 0 :(得分:0)

线程池不过是reusable的{​​{1}}池。通常,线程池有一个java.lang.Thread,如果线程池中有任何线程空闲,它可以执行任务,当任务完成后,线程返回池并尝试查找是否有其他任务在等待。队列。

  

ThreadPool中的线程与java.lang.Thread有何不同?

没有区别。只是用法不同。

  

是因为ThreadPool中的所有线程都使用一个   处理器内核?

否,它可以使用任意数量的可用处理器。

  

我记得ExecutorPool中的默认线程是250   处理器,这是否意味着ExecutorPool不够智能,无法   将250个线程分配到16个内核?

您从哪里获得诸如“ ExecutorPool每个处理器250个”之类的信息?我不完全理解你的问题。线程池的线程可以像普通线程一样在任何内核上执行,线程池的线程没有任何限制。

答案 1 :(得分:0)

首先:在每个循环之间的while循环中应包含一些延迟,以防止应用程序淹没内存。

基本上,ExecutorService.invokeAll()方法返回Future的列表。您可以使用它们来“控制”线程。

  

ThreadPool中的线程与java.lang.Thread有何不同?

它们没有什么不同,但是您得到了包装器(Future),该包装器使您可以在执行时控制线程。基础Thread的工作方式与通常的Java线程类似。

  

是因为ThreadPool中的所有线程都使用一个处理器   核心?