5
ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014 JAVA TECH 22 COMMUNITY JAVA IN ACTION ABOUT US blog //java architect / ッグ・データ革命が起きてい る今こそ、革命に加わるべき 絶好の時期です。企業が生成す るデータ量は日々増加しており、 新情報を発掘するために再利用 できるデータセットが広く公開さ れています。この種々雑多なデー タセットに、クラウド・コンピュー ティングによる安価なオンデマン ドの処理を適用すれば、新しい 可能性が開かれます。 クラウド内の優れたビッグ・ データ関連テクノロジーを活用す ることで、これまでにないアプリ ケーションが多数登場することは 想像に難くありません。実際、多 くの新興企業が、ほんの数年前 までは資金面の問題で実現でき なかったであろう、魅力的な新 しいアプリケーションを提供して います。Java 開発者は、この革 命に加わるための装備を十分に 持っています。普及しているビッ グ・データ関連ツールの多くが Java ベースであるからです。しか し、非常にスケーラブルで優れた アプリケーションを構築しながら ホスティング費用を抑えるために は、アーキテクチャを再検討し、 利用可能な無数のツールがある 中で方向を見失わないようにする 必要があります。 注:本記事で紹介するすべて のサンプルのソース・コードはこ ちらからダウンロードできます。 Hadoop、その他のツール 大規模データセットの分散処理 用フレームワークである Apache Hadoop は、おそらくこの種の ツールの中でも特に有名です。 強力な MapReduce 実装や、信 頼性の高い分散ファイル・システ ムである Hadoop 分散ファイル・ システム(HDFS)を提供するほ か、Hadoop の最上層にはビッグ・ データ関連ツールのエコシステム が位置付けられます。そのほんの 一部を以下に紹介します。 Apache HBase:大規模なテー ブルに対応した分散データ ベース Apache Hive:HDFS に保管さ れたデータに対して SQL によく 似た非定型の問合せを実行で きるデータウェアハウス・イン フラストラクチャ Apache Pig:MapReduce プロ グラムを作成するための高レ ベル・プラットフォーム Apache Mahout:機械学習 / データ・マイニング用ライブラ Apache Crunch、Cascading: ともに MapReduce パイプライ ンを作成するためのフレーム ワーク 以上のツールは強力ですが、 同時にオーバーヘッドを増大さ せるものでもあり、非常に大きな データセットでなければ効果はあ りません。試しに、本記事のサン プル・コードを非常に小さなデー タセット(データが1行のみのファ イルなど)に対して実行してみて ください。処理時間は予想よりも はるかに長くなるでしょう。 Hadoop および HDFS は、小さ なファイルに対して使用すること が想定されておらず、小さなファ イルを処理する場合には非効率 的です。また、習得に時間がか かることは明白であり、これらの ツールを本番に適用するために はインフラストラクチャ側の対応 も必要です。そのため、これらの ツールへの投資を決断する前に、 データが本当にビッグ・データで あるのかを確認してください。 どの程度の大きさがビッグか では、どうすればビッグ・データ の問題が本当にあるのかを判断 できるでしょうか。これ以上がビッ グ・データであるという決まった サイズはありませんが、データが 十分に大きいと言えるかを判断す るために使用できるいくつかの指 標があります。 1 台のマシンではすべてのデー タを保管できない。つまり、許 容できる時間内にデータを処 理するためには、複数のサー バーによるクラスタ構成が必要 になる。 ギガバイト規模ではなくテラバ イト規模のデータを処理してい る。 処理するデータ量が常に増加し ており、1 年で倍増すると予想 される。 非常に大きなデータではない 場合は、単純な状態を維持するこ とが重要です。従来の Java アプ リケ―ションや、あるいは grepAwk などの単純なツールを使用 Java によるビッグ・データの処理 データに関する知識と Hadoop に関する知識をあわせて、MapReduce ジョブの高速化と効率化を 実現する Fabiane Nardon (@ fabianenardon): TailTarget.com の 主任研究員。同社 ではこれまでにな い新しいデータ・サ イエンス・サービス の設計を実施。 Duke's Choice Award を受賞。 Fernando Babadopulos(@ babadopulos): TailTarget.com の CTO。高パフォーマ ンスのソフトウェア 設計の専門家とし て、ブラジルで人気 の Web サイトを多 数設計。 and Java Big Data

