在Scala/Hoop系统中,充分利用多核进行并行处理的更好方法是什么?
比方说,我需要处理1亿份文件。文档不是很大,但是处理它们是计算密集型的。如果我有一个Hadoop集群,其中有100台机器,每台机器有10个核心,我可以:
A) 向每台机器发送1000个文档,并让Hadoop在10个核心(或可用的数量)中的每一个上启动一个映射
或
B) 向每台机器发送1000个文档(仍在使用Hadoop),并使用Scala的并行集合来充分利用多个核心。(我会把所有文档放在一个并行集合中,然后在集合上调用map
)。换句话说,使用Hadoop在集群级别进行分发,并使用并行集合来管理分发到每台机器中的核心。
Hadoop将提供的不仅仅是并行化。它提供了一个分发工作的平台、一个处理并发作业的调度器、一个分布式文件系统、执行分布式reduce的能力以及容错能力。也就是说,这是一个复杂的系统,有时很难使用。
如果您计划让多个用户提交许多不同的作业,Hadoop是最好的选择(两种选择中的一种)。然而,如果您致力于让集群始终通过相同的功能处理文档,那么您可以开发一个具有Scala并行集合和参与者的系统,用于机器间通信,而不会遇到太多麻烦。Scala解决方案将给你更多的控制权,系统可以实时响应,你不必处理很多与你的任务无关的Hadoop配置。
如果您需要在大量数据上运行各种作业(比单个节点所能容纳的数据大),那么就使用Hadoop。如果你更详细地描述你的要求,我可以给你更多的信息。
更新:100万是一个相当小的数字。你可能想做一些计算,看看在一台具有并行集合的机器上需要多长时间。这里的优点是开发时间最短!
答案取决于以下问题-您的Scala代码是否能够充分利用所有可用的核心。如果您在要处理的文档部分之间有良好的内在同步,或者以某种其他方式在没有锁争用的情况下对算法进行并行处理,则可能会使用"B"。如果是这样,则为每个节点配置一个映射器,并让您的映射器以最佳方式利用核心。
如果你从并行化中获得的收益不是那么好,并且在处理中添加更多的线程(核心)并不能以线性方式提高性能,那么"a"可能是更好的方式。"A"的效率也取决于RAM的大小——每个节点需要足够的RAM来容纳10个映射器
我怀疑理想的解决方案可能介于两者之间。因此,我的建议是开发以线程数为参数的映射器,然后进行一些测试,增加每个映射器的线程数,减少每个节点的映射器数
Hadoop不太适合处理很多小文件,但适合处理少量非常大的文件。有没有什么方法可以在处理文件之前合并这些文件,或者它们完全不同?Hadoop本身负责分发和并行,因此不需要显式地将X文档发送到Y机器。而且我不认为你应该只把hadoop作为一种分发机制来使用,这不是它的初衷。你应该使用一个真正的map/reduce,或者为你想要做的任何事情构建你自己的系统,但不要试图让hadoop屈从于你的意愿。