SSH を使用して Apache Spark アプリケーションをリモートでデバッグすることをお勧めします。 手順については、SSH 経由で Azure Toolkit for IntelliJ を使用して HDInsight クラスター上の Apache Spark アプリケーションをリモートでデバッグする方法に関するページを参照してください。
この記事では、Azure Toolkit for IntelliJ の HDInsight ツールを使用して HDInsight Spark クラスターで Spark ジョブを送信し、デスクトップ コンピューターからリモートでデバッグする方法について詳しく説明します。 これらのタスクを完了するには、次の大まかな手順を実行する必要があります。
- サイト間またはポイント対サイトの Azure 仮想ネットワークを作成します。 このドキュメントの手順では、サイト間ネットワークを使用することを前提としています。
- サイト間仮想ネットワークの一部である SPARK クラスターを HDInsight に作成します。
- クラスター ヘッド ノードとデスクトップの間の接続を確認します。
- IntelliJ IDEA で Scala アプリケーションを作成し、リモート デバッグ用に構成します。
- アプリケーションを実行してデバッグします。
[前提条件]
- Azure サブスクリプション。
- HDInsight の Apache Spark クラスター。 手順については、「Azure HDInsight 内に Apache Spark クラスターを作成する」を参照してください。
- Oracle Java 開発キット。 Oracle Web サイトからインストールできます。
- IntelliJ IDEA。 この記事では、バージョン 2017.1 を使用します。 JetBrains Web サイトからインストールできます。
- Azure Toolkit for IntelliJ の HDInsight ツール。 IntelliJ 用の HDInsight ツールは、Azure Toolkit for IntelliJ の一部として利用できます。 Azure Toolkit をインストールする方法については、「Azure Toolkit for IntelliJ のインストール」を参照してください。
- IntelliJ IDEA から Azure サブスクリプションにサインインします。 「Azure Toolkit for IntelliJ を使用して HDInsight クラスター用の Apache Spark アプリケーションを作成する」の手順に従います。
- 例外の回避策。 Windows コンピューターでリモート デバッグ用の Spark Scala アプリケーションを実行しているときに、例外が発生する場合があります。 この例外は SPARK-2356 で説明されており、Windows に WinUtils.exe ファイルがないために発生します。 このエラーを回避するには、C:\WinUtils\bin などの場所に Winutils.exe をダウンロードする必要があります。 HADOOP_HOME環境変数を追加し、変数の値を C\WinUtils に設定します。
手順 1. Azure 仮想ネットワークを作成する
次のリンクの手順に従って Azure 仮想ネットワークを作成し、デスクトップ コンピューターと仮想ネットワークの間の接続を確認します。
- Azure portal を使用してサイト間 VPN 接続を持つ VNet を作成する
- PowerShell を使用してサイト間 VPN 接続を使用して VNet を作成する
- PowerShell を使用して仮想ネットワークへのポイント対サイト接続を構成する
手順 2: HDInsight Spark クラスターを作成する
また、作成した Azure 仮想ネットワークの一部である Apache Spark クラスターを Azure HDInsight に作成することをお勧めします。 HDInsight での Linux ベースのクラスターの作成に関する記事で入手できる情報を使用します。 オプションの構成の一部として、前の手順で作成した Azure 仮想ネットワークを選択します。
手順 3: クラスター ヘッド ノードとデスクトップの間の接続を確認する
ヘッド ノードの IP アドレスを取得します。 クラスターの Ambari UI を開きます。 クラスター ブレードで、[ダッシュボード] を選択 します。
Ambari UI から [ホスト] を選択 します。
ヘッド ノード、ワーカー ノード、および Zookeeper ノードの一覧が表示されます。 ヘッド ノードには hn* プレフィックスがあります。 最初のヘッド ノードを選択します。
開いたページの下部にある [概要 ] ウィンドウから、ヘッド ノードの IP アドレス と ホスト名をコピーします。
Spark ジョブを実行してリモートでデバッグするコンピューター上の hosts ファイルに、ヘッド ノードの IP アドレスと ホスト 名を追加します。 これにより、IP アドレスとホスト名を使用してヘッド ノードと通信できます。
a. 管理者特権でメモ帳ファイルを開きます。 [ ファイル ] メニューの [ 開く] を選択し、hosts ファイルの場所を見つけます。 Windows コンピューターでは、場所は C:\Windows\System32\Drivers\etc\hosts です。
b。 hosts ファイルに次の情報を追加します。
# For headnode0 192.xxx.xx.xx nitinp 192.xxx.xx.xx nitinp.lhwwghjkpqejawpqbwcdyp3.gx.internal.cloudapp.net # For headnode1 192.xxx.xx.xx nitinp 192.xxx.xx.xx nitinp.lhwwghjkpqejawpqbwcdyp3.gx.internal.cloudapp.net
HDInsight クラスターで使用される Azure 仮想ネットワークに接続したコンピューターから、IP アドレスとホスト名を使用してヘッド ノードに ping できることを確認します。
SSH を使用してクラスター ヘッド ノードに接続するには、SSH を使用した HDInsight クラスターへの接続に関する記事の手順に従ってください。 クラスター ヘッド ノードから、デスクトップ コンピューターの IP アドレスに ping を実行します。 コンピューターに割り当てられている両方の IP アドレスへの接続をテストします。
- ネットワーク接続用の 1 つ
- Azure 仮想ネットワーク用の 1 つ
もう一方のヘッド ノードの手順を繰り返します。
手順 4: Azure Toolkit for IntelliJ で HDInsight ツールを使用して Apache Spark Scala アプリケーションを作成し、リモート デバッグ用に構成する
IntelliJ IDEA を開き、新しいプロジェクトを作成します。 [新しいプロジェクト ] ダイアログ ボックスで、次の操作を行います。
a. [HDInsight>Spark on HDInsight (Scala)] を選択します。
b。 [次へ] を選択します。
次の [ 新しいプロジェクト ] ダイアログ ボックスで、次の操作を行い、[ 完了] を選択します。
プロジェクトの名前と場所を入力します。
[Project SDK]\(プロジェクト SDK\) ドロップダウン リストで、Spark 2.x クラスターの場合は [Java 1.8] を選択し、Spark 1.x クラスターの場合は [Java 1.7] を選択します。
Spark バージョンのドロップダウン リストでは、Scala プロジェクト作成ウィザードによって、Spark SDK と Scala SDK の適切なバージョンが統合されます。 Spark クラスターのバージョンが 2.0 より前の場合は、[Spark 1.x] を選択します。 それ以外の場合は、[Spark2.x] を選択します。 この例では、[Spark 2.0.2 (Scala 2.11.8)] を使用します。
Spark プロジェクトによって自動的に成果物が作成されます。 成果物を表示するには、次の操作を行います。
a. [ ファイル ] メニューの [ プロジェクト構造] を選択します。
b。 [Project Structure]\(プロジェクト構造\) ダイアログ ボックスで、[Artifacts]\(成果物\) を選択して、作成された既定の成果物を表示します。 プラス記号 (+) を選択して、独自の成果物を作成することもできます。
プロジェクトにライブラリを追加します。 ライブラリを追加するには、次の操作を行います。
a. プロジェクト ツリーでプロジェクト名を右クリックし、[ モジュール設定を開く] を選択します。
b。 [ プロジェクト構造 ] ダイアログ ボックスで、[ ライブラリ] を選択し、(+) シンボルを選択して、[ Maven から] を選択します。
c. [ Maven リポジトリからライブラリをダウンロード する] ダイアログ ボックスで、次のライブラリを検索して追加します。
org.scalatest:scalatest_2.10:2.2.1
org.apache.hadoop:hadoop-azure:2.7.1
クラスター ヘッド ノードから
yarn-site.xml
とcore-site.xml
をコピーし、プロジェクトに追加します。 次のコマンドを使用してファイルをコピーします。 Cygwin を使用して、次のscp
コマンドを実行して、クラスター ヘッド ノードからファイルをコピーできます。scp <ssh user name>@<headnode IP address or host name>://etc/hadoop/conf/core-site.xml .
デスクトップ上の hosts ファイルのクラスター ヘッド ノードの IP アドレスとホスト名が既に追加されているため、次の方法で
scp
コマンドを使用できます。scp sshuser@nitinp:/etc/hadoop/conf/core-site.xml . scp sshuser@nitinp:/etc/hadoop/conf/yarn-site.xml .
これらのファイルをプロジェクトに追加するには、プロジェクト ツリーの /src フォルダーの下にコピーします (例:
<your project directory>\src
)。core-site.xml
ファイルを更新して、次の変更を行います。a. 暗号化されたキーを置き換えます。
core-site.xml
ファイルには、クラスターに関連付けられているストレージ アカウントに対する暗号化されたキーが含まれています。 プロジェクトに追加したcore-site.xml
ファイルで、暗号化されたキーを、既定のストレージ アカウントに関連付けられている実際のストレージ キーに置き換えます。 詳細については、「ストレージ アカウントのアクセス キーの管理」を参照してください。<property> <name>fs.azure.account.key.hdistoragecentral.blob.core.windows.net</name> <value>access-key-associated-with-the-account</value> </property>
b。
core-site.xml
から次のエントリを削除します。<property> <name>fs.azure.account.keyprovider.hdistoragecentral.blob.core.windows.net</name> <value>org.apache.hadoop.fs.azure.ShellDecryptionKeyProvider</value> </property> <property> <name>fs.azure.shellkeyprovider.script</name> <value>/usr/lib/python2.7/dist-packages/hdinsight_common/decrypt.sh</value> </property> <property> <name>net.topology.script.file.name</name> <value>/etc/hadoop/conf/topology_script.py</value> </property>
c. ファイルを保存します。
アプリケーションのメイン クラスを追加します。 プロジェクト エクスプローラーでsrc を右クリックし、[新規] をポイントして Scala クラスを選択します。
[新しい Scala クラスの作成] ダイアログ ボックスで、名前を指定し、[種類] ボックスで [オブジェクト] を選択し、[OK] を選択します。
MyClusterAppMain.scala
ファイルに、次のコードを貼り付けます。 このコードは、Spark コンテキストを作成し、executeJob
オブジェクトからSparkSample
メソッドを開きます。import org.apache.spark.{SparkConf, SparkContext} object SparkSampleMain { def main (arg: Array[String]): Unit = { val conf = new SparkConf().setAppName("SparkSample") .set("spark.hadoop.validateOutputSpecs", "false") val sc = new SparkContext(conf) SparkSample.executeJob(sc, "wasb:///HdiSamples/HdiSamples/SensorSampleData/hvac/HVAC.csv", "wasb:///HVACOut") } }
手順 8 と 9 を繰り返して、
*SparkSample
という新しい Scala オブジェクトを追加します。 以下のコードをこのクラスに追加します。 このコードは、HVAC.csv (すべての HDInsight Spark クラスターで使用可能) からデータを読み取ります。 CSV ファイルの 7 番目の列に 1 桁しかない行を取得し、クラスターの既定のストレージ コンテナーの下の /HVACOut に出力を書き込みます。import org.apache.spark.SparkContext object SparkSample { def executeJob (sc: SparkContext, input: String, output: String): Unit = { val rdd = sc.textFile(input) //find the rows which have only one digit in the 7th column in the CSV val rdd1 = rdd.filter(s => s.split(",")(6).length() == 1) val s = sc.parallelize(rdd.take(5)).cartesian(rdd).count() println(s) rdd1.saveAsTextFile(output) //rdd1.collect().foreach(println) } }
手順 8 と 9 を繰り返して、
RemoteClusterDebugging
という新しいクラスを追加します。 このクラスは、アプリケーションのデバッグに使用される Spark テスト フレームワークを実装します。 以下のコードをRemoteClusterDebugging
クラスに追加します。import org.apache.spark.{SparkConf, SparkContext} import org.scalatest.FunSuite class RemoteClusterDebugging extends FunSuite { test("Remote run") { val conf = new SparkConf().setAppName("SparkSample") .setMaster("yarn-client") .set("spark.yarn.am.extraJavaOptions", "-Dhdp.version=2.4") .set("spark.yarn.jar", "wasb:///hdp/apps/2.4.2.0-258/spark-assembly-1.6.1.2.4.2.0-258-hadoop2.7.1.2.4.2.0-258.jar") .setJars(Seq("""C:\workspace\IdeaProjects\MyClusterApp\out\artifacts\MyClusterApp_DefaultArtifact\default_artifact.jar""")) .set("spark.hadoop.validateOutputSpecs", "false") val sc = new SparkContext(conf) SparkSample.executeJob(sc, "wasb:///HdiSamples/HdiSamples/SensorSampleData/hvac/HVAC.csv", "wasb:///HVACOut") } }
注意すべき重要な点がいくつかあります。
-
.set("spark.yarn.jar", "wasb:///hdp/apps/2.4.2.0-258/spark-assembly-1.6.1.2.4.2.0-258-hadoop2.7.1.2.4.2.0-258.jar")
の場合は、指定したパスにあるクラスター ストレージで Spark アセンブリ JAR を使用できることを確認します。 -
setJars
の場合は、アーティファクト JAR が作成される場所を指定します。 通常は、<Your IntelliJ project directory>\out\<project name>_DefaultArtifact\default_artifact.jar
です。
-
クラスで
*RemoteClusterDebugging
、test
キーワードを右クリックし、[ RemoteClusterDebugging 構成の作成] を選択します。[ RemoteClusterDebugging 構成の作成 ] ダイアログ ボックスで、構成の名前を指定し、テスト名として [ テストの種類 ] を選択 します。 その他の値はすべて既定の設定のままにします。 [Apply](適用) を選択し、次に [OK] を選択します。
これで、メニュー バーに [リモート実行 構成] ドロップダウン リストが表示されます。
手順 5: デバッグ モードでアプリケーションを実行する
IntelliJ IDEA プロジェクトで、
SparkSample.scala
を開き、val rdd1
の横にブレークポイントを作成します。 [Create Breakpoint for]\(ブレークポイントの作成対象\) ポップアップ メニューで [line in function executeJob]\(executeJob 関数内の行\) を選択します。アプリケーションを実行するには、[リモート実行構成] ドロップダウン リストの横にある [デバッグ実行] ボタンを選択します。
プログラムの実行がブレークポイントに達すると、下部のウィンドウに [デバッガー ] タブが表示されます。
ウォッチを追加するには、(+) アイコンを選択します。
この例では、変数
rdd1
が作成される前にアプリケーションが中断されました。 このウォッチを使用すると、変数rdd
の最初の 5 行を確認できます。 「を選択し、を入力します。」前の図に示されているのは、実行時にテラバイト単位のデータに対してクエリを実行し、アプリケーションの進行状況をデバッグできることです。 たとえば、前の図に示した出力では、出力の最初の行がヘッダーであることがわかります。 この出力に基づいて、必要に応じて、ヘッダー行をスキップするようにアプリケーション コードを変更できます。
[ プログラムの再開 ] アイコンを選択して、アプリケーションの実行を続行できるようになりました。
アプリケーションが正常に完了すると、次のような出力が表示されます。
次のステップ
シナリオ
- Apache Spark と BI: HDInsight 上の Spark と BI ツールを使用して対話型データ分析を実行する
- Apache Spark と Machine Learning: HDInsight 上で Spark を使用して、HVAC データを使用して建物の温度を分析する
- Apache Spark と Machine Learning: HDInsight 上で Spark を使用して食品の検査結果を予測する
- HDInsight 上での Apache Spark を使用した Web サイト ログ分析
アプリケーションの作成と実行
ツールと拡張機能
- Azure Toolkit for IntelliJ を使用して HDInsight クラスター向けの Apache Spark アプリケーションを作成する
- Azure Toolkit for IntelliJ を使用して SSH 経由で Apache Spark アプリケーションをリモートでデバッグする
- Azure Toolkit for Eclipse 上の HDInsight Tools を使用して Apache Spark アプリケーションを作成する
- HDInsight の Apache Spark クラスターで Apache Zeppelin ノートブックを使用する
- HDInsight 用 Apache Spark クラスターの Jupyter Notebook で使用できるカーネル
- Jupyter Notebook で外部のパッケージを使用する
- Jupyter をコンピューターにインストールして HDInsight Spark クラスターに接続する