Javaによるビッグ・データの処理 - Oracle...ORACLE.COM/JAVAMAGAZINE ///// JANUARY/FEBRUARY 2014 JAVA TECH 23 COMMUNITY JAVA IN ACTION ABOUT US blog //java architect / することでも、おそらくはデータの処理

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

22

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

ビッグ・データ革命が起きている今こそ、革命に加わるべき

絶好の時期です。企業が生成するデータ量は日々増加しており、新情報を発掘するために再利用できるデータセットが広く公開されています。この種々雑多なデータセットに、クラウド・コンピューティングによる安価なオンデマンドの処理を適用すれば、新しい可能性が開かれます。 クラウド内の優れたビッグ・データ関連テクノロジーを活用することで、これまでにないアプリケーションが多数登場することは想像に難くありません。実際、多くの新興企業が、ほんの数年前までは資金面の問題で実現できなかったであろう、魅力的な新しいアプリケーションを提供しています。Java 開発者は、この革命に加わるための装備を十分に持っています。普及しているビッグ・データ関連ツールの多くがJava ベースであるからです。しかし、非常にスケーラブルで優れたアプリケーションを構築しながらホスティング費用を抑えるためには、アーキテクチャを再検討し、

利用可能な無数のツールがある中で方向を見失わないようにする必要があります。注:本記事で紹介するすべてのサンプルのソース・コードはこちらからダウンロードできます。

Hadoop、その他のツール大規模データセットの分散処理用フレームワークであるApache Hadoop は、おそらくこの種のツールの中でも特に有名です。強力なMapReduce 実装や、信頼性の高い分散ファイル・システムであるHadoop 分散ファイル・システム(HDFS)を提供するほか、Hadoop の最上層にはビッグ・データ関連ツールのエコシステムが位置付けられます。そのほんの一部を以下に紹介します。 ■ Apache HBase:大規模なテーブルに対応した分散データベース

■ Apache Hive:HDFS に保管されたデータに対してSQL によく似た非定型の問合せを実行できるデータウェアハウス・インフラストラクチャ

■ Apache Pig:MapReduceプロ

グラムを作成するための高レベル・プラットフォーム

■ Apache Mahout:機械学習 /データ・マイニング用ライブラリ

■ Apache Crunch、Cascading:ともにMapReduce パイプラインを作成するためのフレームワーク以上のツールは強力ですが、同時にオーバーヘッドを増大させるものでもあり、非常に大きなデータセットでなければ効果はありません。試しに、本記事のサンプル・コードを非常に小さなデータセット(データが 1行のみのファイルなど)に対して実行してみてください。処理時間は予想よりもはるかに長くなるでしょう。Hadoop および HDFS は、小さなファイルに対して使用することが想定されておらず、小さなファイルを処理する場合には非効率的です。また、習得に時間がかかることは明白であり、これらのツールを本番に適用するためにはインフラストラクチャ側の対応も必要です。そのため、これらのツールへの投資を決断する前に、

データが本当にビッグ・データであるのかを確認してください。

どの程度の大きさがビッグかでは、どうすればビッグ・データの問題が本当にあるのかを判断できるでしょうか。これ以上がビッグ・データであるという決まったサイズはありませんが、データが十分に大きいと言えるかを判断するために使用できるいくつかの指標があります。 ■ 1 台のマシンではすべてのデータを保管できない。つまり、許容できる時間内にデータを処理するためには、複数のサーバーによるクラスタ構成が必要になる。

