Monthly Archives: 12月 2017

2017-12-11

Java 9 ModularityでJigsawを学ぶ

GMOアドマーケティングのT.Nです。

今年の9月にJava9が正式にリリースされました。
弊社ではまだJava8を使用していますが、
Java9へのアップグレードに備え、勉強しているところです。

Java9の変更点はいくつかありますが、
最大の変更点とも言えるJigsawについて、以下の本を読んで学んでいます。

本を読んで学んだことなどを、数回に分けてブログに書く予定です。
今回は、Jigsawの概要について書きます。

Jigsawとは

Project Jigsawという、Javaのプラットフォームをモジュールに分割するプロジェクトのことです。
Java9でJDKがモジュールに分割され、
モジュールを使ったアプリケーションの設計が可能になりました。

モジュールとは

他のモジュールとの依存関係や公開範囲が明確な、
適切にカプセル化されたソースコードの集まりです。

モジュール化のメリット

  • 外部に公開するもの、公開しないものを明確にできる。
  • クラス同士が予期せぬ依存関係を持つことを防ぐことができる。
  • 実行時にクラスパスが存在しないことで起きるエラーを防ぐことができる。
  • 攻撃にさらされる部分を減らすことができる。(リフレクションによるアクセスも制限できる。)
  • 必要なモジュールが明確なので、JVM起動時に必要とするモジュールの最適化ができる。

モジュールの定義

公開するパッケージや依存するモジュールは、module-info.javaに記述します。
module-info.javaは、モジュールごとに定義します。

以下はJava9で追加されたjshellのmodule-info.javaです。
(jshellというのは、コマンドラインでJavaの処理を実行できる機能です。
コマンドラインでjshellと入力することで起動できます。)

module-info.javaには以下のように依存関係が定義されています。

module-info.javaの記述方法

requires

依存するモジュールを定義できます。

exports

公開するパッケージを定義できます。
(privateなフィールド、メソッドなどのリフレクションは許可しません。)

opens

実行時にリフレクションによる参照を許可するパッケージを定義できます。
opensに指定したパッケージは、コンパイル時には参照することができません。

provides, uses

ServiceLoaderを用いた依存関係を定義できます。
モジュールを利用する側では、
供給側のインターフェースの情報のみを持っていれば、実装クラスの処理を実行することができます。
利用する側には実装クラスの情報がないので、
供給側では実装クラスを柔軟に変更することが可能になります。

Annotations

モジュールには、@Deprecatedなどのアノテーションをつけることもできます。

ClasspathとModule Path

Java9以前では、classpathを参照して、JVMがクラスをロードしていましたが、
Java9からは、module pathが使用されるようになりました。
Java9でもclasspathは存在しますが、モジュールからはclasspathを参照することができません。
モジュール化されていないクラスからは、
classpathを通して今までと同じようにクラスを参照できます。

Automatic ModulesとUnnamed Module

モジュールからは、classpathを参照することができないので、
モジュールからモジュール化されていない既存のJARファイルなどを参照する場合は、
Automatic Modulesという仕組みを使用する必要があります。
コンパイル時にオプションで指定することで、
モジュール化されていないJARファイルなどをモジュールとして扱うことができ、
モジュールから参照することができます。

Automatic Modulesは、モジュールであるため、classpathを参照することができませんが、
classpath上のクラスは、Unnamed Moduleとして扱われ、module pathからも参照できるので、
モジュール化されていないクラスも参照することができます。

Moduleクラスについて

Java9でjava.langにModuleというクラスが追加されました。
Moduleクラスには、addExports、addOpens、addReadsのようなメソッドがあり、
実行時にモジュールを操作して、依存関係を変更することができます。

これらのメソッドを使用して、
本来は公開されるべきではないモジュールに対する参照を得ることなどができそうですが、
実際にはできないようになっています。

これらのメソッドには、
@CallerSensitiveというアノテーションが付与されており、
メソッド内で呼び出し元が適切であるかのチェックが行われています。
変更対象のモジュール内のクラスから実行された場合のみ、変更を行うことができます。

最後に

今回はJava 9 Modularityを読んで学んだことをまとめました。
途中までしか読んでいないので、簡単な内容のみになりましたが、
今後読み進めていく中で学んだことを、弊社でのモジュール化対応に活かし、
次回はそちらの内容についても書けたら良いと考えています。

2017-12-07

SparkのWebUIでモニタリング

皆さん

こんにちは、GMOアドマーケティングのS.Rです。

SparkのProgramを開発する上で、Performanceの改良やInstanceの設定のTuningはかなり重要です。

これらのチューニングはSparkのWebUIを使えばかなり簡単に制御できます。

そこで、今回はSparkのWebUIを皆さんへ紹介致します。

※この記事を理解するには、Spark、Hadoop、Linuxのshellコマンドの基本知識が必要です。

1 Sparkとは?

Sparkの概要は以下のWikipediaの記事を参考にして下さい。

