用例: 我有一个包含 id 的文件(约 500k( 我的应用程序读取这些文件并处理它们(每个 id 的处理量很大(。 因此,总的来说,此处理需要花费大量时间和内存。
我们需要实现的是扩大进程的数量(在单独的盒子/机器上运行 Java 进程(,并将整个 id 列表划分为一些固定的批量大小,以便 5 个进程开始处理文件中的项目,并在处理完成后拾取下一批。 例如。如果文件中的总项目数为 100,我的批量大小为 5,总共 3 个进程,则处理过程应如下所示
- 过程 1:1-5
- 过程 2:6-10
- 过程 3:11-15
这样,如果进程 2 在其他进程之前完成,则它开始处理 16-20 并通知其他人,以便下一个可用进程选取项目 21-25。
请注意,由于内存限制,我们无法在单个进程/主机上使用多个线程来执行此操作。
有人可以建议解决方案/参考如何实现它。
听起来你有一个分布式计算问题。您有一组"要处理的事情",并希望跨多台计算机进行该处理。最简单和最典型的方法是将这些"要处理的内容"放入分布式队列中,例如Amazon SQS或RabbitMQ(文件将不起作用(。
- 让一个进程(并且只有一个进程(负责将文件传输到分布式队列。如果可以完全避免该文件(并且让写入文件的任何内容只写入队列(,请改为执行此操作。
- 设置多个主机(考虑 Amazon EC2(以从该队列中读取数据,然后进行处理。
- 确保在处理完成后从队列中删除该项目(并根据处理时间设置合理的可见性超时(,以避免其他工作线程主机在不应该拿起该项目时选取该项目。
- 如果需要,可以一次从队列中拉取一个,也可以分批拉取。我建议在每个主机上设置一个线程池来执行轮询/工作/删除循环,这样只需更改线程池大小即可轻松调整每个主机的并发量。
通过使用这样的分布式队列,一个主机占用的项目不会被其他主机看到(从而避免双重处理(。