データサイエンティスト向けの勉強会やセミナーに参加したことはあるでしょうか。

Apache Spark・Hadoopなどの単語が出てきたものの、なんとなく分散処理をする何かということしか分からない方もいるでしょう。

本記事の前半はApache Sparkを理解するための基本的な知識を整理するのが目的です。ここでApache Hadoopとの違いにも触れます。

後半ではDocker環境にて実際にApache Sparkを動かし、具体的な使い方などについて解説していきましょう。

簡略化のため本文中ではApache SparkをSpark、Apache HadoopをHadoopと記述します。あらかじめご了承下さい。


分散処理フレームワークとは

分散処理フレームワークといえばSparkとHadoopです。

分散処理では対象となるデータや処理を分割し、複数のコンピューターで同時に実行することで処理速度や耐障害性を高めます。

対になる用語は集中処理です。セキュリティ管理が行いやすい反面、ホストコンピューターへの負荷や障害発生に問題がありました。

フレームワークは骨組みや構造を意味する単語です。

つまり分散処理フレームワークは分散処理を行うための骨組みを提供するものといえるでしょう。

フレームワークを利用すればより効率的に分散処理システムの構築が行えるようになります。


Apache Hadoopとは

Sparkについて解説するためには、まずHadoopについて説明しなければなりません。

何故ならHadoopが苦手とする処理を補うために生まれたのがSparkだからです。両システムは現在では共存関係にあります。

Hadoopは2006年にDoug Cutting氏が開発したフレームワークです。

由来はCutting氏の娘が、お気に入りの象のぬいぐるみに付けた名前といわれています。

Hadoopは膨大なデータを分散処理するための機能を提供するオープンソースのフレームワークです。

ログ解析・データマイニングなどの様々な用途に利用でき、FacebookやVisaをはじめとする多くの企業での導入事例があります。


Apache Hadoopの特徴

Hadoopはいくつかの異なる機能の集合体です。

Sparkを理解するためにも各機能が何をしているのか、しっかり要点を押さえていきましょう。


HDFS

HDFS(Hadoop Distributed File System・Hadoop分散ファイルシステム)はHadoop独自のファイル管理システムです。

大規模データを複数のディスクに分割した状態で保持しておくことができます。

読み書きを並列実行することで、ディスクI/Oによる処理時間の増加を抑える仕組みです。

ちなみにHDFSについて調べているとApache HBase(アパッチ エイチベース)という用語も出てきます。

これはHDFS上に構築された列指向型の分散データベースで、HDFSとは利用用途ごとに区別して使い分けなければなりません。


YARN

YARNはクラスタのリソース管理を行うミドルウェアです。綴りはYet Another Resource Negotiatorになります。

HDFS上で後述するMapReduceフレームワークもYARNによる管理です。

YARNはMapReduceやSparkなどのアプリケーションの実行を依頼されると、必要なリソースの割当を行い全体のリソース量を制御します。


MapReduceフレームワーク

MapReduceフレームワークは並列分散処理を実行するミドルウェアです。

MapReduceは元々Googleによって発表された論文で述べられた分散処理の方法でした。

この考え方を元に作成されたのがMapReduceフレームワークです。

Map処理では入力されたデータの各行データから、key-valueの組み合わせを作成します。

Reduce処理はMap処理で作成された組み合わせを元に、更に別の組み合わせを作成していくものです。

具体的には同じkeyのデータを集計・統合します。


SparkとHadoopの関係

HadoopはフレームワークでありHDFS・YARN・MapReduceフレームワークの3つの機能によって構築されていることを説明しました。

SparkフレームワークはこのうちMapReduceフレームワークと同じポジションに位置する分散処理フレームワークです。

しかし技術記事ではSparkフレームワークがポストHadoopとして紹介されたり、同レベルで扱われることもあります。

またSparkエコシステム全体を指してSparkと表現する場合もあり、各々の記事で何をSparkとしているか判断しないといけません。

SparkフレームワークもMapReduceの考え方を元に作られたため、互換性や耐障害性にMapReduceフレームワークと類似する点が見られます。

一方で得意とする処理や利用シーンは異なっており、両フレームワークは互いに共存が可能なものです。


Apache Sparkとは

Sparkフレームワークは2009年から開発が開始され、2014年にバージョン1.0がリリースされました。

機械学習・リアルタイム分析などの用途に使用でき、UberやYahoo!などの有名な企業で導入されています。


Apache Sparkの特徴

Sparkの特徴をSparkエコシステムに沿って見ていきましょう。

Sparkエコシステムは各種コンポーネントから構成されており、これらが相互作用することで機能を果たします。


Spark Core

Spark Coreは並列分散処理の基盤です。

RDD(Resilient Distributed Dataset)という弾力性のあるデータ構造や、DataFrameというテーブル状のデータ構造を利用します。

Hadoopと異なるのはこれらがHDDやSSDではなく、全てをメモリ上で処理するインメモリ計算を可能にする点です。

Spark全体のリソースやネットワークの管理を行います。


