Spark JVMとメモリーの管理

DataStax Enterpriseで実行されているSparkジョブは、複数の異なるJVMプロセス間で分割されます。

DataStax Enterpriseで実行されているSparkジョブは、複数の異なるJVMプロセス間で分割されます。これらのプロセスはそれぞれ異なるメモリー要件を持っています。

CassandraとSparkマスターのJVM

SparkマスターはCassandraと同じプロセスで実行されますが、そのメモリーの使用量はわずかです。SparkがCassandraでOutOfMemoryErrorを発生させる唯一の状況は、クライアント要求キューが一杯になるCassandraクエリーが間接的に実行された場合のみです。たとえば、高い制限値でクエリーが実行され、ページングが無効になっていたか、非常に大きなバッチを使用してテーブル内のデータの更新またはデータの挿入が行われた場合です。これはcassandra-env.sh内のMAX_HEAP_SIZEによって制御されます。system.logOutOfMemoryErrorが見つかった場合は、それをCassandraの標準のOutOfMemoryErrorとして取り扱い、通常のトラブルシューティング手順に従ってください。

SparkエグゼキューターのJVM

Sparkエグゼキューターは、SparkがRDDに対して変換や操作を実行する場所で、通常はここでSpark関連のOutOfMemoryErrorが発生します。エグゼキューター内のOutOfMemoryErrorは、現在実行中のアプリケーションのstderrログ(通常は/var/lib/spark内)に記録されます。エグゼキューターのメモリーを制御する構成設定は複数存在し、これらは複雑な方法で互いに関係します。

  • spark-env.sh内のSPARK_WORKER_MEMORYはメモリーの最大量で、特定のノードで実行されているすべてのアプリケーションに対してすべてのエグゼキューターに与えられます。
  • dse.yaml内のinitial_spark_worker_resourcesは、それがコメント・アウトされている場合(デフォルトの場合)にSPARK_WORKER_MEMORYを自動的に計算するために使用されます。これには次の数式が使用されます。

    initial_spark_worker_resources * (total system memory - memory assigned to Cassandra)

  • spark.executor.memoryは、特定のアプリケーションに与えられるエグゼキューターのメモリー量を制御するシステム・プロパティです。これはSPARK_WORKER_MEMORY以下にする必要があります。これはドライバー・アプリケーション内でSparkContextに対するコンストラクターで指定するか、--conf spark.executor.memoryまたは--executor-memoryコマンド・ライン・オプションを経由して、spark submitを使用してジョブを送信する際に指定できます。
spark-env.shファイルのデフォルトの場所は、インストールのタイプによって異なります。
Installer-Servicesおよびパッケージ・インストール /etc/dse/spark/spark-env.sh
Installer-No Servicesおよびtarボール・インストール install_location/resources/spark/conf/spark-env.sh
dse.yamlファイルの場所は、インストールのタイプによって異なります。
Installer-Services /etc/dse/dse.yaml
パッケージ・インストール /etc/dse/dse.yaml
Installer-No Services install_location/resources/dse/conf/dse.yaml
tarボール・インストール install_location/resources/dse/conf/dse.yaml
cassandra-env.shファイルの場所は、インストールのタイプによって異なります。
パッケージ・インストール /etc/dse/cassandra/cassandra-env.sh
tarボール・インストール install_location/resources/cassandra/conf/cassandra-env.sh

クライアント・ドライバーのJVM

ドライバーは、Sparkジョブ用のクライアント・プログラムです。ほとんどのデータはエグゼキューター内で処理されるため、通常は大量のメモリーは必要ありません。数ギガバイトを超えるメモリーが必要な場合は、アプリケーションがcollectまたはtakeを使用して、アンチパターンによりRDDのすべてのデータをローカル・データ構造に取り込んでいる可能性があります。通常、実稼働コードではcollectは絶対に使用すべきではなく、takeを使用する場合は、少数のレコードのみを取り込むようにします。ドライバーのメモリーが不足した場合は、stderrドライバーまたは構成されているログの記録先にOutOfMemoryErrorが表示されます。これは次の2つの場所で制御されます。

  • spark-env.sh内のSPARK_DRIVER_MEMORY
  • spark submitを使用したジョブの送信時に--conf spark.driver.memoryまたは--driver-memoryコマンド・ライン・オプションを経由して指定できる、spark.driver.memoryシステム・プロパティ。これをSparkContextコンストラクターで指定することはできません。その時点までにドライバーがすでに起動しているためです。

SparkワーカーのJVM

ワーカーは、エグゼキューターを生成するウォッチドッグ・プロセスで、そのヒープ・サイズを大きくする必要は決してありません。ワーカーのヒープ・サイズはspark-env.sh内のSPARK_DAEMON_MEMORYによって制御されます。SPARK_DAEMON_MEMORYもSpark SQL Thriftサーバーのヒープ・サイズに影響を及ぼします。