我需要构建一个作业处理模块,其中作业的传入速率为数百万次。我有一个多处理器机器来运行这些作业。在我当前使用的解决方案Java中,我使用Java的ThreadPoolExecutor框架创建作业队列LinkedListBlockingQueue,并且线程数等于系统上可用的处理器。由于作业队列保持增长,此设计无法支持传入速率,即使CPU利用率未达到最大值,它也会在几秒内报告溢出。 CPU利用率保持在30-40%的范围内。Java:如何构建可扩展的作业处理机制
这意味着大部分时间都会在其他CPU空闲的线程争用中消失。有没有更好的处理作业的方式,以便更好地利用CPU,使作业队列不会溢出?
由于您的电脑利用率太低,这表明有更多的处理带宽..也许增加线程数量将有助于你的情况。尽管分析你的工作可能会让人想到需要多少线程。线程彼此等待的时间越多,您可以创建的线程利用未使用的处理能力越多。但是,如果你在几秒钟内崩溃,即使这不会帮助。也许你需要更多的计算机来分配工作? –
不,线程正在队列中等待按顺序执行作业,该作业持有一个锁,因此当一个线程调用queue.take()时,其他线程将等待。我认为引入更多线程只会使情况更加恶化,因为每个线程都必须等待。可能更多的线程可以帮助,如果工作处理时间更多,每个工作正在做一些I/O,对吧? –
对于如此沉重的负载,即使您设计的高效执行器,传入速率可能会变得过高,并且所有可用内存将被作业队列占用。为了避免它,使用固定或有限容量的ArrayBlockingQueue。与LinkedBlockingQueue相比,它还节省了链接的内存。 –