web-dev-qa-db-ja.com

PySpark内の可視ノードの数を取得する

PySparkでいくつかの操作を実行していて、最近(Amazon EMRにある)構成でノードの数を増やしました。ただし、ノード数を3倍(4から12)にしても、パフォーマンスは変化していないようです。そのため、新しいノードがSparkに表示されるかどうかを確認します。

次の関数を呼び出しています:

sc.defaultParallelism
>>>> 2

しかし、これは、Sparkが認識できるコードの総数ではなく、各ノードに分散されたタスクの総数を示していると思います。

PySparkがクラスターで使用しているノードの数を確認するにはどうすればよいですか?

20
Bryan

_sc.defaultParallelism_は単なるヒントです。構成によっては、ノードの数とは関係がない場合があります。これは、パーティションカウント引数を取る操作を使用するが、提供しない場合のパーティション数です。たとえば、_sc.parallelize_はリストから新しいRDDを作成します。 2番目の引数を使用して、RDDに作成するパーティションの数を指定できます。ただし、この引数のデフォルト値は_sc.defaultParallelism_です。

Scala APIでは_sc.getExecutorMemoryStatus_を使用してエグゼキューターの数を取得できますが、これはPython APIでは公開されていません。

一般に、推奨事項は、エグゼキューターの約4倍のパーティションをRDDに含めることです。これは良いヒントです。タスクにかかる時間にばらつきがある場合は、それが解消されるからです。たとえば、一部のエグゼキューターは5つの高速タスクを処理し、他のエグゼクターは3つの低速タスクを処理します。

これで非常に正確である必要はありません。大まかなアイデアがある場合は、見積もりで行くことができます。 CPUの数が200未満であることがわかっている場合と同様に、500パーティションで問題ないと言えます。

したがって、次の数のパーティションでRDDを作成してみてください。

_rdd = sc.parallelize(data, 500)     # If distributing local data.
rdd = sc.textFile('file.csv', 500)  # If loading data from a file.
_

または、RDDの作成を制御しない場合は、計算の前にRDDを再分割します。

_rdd = rdd.repartition(500)
_

rdd.getNumPartitions()を使用して、RDDのパーティション数を確認できます。

16
Daniel Darabos

Pysparkでは、pysparkのpy4jブリッジを使用してscala getExecutorMemoryStatus AP​​Iを呼び出すことができます。

sc._jsc.sc().getExecutorMemoryStatus().size()
25
Nic

これを使用して、クラスター内のノード数を取得できるはずです(上記の@Danの方法に似ていますが、短くて機能します)。

sc._jsc.sc().getExecutorMemoryStatus().keySet().size()
4
Charles Newey

リモートによってセッションが強制終了されて、奇妙なJavaエラーが発生することがありました。

Py4JJavaError: An error occurred while calling o349.defaultMinPartitions.
: Java.lang.IllegalStateException: Cannot call methods on a stopped SparkContext.

私はこれを次のようにして避けました

def check_alive(spark_conn):
    """Check if connection is alive. ``True`` if alive, ``False`` if not"""
    try:
        get_Java_obj = spark_conn._jsc.sc().getExecutorMemoryStatus()
        return True
    except Exception:
        return False

def get_number_of_executors(spark_conn):
    if not check_alive(spark_conn):
        raise Exception('Unexpected Error: Spark Session has been killed')
    try:
        return spark_conn._jsc.sc().getExecutorMemoryStatus().size()
    except:
        raise Exception('Unknown error')
1

他の回答は、実行者の数を取得する方法を提供します。ノードの数を取得する方法は次のとおりです。これには、ヘッドノードとワーカーノードが含まれます。

s = sc._jsc.sc().getExecutorMemoryStatus().keys()
l = str(s).replace("Set(","").replace(")","").split(", ")

d = set()
for i in l:
    d.add(i.split(":")[0])
len(d)