Apache Sparkはオープンソースのクラスタコンピューティングフレームワークである。カリフォルニア大学バークレー校のAMPLabで開発されたコードが、管理元のApacheソフトウェア財団に寄贈された。Sparkのインタフェースを使うと、暗黙のデータ並列性と耐故障性を備えたクラスタ全体をプログラミングできる(Apache Spark、2014年5月30日、ウィキペディア日本語版、https://ja.wikipedia.org/wiki/Apache_Spark)

 

2 Sparkのインストール:

  1. Sparkの公式ダウンロードサイトで任意のバージョンをダウンロードします。
    今回は例として最新のSpark2.2.0、Pre-bulit版をダウンロードしました。
  2. Sparkのモードを選びます。Sparkには3つの起動モードがあります。
    1. WorkerNodeがない状態で起動します(Standalone Deploy Mode)。
      今回は例としてこのモードで説明します。
    2. Yarnで起動します。YARN(Yet Another Resource Negotiator )は、Hadoopクラスタのリソース管理、ジョブスケジューリングを担当するモジュールです(YARN、2014年5月30日、ウィキペディア日本語版、https://ja.wikipedia.org/wiki/Apache_Hadoop#Yet_Another_Resource_Negotiator_.28YARN.29)
    3. Mesosで起動します。Mesosはカリフォルニア大学バークレー校の研究機関AMPLabのプロジェクトによって開発されたクラスタのリソース管理のモジュールです(Mesos, 30 October 2017, Wikipedia, https://en.wikipedia.org/wiki/Apache_Mesos)
  3. SparkのShellを起動します。Sparkは四種類のShell(Scala, Java, Python, R )を実行できます。
    今回は例としてScalaのShellを起動します。起動するコメントは下記です:

SparkのShellを起動すると下記の画面を確認することが出来ます:

図1:Sparkの起動画面

3 WebUIへアクセス:

今回は二つモード(StandaloneとDataproc)でSparkのWebUIをアクセスする方法を紹介します。

  1. Standalone:
    例としてStandaloneモードでSparkの公式サイトに記載されているLinearRegressionのSampleCodeを実行します。SampleCodeやデータはSpark公式のGithub(Source CodeData)からDownloadしてください。今回はWebUIを確認しやすくするために、ソースコードの最後に下記の”halting”のコードを追加します。

    操作の手順は以下の通りです:

    1. Sparkをインストールします。
    2. LinearRegressionのSampleCodeをsubmitします。
    3. SampleCodeが動作しているときにBrowserへMaster NodeのIPやPortを入力してWebUIへアクセスします(Standaloneの場合はhttp://127.0.0.1:4040/jobs/を入力します)。
      WebUIのアクセスに成功すると図2のような画面を確認することが出来ます。
      WebUIの各部については第3章で詳しく説明します。

      図2:StandaloneのWebUI

     

  2. Google Cloud Dataproc:
    今回はGoogle社により提供されている Spark / Hadoop のマネージドサービスであるDataprocのWebUIにアクセスする方法を紹介します。

    1. Google SDKを設定します。設定方法はGoogle Cloudの公式サイトを参考にしてください。
    2. DataprocのInstanceを立ち上げます。使うCommandは下記の通りです。
    3. Step2で作ったDataprocのInstanceのMasterNodeと連携するSSH tunnelを作ります。
      使うCommandは下記の通りです。

      Commandの詳細の説明はGoogle Cloudの公式サイトを参考にしてください。
    4.  Sparkのapplicationをsubmitします。今回は例としてLinearRegressionのSampleCodeをsubmitします。使うCommandは下記の通りです。
    5. Terminal(Mac, Linux)やCommand Line(Window)でChromeを起動します。
      使うCommandは下記の通りです。

      各OSでのChromeのDefault Pathは表1の通りです。

      表1:ChromeのDefault  Path

      Operating System Default  Path of Google Chrome
      Mac OS X /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
      Linux /usr/bin/google-chrome
      Windows C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
    6. 起動したChromeでhttp://[MasterNodeのInstance名]:8088へアクセスします。
      アクセスすると、DataprocのWebUIを確認することができます(図3)。
      DataprocのWebUIの項目「TrackingUI」から「History」をクリックすることで、図3の様なSparkのWebUIに遷移できます。

      図3:DataprocのWebUI

4 WebUIの説明
SparkのWebUI には6つのTabがあります。

  1. Jobs:
    Tab JobでJobのListが確認できます(図4)。
    JobのDescriptionをクリックすることでさらに詳細のJobを確認することができます。
    今回は例としてJob 5(count at LinearRegression.scala:696)をクリックしてみます。
    図4はJob 5の詳細画面です。

    図4:Job の詳細

    Jobの詳細画面にはstageが並んでいます。気になるstageのDescription項目をクリックするとさらに詳細な情報を確認することができます(図5)。

    図5:Stage の詳細

  2. Stages
    Tab Stagesで全てのStagesのListが確認できます。気になるStagesをクリックすることで、そのStageの詳細を確認することができます(図6)。

    図6:Tab Stages

  3. Storage
    Storageで当InstanceのStorageの状況を確認できます。今回のSample CodeではRDDの詳細はないのでStorgeの詳細画面はBlankになりました(図7)。

    図7:Stage の詳細

  4. Executors
    Executorsで当Executorsの詳細状況を確認できます(図8)。

    図8:Executors の詳細

  5. SQL
    SQLでSubmitしたCodeで実行されたSQLの詳細状況を確認できます(図9)。
    気になるStepのDescriptionをクリックして当Stepの詳細情報を確認できます。
    今回は例としてID: 1(first at LinearRegression.scala:198)をクリックしてみました。
    図10はクリック後の遷移画面です。

    図9:SQLの詳細

     

    図10:SQLの詳細状況

5 まとめ

今回はSparkのWebUIについて紹介しました。いかがだったでしょうか。
私は以前、大規模なデータのSparkのProgramを開発していたときに一番悩んだのは、メモリ不足によるエラーを解決することでした。
現在はSparkのWebUI を利用することでProgramの各部分の処理時間、メモリの使用量などの状況を全て確認できるようになりました。
これにより、Programのエラー解決がスムーズになるので、皆さん興味があればSparkのProgramを開発する時にぜひ試してください。