Sparkについてのドキュメント アプリケーション内でのスケジューリング :
特定のSparkアプリケーション(SparkContextインスタンス)内で、複数の並列ジョブが別々のスレッドから送信された場合、それらを同時に実行できます。「ジョブ」とは、このセクションでは、Sparkアクション(例:保存、収集)およびそのアクションを評価するために実行する必要のあるタスク。Sparkのスケジューラは完全にスレッドセーフであり、このユースケースをサポートして、複数のリクエスト(例:複数のユーザーのクエリ)を提供するアプリケーションを有効にします。 」
ScalaとJavaで同じコードの例をいくつか見つけることができました。PySparkを使用してこれを実装する方法の例を誰かが示すことができますか?
同じ問題が発生したため、小さな自己完結型の例を作成しました。 Pythonのスレッドモジュールを使用して複数のスレッドを作成し、複数のsparkジョブを同時に送信します。
デフォルトでは、sparkは先入れ先出し(FIFO)でジョブを実行します: http://spark.Apache.org/docs/latest/job- schedule.html#scheduling-within-an-application 。以下の例では、FAIRスケジューリングに変更します
# Prereqs:
# set
# spark.dynamicAllocation.enabled true
# spark.shuffle.service.enabled true
spark.scheduler.mode FAIR
# in spark-defaults.conf
import threading
from pyspark import SparkContext, SparkConf
def task(sc, i):
print sc.parallelize(range(i*10000)).count()
def run_multiple_jobs():
conf = SparkConf().setMaster('local[*]').setAppName('appname')
# Set scheduler to FAIR: http://spark.Apache.org/docs/latest/job-scheduling.html#scheduling-within-an-application
conf.set('spark.scheduler.mode', 'FAIR')
sc = SparkContext(conf=conf)
for i in range(4):
t = threading.Thread(target=task, args=(sc, i))
t.start()
print 'spark task', i, 'has started'
run_multiple_jobs()
出力:
spark task 0 has started
spark task 1 has started
spark task 2 has started
spark task 3 has started
30000
0
10000
20000
今日も同じことを聞いていました。マルチプロセッシングモジュールはThreadPool
を提供します。これはいくつかのスレッドを生成するため、ジョブを並列で実行します。最初に関数をインスタンス化し、次にプールを作成してから、反復したい範囲でそれをmap
します。
私の場合、さまざまな中心数(ハイパーパラメーターチューニング)に対してこれらのWSSSE数を計算して、 MLSparkドキュメント 。これ以上の説明はありませんが、ここに私のIPythonワークシートのいくつかのセルがあります。
from pyspark.mllib.clustering import KMeans
import numpy as np
c_pointsは12dim配列です:
>>> c_points.cache()
>>> c_points.take(3)
[array([ 1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]),
array([-2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]),
array([ 7, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
以下では、各i
について、このWSSSE値を計算してタプルとして返しています。
def error(point, clusters):
center = clusters.centers[clusters.predict(point)]
return np.linalg.norm(point - center)
def calc_wssse(i):
clusters = KMeans.train(c_points, i, maxIterations=20,
runs=20, initializationMode="random")
WSSSE = c_points\
.map(lambda point: error(point, clusters))\
.reduce(lambda x, y: x + y)
return (i, WSSSE)
ここから興味深い部分が始まります:
from multiprocessing.pool import ThreadPool
tpool = ThreadPool(processes=4)
それを実行します:
wssse_points = tpool.map(calc_wssse, range(1, 30))
wssse_points
与える:
[(1, 195318509740785.66),
(2, 77539612257334.33),
(3, 78254073754531.1),
...
]