■ ギガバイト規模ではなくテラバイト規模のデータを処理している。

■ 処理するデータ量が常に増加しており、1年で倍増すると予想される。非常に大きなデータではない場合は、単純な状態を維持することが重要です。従来の Javaアプリケ―ションや、あるいは grep、Awk などの単純なツールを使用

Java によるビッグ・データの処理データに関する知識とHadoop に関する知識をあわせて、MapReduceジョブの高速化と効率化を実現する

Fabiane Nardon(@fabianenardon):TailTarget.comの主任研究員。同社ではこれまでにない新しいデータ・サイエンス・サービスの設計を実施。 Duke's Choice Award を受賞。Fernando Babadopulos(@babadopulos):TailTarget.comのCTO。高パフォーマンスのソフトウェア設計の専門家として、ブラジルで人気のWebサイトを多数設計。

and JavaBig Data

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

23

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

することでも、おそらくはデータの処理にかかる時間と費用を節約できます。

Hadoopによるビッグ・データの効率的な処理データセットの分析にHadoopを使用することを決定した場合、将来的にデータが増加した際にパフォーマンス・ボトルネックが発生しないようにすることが望まれます。Hadoopクラスタには、多くの構成上のチューニングを適用できます。また、アプリケーションのデータ処理速度が、求められる水準に達していない場合は、いつでもノードを追加できます。ただし、アプリケーション・コードの実行速度を向上すること以上に、ビッグ・データ・アプリケーションのパフォーマンスを改善するものはありません。ビッグ・データ処理用のアプリケーショ

ンを実装する場合、そのアプリケーション・コードは通常、1つの処理サイクルで数百万回、あるいは数十億回も実行されることになります。たとえば、1行が 500 バイトある10GB のログ・ファイルを処理する必要があるとします。この場合、1行のデータを分析するコードが 2,000 万回実行されることになります。コードの実行時間を1行あたり10マイクロ秒短縮するだけでも、このファイルの処理時間が 3.3 分も削減されます。おそらく、1日に多数の 10GB のファイルを処理する状態が長期間続くと思われます。そのような場合、このわずかな時間短縮が、時間とリソースの大幅な節約につながるのです。 この例から得られる教訓は、1マイクロ秒の積み重ねが重要だということ

です。現在の問題に対して最速の Javaデータ構造を選択すること、可能な限りキャッシュを利用すること、不要なオブジェクトのインスタンス化を行わないこと、効率的な String 操作メソッドを利用すること、そして自分の Javaプログラミング・スキルを駆使して可能な限り速いコードを記述することに取り組んでください。効率的なコードを記述することに加

えて、よくある問題を避けるために、Hadoop の仕組みを知っておくことが重要です。まずは、初心者がよく陥る間違いを紹介します。初心者はWritable オブジェクトを再利用しないのです。 リスト1のコードは非常に単純なMapReduce のサンプルです。このコードは、Webアクセスに関するログ・ファイルのデータ行を受け取り、特定のインターネット・ドメインへのアクセス回数をカウントします。このサンプルでは、キーと値のペアをマッパーの出力に書き込もうとするたびに、新しい org.apache.hadoop.io.Text オブジェクトを生成しています。その結果、持続時間の短い多数の不要なオブジェクトが割り当てられます。周知のとおり、Javaでのオブジェクトの割当ては高コストの操作です。代わりに、このサンプルではWritable オブジェクトを安全に再利用できます(リスト2)。再利用の結果、より速く効率的なコードになります。注:リスト1、リスト2を含む本記事のすべてのリストはコードの抜粋です。リストの全コードはソース・コード・ファイルから取得してください。MapReduceジョブのパフォーマンス

を改善するために簡単に適用できる別すべてのリストのテキストをダウンロード

