Azure SDK 2.5

マイクロソフト開発者向けの Hadoop サポート

Omid Afnan

2013 年、マイクロソフトは独自のビッグ データ クラウド サービスである HDInsight のリリースを発表しました。このサービスによって、Microsoft Azure 上で Hadoop クラスター、HBase クラスター、さらには Storm クラスターまでも作成できるようになります。Azure 管理ポータルを使用すれば手順は簡単で、Hadoop クラスターを作成して、Azure ストレージに関連付け、必要なコア数を選択するだけです。ボタンをクリックするだけで、必要な計算リソースと、クラウドで稼働している完全な Apache Hadoop ディストリビューションにより、数分以内にクラスターがプロビジョニングされます。実に簡単です。ハードウェアを調達する必要はありません。Hadoop スタックの並べ替えも、Hadoop のインストール方法の学習も必要ありません。これだけで、ビッグ データに対するクエリを実行する準備が整います。

「わかったけど、どうすればいいの」というのが率直な感想でしょう。ビッグ データを扱うことを考える一般的なケースは数多くあります。モノのインターネット (IoT) のテレメトリ分析、ソーシャル メディアの感情分析、ユーザーの嗜好分析といった特定のケースを思い浮かべる方もいるでしょう。当社のお客様の場合は、Web サービスやアプリケーションのログを分析することに関心を持つ方が多いようです。そこで今回は、HDInsight を使用してこのシナリオを自力で実現する方法と、新しくリリースされた Microsoft Azure HDInsight Tools for Visual Studio を使用して開発エクスペリエンスをシンプルにする方法を紹介します。

ログ分析のシナリオ

多くのアプリケーションやサービスは、使用状況の追跡、障害の把握、または実行環境の管理を目的として、ひと続きの長いデータを生成します。エラー ログ、ソフトウェア品質管理 (SQM) の出力、クリックストリームの計測、Web サーバー ログなどのデータ ストリームは、毎週ギガバイト単位やテラバイト単位のペースで蓄積されていきます。アプリケーションに障害が発生した場合やサービスが停止した場合のデバッグは例外として、これらのログは、サイズや、きちんと構造されていないというコンテンツの性質が原因で、手付かずで放置されているのがほとんどです。

しかし、この問題に対処し、品質に関する問題をすばやく解決したり、顧客の使用状況を詳しく把握することで、最終的には顧客との密な関係を築き、顧客満足度を向上することを目指す組織もたくさんあります。このような組織に共通する基本的な事例は、Web サーバーのログを分析して、次の 2 種類の情報を引き出すことです。

  • Web サイトで特定のエラーが発生する頻度
  • Web サイトを出入りするトラフィックのパターン

このようなログ データを解析および集計するには、高度な並列処理が必要で、レコードのサブセットを個別のサーバーで解析、転送、集約するのが理想です。その後、各サーバーの部分的な結果を結合して、最終集計データを作成します。まさにこれを行うのが Hadoop の MapReduce エンジンです。Hive クエリ言語 (HiveQL) は、SQL に似たクエリ構文で、目的とする集計を表現することができます。使用率が高まりデータ量が増大すると、このアプローチも効果的に拡張され、処理時間全体が制御されます。

Hadoop MapReduce に対するプログラミングは、HiveQL のような高水準言語を用いると劇的に簡単になります。Visual Studio の HDInsight ツールにより、あらゆる開発者が使い慣れた標準フレームワークでこの種のコードを管理できるようになります。また、Hadoop クラスターとデータ成果物に関連する情報もツールによってわかりやすく表示されます。ここからは、簡単なログ分析の事例を取り上げ、HiveQL 言語と HDInsight ツールを使用してソリューションをすばやく稼働させる方法を示します。

セットアップする

まず、クエリを実行するための HDInsight クラスターを作成します。クラスターはクエリの実行時のみ必要で、使用していないときは削除してもかまいません。ただし、実行したままにしておくこともできます (料金が継続的に発生します)。今回は永続的なデータを Azure ストレージに保存することにします。このストレージは別途作成し、時間が経つにつれて多くの異なるクラスターが使用するようになります。これを Azure 管理ポータルで実行するようすを図 1 に示します。

Microsoft Azure 管理ポータルでの Hadoop クラスターの作成
図 1 Microsoft Azure 管理ポータルでの Hadoop クラスターの作成

作成したクラスターは管理ポータルに表示されます。管理ポータルでは、必要に応じてクラスターを表示したり削除することができます。管理ポータルから表示できるクエリ コンソールを使用すると、ブラウザーから簡単なクエリを直接送信することができます。