Spark SQL

SparkでのSQL使用に必要なコンポーネントです。

開発者はSpark SQLを使用してRDDやDataFrameなどのデータ構造にアクセスします。

Spark SQLの中核となる機能はCatalyst(カタリスト)というオプティマイザーです。

CatalystはScalaの関数型プログラミング構造に基づいて設計されています。

ルールベースとコストベースの最適化を行うことができる他、開発者がオプティマイザー自体を拡張することも可能です。


Spark Streaming

Sparkでストリームデータを扱うためのコンポーネントをSpark Streamingと呼びます。

Streamingにはバッチ処理やストリーミングなどの便利なAPIが多数用意されていますので確認してみて下さい。

Spark MLlibとの連携やリアルタイムデータストリーミングなどを可能にします。


Spark MLlib

Spark MLlibは機械学習処理に必要な各種アルゴリズムを提供するコンポーネントです。

MLlibはScala・Python・Javaなどから呼び出し可能な機械学習ライブラリで、パイプラインの構築や開発をサポートします。


GraphX

大規模なグラフ構造データを処理するためのコンポーネントです。

GraphXもSpark上のAPIの1つでグラフ分析を行う際に使用します。

グラフ分析は経路探索・リレーションなどの分野に有効です。


HadoopとSparkの違い

HadoopとSparkの類似点・相違点について見ていきましょう。


安定性・耐障害性

HadoopもSparkも共に安定性・耐障害性が高くなっています。

Hadoopは複数サーバーで処理しているため、いずれか1つのサーバーがダウンしても処理を続行可能です。

またSparkで万一RDDのデータが失われた場合は、再計算によりRDDのデータが復旧されるようになっっています。


処理速度と即時性

リアルタイムに高速処理を行わなければならない場合はSparkに分があるでしょう。

HadoopはHDFSを採用しているためどうしてもディスクI/Oに左右されます。これが原因でリアルタイム性のある処理には向きません。

Sparkは全てのデータをメモリ上に保持して処理を行うので、MapReduceフレームワークのみの場合と比べ10倍から100倍ほど高速になります。


データ容量

データ容量がメモリ上に乗り切らないほど多い場合はHadoopを採用する必要があるでしょう。

大容量データに対するバッチ処理などに向いています。


Apache Spark環境構築

環境構築手順や構築に必要なDocker関連ファイルの中身を記載すると大変な量になってしまうため、ここでは手段のみの説明です。


Bitnamiからdocker-compose.ymlを取得

BitnamiというとWordPress・Redmineなどの環境が簡単に構築できることで有名でしょうか。

BitnamiにはSparkのDocker環境も用意されており、これを利用することで簡単にSpark環境をローカルに構築できるでしょう。

指示に従いdocker-compose.ymlをダウンロードした後、portsに4040ポートを追加しておいて下さい。


Dockerコンテナを起動

docker-compose upコマンドにてコンテナを起動します。

  1. 1. $ curl -LO https://raw.githubusercontent.com/bitnami/bitnami-docker-spark/master/docker-compose.yml
  2. 2. $ docker-compose up

以下のURLにアクセスすると「Spark Master at spark://(ランダムな英数字):7077」というタイトルの画面が表示されている筈です。

また以下のURLにアクセスすると、ジョブの一覧が表示されます。


Apache Sparkの使い方

起動はできたものの何をどうしたら良いか分かりません。

使い方を確認していきましょう。


spark-shellを起動する

spark-shellはSparkをCLI上から実行するツールです。

以下のコマンドを実行し、しばらく待ちましょう。

  1. 1. $ docker-compose exec spark spark-shell –master spark://spark:7077
  2. 2. $ (中略)
  3. 3. scala>

コンソール上に「Welcome to Spark」と表示されます。

ここで先程のブラウザ画面にアクセスしてみましょう。「Running Applications」にSpark shellが追加されています。

ちなみにこの画面から抜けるためには「:q」を入力して下さい。


コマンドを実行する

scコマンドはSparkContextの表示です。

  1. 1. scala> sc
  2. 2. res0: org.apache.spark.SparkContext = org.apache.spark.SparkContext@4088c5e6

SparkContextはSpark操作の開始地点のようなものと考えておいて下さい。

次は以下のコマンドを実行してみましょう。toDSはDatasetを作成する関数です。

  1. 1. scala> val ds = Range(0, 10, 2).toDS()
  2. 2. scala> ds.map(_ * 10).show()

ジョブの一覧で実行結果の詳細を確認できます。各処理にかかる時間やメモリ使用量などが確認可能です。

最後にsc.textFile関数でファイルの内容を読み取ってみます

  1. 1. scala> val textFile = sc.textFile(“README.md”)
  2. 2. scala> textFile.count()


おわりに

Sparkの使い方について雰囲気だけでも掴んで頂けたでしょうか。

現在Apache Sparkの案件数は少なめですが増加傾向にあります。

ユースケースを考慮すれば今後将来性のある技術といえるでしょう。