public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {

private static final IntWritable one = new IntWritable(1);

public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { try { String line = value.toString(); String[] parts = line.split(" " ); String domain = new URL(parts[2]).getHost(); context.write(new Text(domain), one); } catch (MalformedURLException e) { } } }

public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {

public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable value : values) { count = count + value.get(); } context.write(key, new IntWritable(count)); } }

リスト1 リスト2

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

24

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

のテクニックは、Combiner の利用です。このテクニックを利用するために、Hadoop MapReduce の仕組みを理解しておくことにしましょう。ジョブを実行すると、Hadoop は入力データを、より小さなチャンク(データのまとまり)に分割して、各チャンクをそれぞれ別のHadoopノードに送信して処理させます。 各チャンクを処理するのはマッパー関数であり、この関数が出力を生成します。マッパーが生成した出力はバッファに保管されます。このバッファがしきい値に達したときには、新しいスピル・ファイルがディスクに保存されます。マップ・タスクが担当のデータをすべて処理したら、それまでのスピル・ファイルがマージされ、ソートされた後に 1つの出力ファイルにまとめられます。次に、各マップの出力ファイルがネットワーク経由でリデューサに送信されます。リデューサは、複数のマッパーによって生成されたデータを処理して、最終的な結果を出力します。 分散システムでは通常、ネットワーク経由で送受信されるデータ量がボトルネックの原因となります。本記事のサンプルでは、マッパーはログの 1行につき1つのペアを書き込みます(例:<ドメイン名 , 1>)。つまり、場合によっては数百万ものペアをディスクに書き込んで、リデューサに送信する必要があります。その後、リデューサが受信したペアを組み合わせて、特定ドメインへのアクセス回数をカウントします。 ここで、マッパー・ノード内で小さな

リデューサを実行してペアを組み合わせてから、ネットワーク経由でデータを送

信できればどうなるでしょうか。この役割を担うのがコンバイナです。コンバイナをMapReduceジョブに関連付けた場合、マップ処理フェーズでデータを集約してから、より小さなデータセットをリデューサに送信することができます。コンバイナ自身は処理時間のほとんどで、リデューサの役割を果たすことができます(リスト3)。試しに、コンバイナがある場合とない場合のそれぞれで、このサンプルを大きなログ・ファイルに対して実行してみてください。このそれぞれのジョブ統計情報を比較すれば、明確な違いが現れるでしょう。 ここまでのHadoop MapReduce の仕組みへの理解を基礎として、いくつかのトリックやデータに関する知識を利用することで、コードをさらに最適化できます。たとえば、サンプルのMapReduceジョブではドメインをカウントしていますが、ドメインの種類はそれほど多くないことがわかっています。おそらく高々数百個であり、このドメインのリストをメモリ内に格納しても問題ありません。したがって、コンバイナの代わりにメモリ内のマップを利用して、マッパー関数内でドメイン数をカウントすることにします。最後に、マッパーでドメイン名とその個数のみを出力するようにして、その後リデューサで最終的な合計を出すことができます。マッパー・タスクの終了時には cleanupメソッドが呼び出されます。このメソッドを利用して、<ドメイン名, 個数>のペアを出力できます(リスト4)。このサンプルを実行して、統計情報を前述の実装と比較すると、ディスクに保存されるデータ量が減少すること、およびジョブ実行速度が向上するこ

とがわかります。 このように、データに関する知識

とHadoop の仕組みに関する知識をあわせることで、より速く効率的なMapReduceジョブを作成できます。このことで、将来の費用の多くを節約できます。

MapReduce パイプライン前項までに確認したサンプルは、1つのMapReduceジョブが入力を受け取り出力を生成するという非常に単純なものでした。しかし、実際の場面では、ビッグ・データに関する課題はそれほど単純なものではありません。多くの場合、必要な結果にたどり着くまでに、多種多様な

job.setMapperClass(Mapp.class);job.setCombinerClass(Reduce.class);job.setReducerClass(Reduce.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);job.submit();