この時点では、HDInsight Tools for Visual Studio を含む Azure SDK 2.5 をインストール済みの状態にしておきます。Visual Studio 2013 で [ファイル]、[新規作成]、[プロジェクト] を順にクリックすると、HDInsight プロジェクト用の新しいカテゴリが表示されます。他の Visual Studio プロジェクトと同様、"Hive Application" というプロジェクトの種類によって、作業するアプリケーションを特定の言語 (今回の場合は HiveQL) で指定するのに必要な関連ファイルを簡単に作成できるようになります。また、本稿付属のコード サンプルには Hive Sample プロジェクトを含めています。Hive プロジェクトを使用すると、関連するクエリを簡単にグループ化、保存、変更、共有できるようになります。

データを取得する

ここで Visual Studio のサーバー エクスプローラーを開き、サブスクリプション内の Azure サービスとオブジェクトに移動します。[Azure] の [HDInsight] ノードに移動すると、先ほど作成した Hadoop クラスターがあります (今回は WeblogAnalytics という名前です)。このノードを展開して 2 つの子ノード (Hadoop データベースと、作成時にアカウントに関連付けた既定の BLOB ストレージ) を表示します。現在 BLOB ストレージには、クラスターと同じ名前の既定のコンテナーが含まれており、Hadoop アプリケーションは提供された URI を使用してこのコンテナーとサブフォルダーに読み取りと書き込みを実行することができます。

データをこのコンテナーにコピーするか読み込んだら、適切な URI を提供してデータを参照できるようになります。Web サイトが Azure 外に配置されている場合は必要に応じて AzCopy を使用して、このストレージ コンテナーに目的のログを移動します。Azure にデータが既に存在していれば、それ以上コピーしなくてもそのデータにアクセスすることができます。アプリケーションをホストするのに Azure Web サイトを使用している場合はこちらの方がずっと簡単です。その場合、クラスターの作成時に、クラスターに関連付けるストレージ アカウントとして、Web サイトのデータを含むストレージ アカウントを選択します。また、HDInsight クラスターのカスタマイズ機能を使用して、複数のストレージ コンテナーを追加することも可能です。この場合、次のような参照によって必要なファイルに簡単にアクセスすることができます。

wasb://container@storage.blob.core.windows.net/example/data/filename.ext

今回は、HDInsight のサンプル コードに含まれているいくつかのログ データを使用することにします。既定のコンテナーの HDISamples フォルダーに移動すると、サンプルが含まれる一連のフォルダーがあり、次のファイルが含まれています。

HDISamples/webloganalyticsstorage/webloganalytics/HdiSamples/
  WebsiteLogSampleData/SampleLog/909f2b.log

手を加えていないデータそのものが使用可能になったら、それを Hive テーブルに変換します。このテーブルは、行の選択が可能な行セットとして、別の Hive クエリから参照できます。そのためには、テーブルを External テーブルとして作成します。これは Hadoop ではメタデータ操作になり、ディスク上のデータは変更されません。必要なステップは、列の型を定義して名前を付け、使い慣れた SQL 形式でデータを参照できるようにするだけです。ビッグ データ モデルの重要な側面は、データの形式とデータそのものの間で遅延バインディングを実行できる点です。前もってスキーマを作成しておかなくてもよく、読み込み時のデータのクリーンアップについても考える必要はありません。実のところ、定義したスキーマにデータの行が従っているかどうかはチェックされません。そのため、異なるバージョンのデータや不足しているデータがビジネス ロジックに応じて処理されているかどうかなどのクエリは自身で作成する必要があります。

ここでも、Visual Studio IDE を使用して作業を簡単にすることができます。図 2 に、SQL Server のツールに似たテーブル作成ツールを示します。[Table Columns] (テーブルの列) にエントリを追加し、名前、データ型、その他のコメントを入力して、簡単にテーブルの列を定義できます。基本的な空のテーブル定義を作成する場合は、名前を入力するだけでかまいません。ただし今回は、この定義を既存のファイルに適用するので、先ほどの URI を指定するために External テーブル プロパティを使用します。

Hive テーブル定義の作成
図 2 Hive テーブル定義の作成

メタデータを操作するには、Hadoop クラスターで DDL ステートメントを実行します。[Create Table] (テーブルの作成) ダイアログには、生成された DDL が表示されます。今回は次のようになります。

