【问题标题】:Performance problem of java.lang.Thread and threads in ThreadPooljava.lang.Thread和ThreadPool中线程的性能问题
【发布时间】:2023-03-27 10:46:02
【问题描述】:

Kafka 消费者应用程序具有严重的延迟(在高峰时段没有足够快地消耗 kafka 事件)。 kafka topic有120个partition,consumer group一共有30个host,每个host有两个consumer,所以每个consumer从2个kafka partition消费。我们使用的主机是 32 核的 AWS C5.9xlarge 实例。每个消费者都被放入一个 java.lang.Thread 中,并且在每个线程中,创建一个包含 250 个线程的 ThreadPool。

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

我的问题是,为什么线程池中从 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 
        }    
    }
}

【问题讨论】:

    标签: multithreading apache-kafka threadpool executorservice consumer


    【解决方案1】:

    首先:您应该在每个循环之间的 while 循环中加入一些延迟,以防止您的应用程序占用您的内存。

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

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

    它们没有区别,但是您会得到一个包装器 (Future),它可以让您在执行时控制线程。底层的Thread 像普通的Java 线程一样工作。

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

    没有

    【讨论】:

    • 感谢回复!!真正的问题是:为什么线程池中从 250 个增加到 500 个没有帮助,但每个主机从 2 个增加到 4 个消费者有帮助?我问这个的原因是,由于 ThreadPool 线程与 java.lang.Thread 相同,并且这两种方法都有效地有 1000 个(500*2 或 250*4)线程,为什么性能不同?
    【解决方案2】:

    线程池不过是java.lang.Threadreusable 池。通常,线程池有一个queue of tasks,如果线程池中的任何线程空闲,它就可以执行任务,当任务完成后,线程回到池中并尝试查找队列中是否有其他任务等待。

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

    没有区别。只是用法上的区别。

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

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

    我记得 ExecutorPool 中的默认线程是 250 个 处理器,这是否意味着 ExecutorPool 不够聪明 将 250 个线程分配给 16 个内核?

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

    【讨论】:

    • 感谢回复!!真正的问题是:为什么线程池中从 250 个增加到 500 个没有帮助,但每个主机从 2 个增加到 4 个消费者有帮助?我要问的是,既然 ThreadPool 线程与 java.lang.Thread 相同,并且这两种方法都有效地有 1000 个(500*2 或 250*4)线程,为什么性能不同?
    猜你喜欢
    • 2011-10-15
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 2014-03-06
    • 2012-08-24
    • 1970-01-01
    相关资源
    最近更新 更多