为什么这个简单的Spark程序不使用多个内核?

时间:2014-11-09 13:59:52

标签: python scala bigdata apache-spark multicore

所以,我在16核多核系统上运行这个简单的程序。我跑了 发布以下内容。

spark-submit --master local[*] pi.py

该程序的代码如下。

#"""pi.py"""
from pyspark import SparkContext
import random

N = 12500000

def sample(p):
    x, y = random.random(), random.random()
    return 1 if x*x + y*y < 1 else 0

sc = SparkContext("local", "Test App")
count = sc.parallelize(xrange(0, N)).map(sample).reduce(lambda a, b: a + b)
print "Pi is roughly %f" % (4.0 * count / NUM_SAMPLES)

当我使用top来查看CPU时 消费,只使用了1个核心。为什么会这样? Seconldy,火花 文档说默认并行性包含在属性中 spark.default.parallelism 。我如何从我的内部阅读这个属性 python程序?

4 个答案:

答案 0 :(得分:16)

由于以上都没有真正对我有用(也许是因为我并不真正理解它们),这是我的两分钱。

我开始使用spark-submit program.py并在我sc = SparkContext("local", "Test")的文件中开始工作。我尝试使用sc.defaultParallelism验证核心数 spark 看到。事实证明它是1.当我将上下文初始化更改为sc = SparkContext("local[*]", "Test")时,它变为16(我的系统的核心数),我的程序正在使用所有核心。

我是 spark 的新手,但我的理解是默认情况下 local 表示使用了一个核心并且因为它在程序中设置,它会覆盖其他设置(在我的情况下肯定会覆盖配置文件和环境变量中的设置)。

答案 1 :(得分:5)

可能是因为对sc.parallelize的调用将所有数据放入一个单独的分区。您可以将分区数指定为并行化的第二个参数:

part = 16
count = sc.parallelize(xrange(N), part).map(sample).reduce(lambda a, b: a + b)

请注意,这仍然会在驱动程序中生成一个CPU产生1200万个点,然后只将它们分散到16个分区以执行reduce步骤。

更好的方法是在分区后尝试完成大部分工作:例如,以下内容仅在驱动程序上生成一个小数组,然后让每个远程任务生成实际的随机数和随后的PI近似值:

part = 16
count = ( sc.parallelize([0] * part, part)
           .flatMap(lambda blah: [sample(p) for p in xrange( N/part)])
           .reduce(lambda a, b: a + b)
       )

最后,(因为我们越懒越越好),spark mllib实际上已经有了一个很好地并行化的随机数据生成,请看一下:http://spark.apache.org/docs/1.1.0/mllib-statistics.html#random-data-generation。所以也许以下内容接近您尝试做的事情(未测试=&gt;可能无法正常工作,但希望能够接近)

count = ( RandomRDDs.uniformRDD(sc, N, part)
        .zip(RandomRDDs.uniformRDD(sc, N, part))
        .filter (lambda (x, y): x*x + y*y < 1)
        .count()
        )

答案 2 :(得分:1)

要更改CPU核心消耗,请在spark-env.sh spark-installation-directory/conf文件中设置工作人员使用的核心数 这是通过spark-env.sh文件中的SPARK_EXECUTOR_CORES属性完成的。 默认情况下,该值设置为1。

答案 3 :(得分:1)

我尝试了@Svend提到的方法,但仍然无效。

以下适用于我:

使用sc = SparkContext("local", "Test App")网址,例如:

sc = SparkContext("spark://your_spark_master_url:port", "Test App")

使用这样的主URL:

$sXML = pack( 'n', 0xFEFF ) . iconv( '', 'UCS-2BE', $sXML );