我有十亿条未分类的记录,彼此无关,我必须使用Java在每条记录上调用一个函数 processRecord 。
这样做的简单方法是使用for循环,但这需要花费很多时间。
我能想到的另一种方法是使用多线程,但问题是如何有效地划分记录数据集以及多少线程?
是否有一种有效的方法来处理这个大型数据集?
答案 0 :(得分:2)
<强>测量强> 在确定选择哪个实施路径之前,您应该测量处理单个项目所需的时间。基于此,您可以选择提交给线程池,队列,集群的工作块大小。非常小的工作块会增加协调开销。太大的工作块需要很长时间才能处理,所以你的渐进信息会逐渐减少。
单机处理更容易实现,故障排除维护和理由。
在单机上处理
使用java.util.concurrent.ExecutorService
使用submit(Callable<T> task)
方法https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#submit-java.util.concurrent.Callable-
使用java.util.concurrent.Executors.newFixedThreadPool(int nThreads)
创建ExecutorService的实例。为nThreads选择合理的值Nnumber的CPU核心是合理的启动值。如果在处理过程中存在阻塞IO调用(数据库,HTTP),则可以添加使用更多线程。
在多台计算机上处理 - 群集 将处理作业提交到集群处理技术,如Spark,Hadoop,Google BigQuery。
在多台计算机上处理 - 排队 您可以将记录提交到任何队列系统(Kafka,RabbitMQ,ActiveMQ等)。然后让多台机器使用队列中的项目。您可以随时添加/删除消费者。如果您不需要具有处理结果的单个位置,则此方法很好。
答案 1 :(得分:1)
这里可以使用并行流来执行数据的并行处理。默认情况下,并行流使用池少于处理器计数的一个线程。
有关这方面的广泛且有用的信息可以在https://stackoverflow.com/a/21172732/8184084
找到