リスト3 リスト4

すべてのリストのテキストをダウンロード

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

25

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

MapReduceジョブを連結する必要があります。ある1つのジョブの出力が別のジョブの入力となり、その関係が続いていくのです。この処理は、MapReduceパイプラインと呼ばれています。 しかし、効率的なパイプラインを実装するためにはある程度の作業が求められます。中間的なデータの処理、各ジョブの適切な粒度の把握などが必要です。幸いにも、MapReduce パイプラインを作成するために使用できるツールがあります。例をいくつか紹介しましょう。

■ Pig:異なるMapReduceタスクを連結できるスクリプト言語

■ Cascading:データ・パイプラインを作成するための Javaフレームワーク

■ Crunch:最適化機能や便利な抽象表現を提供することで、MapReduce パイプラインの作成を容易にする Javaライブラリこれ以降、パイプラインの利用方法について理解を深めるため、Crunch の仕組みについて詳しく説明し、いくつかの例を見ていきます。Crunchでは、分散データセットを表す 3つのインタフェースを利用します。PCollection、PTable、PGroupedTableです。これらのインタフェースには、parallelDoというメソッドがあります。parallelDoを呼び出すと、このメソッドは並行処理によって、コレクション内の各要素に特定の関数を適用し、その結果として別のコレクション(PCollection、PTable、または PGroupedTable)を返します。この後、ある関数のコレクション出力を次の関数の入力として使用するという方法で、異なる複数の関数を連結できます。Crunch がこの中間的な

データの管理や、最適化されたパイプライン実行計画の作成を担当します。 この Crunch による最適化フェーズは重要です。Crunch は、実行するMapReduceジョブ数を最小限に抑えようとするためです。したがって、効果があると見なした場合は、異なる関数(通常ならば別のMapReduceジョブとして実装される関数)を、より効率的な 1つのジョブに統合します。この最適化戦略の理論的根拠となるのは、I/O のコストが高いため、ディスクから一度データを読み取った後は、そのデータを使用して可能な限り多くの処理を実行すべきだという考え方です。また、MapReduceジョブには起動時のオーバーヘッドがあるため、より少ないジョブでより多くの処理を実行できれば、効率が向上します。Crunch パイプラインを構成する関数はDoFnクラスのサブクラスです。これらの関数のインスタンスはシリアライズ可能とする必要があります。Crunch によってこれらの関数がシリアライズされ、タスクを実行するすべてのノードに配信されるためです。それでは、ドメインへのアクセス回数をカウントするサンプルを、Crunchを使用して実装する方法について確認しましょう。リスト5は、ログ・ファイルの処理に使用するDoFn 関数です。また、リスト6は、パイプラインの定義および実行の方法を示しています。パイプラインは、pipeline.done() メソッドが呼び出されたときにのみ、実行されます。 リスト6のコードより、一般的なビッグ・データ処理のタスクを実装するためのメソッドが Crunchで標準的に

提供されていることがわかります。たとえば、収集した値の合計を出すReducerコードを記述する代わりに、Aggregators.<String>SUM_INTS() メソッドを使用して同じことを行っています。 MapReduce パイプラインは、ビッグ・

データを処理するための強力なメカニ

ズムであり、アプリケーションが複雑化するほど利用の必要性が高まります。

クラウドでのビッグ・データの処理ビッグ・データ対応アプリケーションをクラウドにデプロイすることには多くの利点があります。たとえば、データの増加にあわせてオンデマンドでマシンを追

public class Listing5 extends DoFn<String, Pair<String, Integer>> {

public void process(String line, Emitter<Pair<String, Integer>> emitter) {

String[] parts = line.split(" " ); try { URL url = new URL(parts[2]); emitter.emit(Pair.of(url.getHost(), 1)); } catch(MalformedURLException e) {} } }

リスト5 リスト6

すべてのリストのテキストをダウンロード

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