CREATE EXTERNAL TABLE IF NOT EXISTS weblogs (s_date date, s_time string,
  s_sitename string, cs_method string, cs_uristem string,
  cs_uriquery string, s_port int, cs_username string, c_ip string,
  cs_useragent string,
  cs_cookie string, cs_referer string, cs_host string, sc_status int,
  sc_substatus int,
  sc_win32status int, sc_bytes int, cs_bytes int, s_timetaken int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
STORED AS TEXTFILE LOCATION 'wasb://webloganalytics@
  webloganalyticsstorage.blob.core.windows.net/HdiSamples/ 
  WebsiteLogSampleData/SampleLog/'
TBLPROPERTIES ('skip.header.line.count'='2');

DDL には余分な項目がいくつか含まれています。今回の例のサンプル ファイルでは、各行の列値を区切るためにスペースが使用されているため、ROW FORMAT 句を使用してフィールド区切り記号にスペースを指定します。Hive によって、テーブルに関連する特定のメタデータ値をいくつか設定することも可能です。DDL の最終行では、テキスト ファイルに、省略可能なヘッダー情報を 2 行含めるよう指定しています。この DDL を切り取って別の HiveQLスクリプトに貼り付けます。または、[Submit] (送信) ボタンをクリックしてテーブルの作成を開始することもできます。ボタンをクリックすると Hadoop クラスターにタスクが送信され、テーブルが作成されます。Visual Studio にはジョブのステータスを示すウィンドウがあり、最新情報に更新してタスクの完了ステータスを追跡することできます。タスクが完了したら、サーバー エクスプローラーで新しいテーブルを表示したり、その定義を参照したり、(データベースのコンテキスト メニューから) 最初の 100 行を確認することができます。

データを情報に変える

Web サイトがどの程度適切に動作しているかを把握しておくことは重要です。手始めに、ユーザーが HTTP 要求でクライアントのエラーを受け取る頻度を見てみます。さまざまなソースの参照元が受け取るさまざまな種類のエラーを確認し、エラーの種類別に分類して、最も影響が大きいエラー (出現頻度の多いエラー) から順に並べます。結果を保存する場合は、CREATE EXTERNAL TABLE ステートメントを使用して新しい Hive テーブルを作成して保存します。今回は、select ステートメントを使って計算値を挿入することで、テーブルを設定します。コードは、図 3 のようになります。

図 3 計算値の挿入

DROP TABLE IF EXISTS ClientErrors;               
--create table ClientErrors for storing errors users experienced and their frequencies
CREATE EXTERNAL TABLE ClientErrors(sc_status int, cs_referer string, cs_page string, cnt int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
--populate table ClientErrors with data from table weblogs
INSERT OVERWRITE TABLE ClientErrors
SELECT sc_status,
  cs_referer,
  concat(cs_uristem,'?', regexp_replace(cs_uriquery,
  'X-ARR-LOG-ID=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}','')) cs_page,
  count(distinct c_ip) as cnt
FROM weblogs
WHERE sc_status >=400 and sc_status < 500
GROUP BY sc_status,
  cs_referer,
  concat(cs_uristem,'?', regexp_replace(cs_uriquery,
  'X-ARR-LOG-ID=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}',''))
ORDER BY cnt;

このコードでは、データである程度のクリーンアップを行っているのがわかります。cs_uriquery フィールドの場合、HTTP 要求と共に渡されたクエリ文字列を確認するだけでよく、ログに格納されている X-ARR-LOG-ID 情報は必要ありません。したがって、文字列のその部分を空白に置き換えています。もちろん、これは宣言型のクエリ ステートメントで、プロシージャではないので、使用する変換の再利用を cs_uriquery フィールド用に指定することはできません。ただし、クエリ実行ランタイムでこの状況を最適化することはできます。

最も頻繁に Web サイトを訪れる参照元も見てみます。そのためには、IIS ログで cs_referer フィールドを選択して、日付と参照元別に参照数を数えます。このデータも今後のために保存するので、RefersPerDay という別の Hive テーブルを作成して、クエリ結果をそこに格納します。図 4 に、テーブル作成とデータ挿入の方法を示します。

図 4 テーブル作成とデータ挿入

DROP TABLE IF EXISTS RefersPerDay;
--create table RefersPerDay for storing references from external Web sites
CREATE EXTERNAL TABLE IF NOT EXISTS RefersPerDay(year int, month int, day int,
  cs_referer string, cnt int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
--populate table RefersPerDay with data from the weblogs table
INSERT OVERWRITE TABLE RefersPerDay
SELECT year(s_date), month(s_date), day(s_date),
  cs_referer, count(distinct c_ip) as cnt
FROM weblogs
WHERE sc_status >=200 and sc_status <300
GROUP BY s_date, cs_referer
ORDER BY cnt desc;

図 3図 4 のコードはすべて、1 つの Hive QL ファイルにまとめることができます。これで、新しい Hive アプリケーション プロジェクトを作成し、このコードを入力して、クエリを実行することができるようになります。Hive プロジェクトでは、クエリを将来利用するために保存することができます。ここで紹介している例はきわめてシンプルですが、IIS ログの実際の形式に基づいています。したがって、実際のサーバー ログに対して動作し、より複雑な分析を作成する際の基盤になります。

当然、クエリを実行するということは、クエリを Azure の Hadoop クラスターに送信することになります。そのためには、ジョブの送信先となるクラスターを選択する必要があります。HDInsight ツールバーでは、自身のサブスクリプションで使用可能なクラスターの一覧からクラスターを選択できます。図 5 のように、今回は WeblogAnalytics クラスターを選択します。[Submit] (送信) を選択するとそのクラスターにクエリが送信されます。図に示しているのは高度な送信機能で、クラスターに表示されるジョブにわかりやすい名前を付けることができます。こうすると、実行中のクエリを簡単に追跡できるようになります。Hive プロセッサー用にさらに引数を追加することもできます。

クエリの送信
図 5 クエリの送信

クエリの送信後すぐに図 6 のようなジョブの概要ウィンドウが表示され、クエリの現在状態 (初期化済み、実行開始、完了、失敗) が表示されます。Hive クエリを MapReduce タスクに変換し、多数のノードに分散して実行することができます。このようにすれば、まさに Hadoop 処理モデルがその能力を発揮し、大規模なスケール変換が実現されます。[Job Summary] (ジョブの概要) ビューでは、一緒に送信されたすべてのクエリを完了するまで、ジョブが map フェーズと reduce フェーズでさまざまな割合に変化するのがわかります。

[Hive Job Summary] (Hive のジョブの概要) ウィンドウ
図 6 [Hive Job Summary] (Hive のジョブの概要) ウィンドウ

ジョブが完了したら、関連しているクエリを確認して、[Job Details] (ジョブの詳細) の下にあるリンクからジョブの出力、例外、またはエラーをチェックすることができます。もちろん、要約されたデータはクエリによって新しいテーブルに格納され、それらのテーブルとコンテンツをサーバー エクスプローラーから確認することができます。また、さらに要約または集計するために、これらの新しいテーブルのデータを使用する新しいクエリを実行することもできます。

まとめ

HDInsight によって、生成した、またはクラウドに転送した大量のデータにすばやく簡単にアクセスできるようになります。Hadoop クラスターの機能を強化してデータを処理し、Azure のどこからでもデータにアクセスすることができます。Hive では、データの構造を指定して、今後のデータ形式の変更と共に進化させることも可能です。HDInsight Tools for Visual Studio を使用すると、Hadoop クラスターとデータを直感的に確認することができます。さらに重要なのは、Hive クエリ プロジェクトを作成して、他のコードと同じように管理できる点です。これにより、機能している簡単なクエリを、徐々に複雑な情報処理に変えることが可能になります。HDInsight を使用して作成した集計データを最もわかりやすく表示するには、HDInsight ソースへの直接接続を可能にする Power BI などのツールを使います。機械学習などの機能も、これらのツールと組み合わせて使用すれば、分析能力を高めることができます。Azure サービスによるビッグ データ問題の解決について、今後も注目してください。


Omid Afnan は、分散演算システムとそれに関連する開発ツールチェーンの実装に取り組んでいる、Azure ビッグ データ チームの主任プログラム マネージャーで、中国に在住および勤務しています。連絡先は omafnan@microsoft.com (英語のみ) です。

この記事のレビューに協力してくれた技術スタッフの Duc Le および Tony Murphy に心より感謝いたします。
Duc Le (マイクロソフト): Duc Le はマイクロソフトの HDInsight ビッグ データ チームのソフトウェア開発者です。マイクロソフトに所属する前は、プログラミング言語とソフトウェアのテストについて研究する大学院生でした。彼の趣味は読書で、好きな作家はアーサー コナン ドイルです。

Tony Murphy (マイクロソフト): Tony Murphy は 2007 年にマイクロソフトに入社しました。最初は SQL Server エンジンに携わり、その後 SQL Azure チームに移動しました。彼はマイクロソフトの HDInsight チームの創設メンバーです。