26

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

加で導入できます。また、需要のピークに対して事前に準備できます。しかし、法外なスケーリング費用を負担せずにクラウド・サービスを利用するためには、クラウドの特殊性を考慮してアプリケーションを設計する必要があります。まず重要になるのが、コードが効率的であるほど処理時間が短縮されるため、より少ないホスティング費用で済むということです。クラスタに新しいノードを追加する必要があると、そのたびに追加コストが発生します。そのため、コードを可能な限り効率的にすることが良い習慣と言えます。クラウドにビッグ・データ対応アプリケーションをデプロイする際には、シェアード・ナッシング・アーキテクチャの利用を検討することが重要です。シェアード・ナッシング・アーキテクチャとは、基本的に、各マシンがネットワークだけで接続され、ディスクやメモリを共有しないことを表します。そのため、この種のアーキテクチャのスケーラビリティは非常に優れ、ディスク・アクセスの競合や別のプロセスによるボトルネックが発生することはありません。各マシンが担当のすべての処理を管理します。マシンは相互に独立し、自己完結しています。Hadoop のフォルト・トレランス関連の機能により、さらに安価なクラウド・マシン・サービスが検討対象となる可能性があります。たとえば、Amazonスポット・インスタンスというサービスがあります。このサービスでは、インスタンスの価格が入札額よりも高い場合はマシンが利用できなくなります。この種のマシンを利用して、たとえばTaskTracker を実行しているとします。

その場合、Hadoop によって、そのマシンがいつ消失しても対応できる余裕が生まれます。Hadoop は、ジョブを実行していた 1つ以上のノードが消失したことを検出するとすぐに、別のノードでそのジョブを再実行するからです。 実際に、多くのビッグ・データ対応ア

プリケーションでは、データのごく一部が消失することも許容されます。統計的処理を実行中に、小さなデータセットが未処理のまま処理が終了する状況がよく発生しますが、これが最終的な結果に影響を及ぼす可能性はほとんどありません。そのため、アーキテクチャの構築時に、この点を有利に活用できます。アプリケーションをホストするクラウドで、Hadoop に対応するサービスを利用できます。Amazon EMR はそのようなサービスの好例です。Hadoop ホスティング・サービスを利用することで、独自のHadoopクラスタの設置や維持にかかる負担が軽減されます。一方で、より高い柔軟性を要する場合には、独自のHadoopソリューションをクラウド内にインストールすることもできます。クラウドでのHadoop の利用には、ジョブの動作状況を監視して、ジョブの実行中であっても、ノードの追加や削除を必要に応じて自動的に行えるという別の利点もあります。Hadoop のフォルト・トレランス機能によって、システム全体の機能を確実に維持できます。ここで使うトリックは、マスター・ノードに対して、許可するスレーブの IPアドレスの範囲を事前に設定しておくことです。この設定には、Hadoopインストール・ディレクトリ内の conf/slavesファイルを使用します。この設定を行っておくことで、事

前に設定された IPアドレスのいずれかを使用して新しいスレーブ・ノードを起動できます。そのノードは自動的にクラスタに登録されます。

まとめ本記事では、ビッグ・データ対応アプリケーションによって近い将来に実現できることについて簡単に説明しました。Hadoop、HBase、Hive、Cascading、Crunch などのツールによって、Java がビッグ・データ革命の原動力となります。 データセットのサイズが問題になる場合には、アーキテクチャを再検討して、コードを効率化する解決策を見出す必要があります。幸いにも、Java 開発者はこの種の課題に喜んで挑むことでしょう。</article>

LEARN MORE• Apache Hadoop• Introduction to Data Science

and JavaBig Data

MORE ON TOPIC:

My local and global JUGs are great places to networkboth for knowledge and work. My global JUG introduces me to Java developers all over the world.Régina ten Bruggencate

JDuchess

FIND YOURJUG HERE

LEARN MORE