HDInsightのクラスタ作成時にスクリプトを実行する“Script Action”


# Qiitaへ
※ こちらは、昨年TechNetブログに書いた下記のエントリを、現時点の内容に合わせて少々アップデートし、転載したものです。
[HDInsight のクラスタ作成時にスクリプトを実行する “Script Action”](http://blogs.technet.com/b/ksasaki/archive/2014/12/01/introducing-hdinsight-script-action.aspx)


# autoexec.bat あるいは /etc/rc 的なやつ

HDInsight は「ジョブを繰り返し実行する間だけクラスタを動かしておき、使わなくなればクラスタを削除」という使い方が一般的です。「次回も使う(かもしれない)からとっておきたいデータ」はデフォルトファイルシステムであるAzureのBLOBストレージへ置いておくわけです。
こういう使い方をする以上、頻繁にクラスタの作成と削除を繰り返すことになりますが、そうなると「クラスタ作成時に行う環境設定処理を自動化」したくなるのが人情というものです。昨年追加された ”Script Action” で、これが可能になりました。

# Script Action を試してみる

登場した頃は、PowerShellでしか設定できなかったScript Actionですが、今はAzure管理ポータルで簡単ににできるようになりました。

## 管理ポータルでScript Actionを設定
詳しく解説しようと思ったのですが、本家Azureドキュメントサイトでわかりやすく説明されていました。こちらをご覧ください:
[Script Action を使って HDInsight クラスターをカスタマイズする](https://azure.microsoft.com/ja-jp/documentation/articles/hdinsight-hadoop-customize-cluster/)

## Azure PowerShellでScript Actionを設定
今は管理ポータルから簡単に設定できるようになりましたが、以前はAzure PowerShellを使うこの方法しかありませんでした。一応、残しておきます。
下記のように`New-AzureHDInsightClusterConfig`の出力を`Add-AzureHDInsightScriptAction`にパイプして、スクリプトのURIなどを指定します。

    New-AzureHDInsightClusterConfig <ゴニョゴニョ> |
    Add-AzureHDInsightScriptAction `
    -Name スクリプト名 `
    -ClusterRoleCollection 実行するノードの指定 (HeadNode|WorkerNode|HeadNode,WorkerNode)`
    -Uri スクリプトのURI

`-Name` はスクリプト定義に対して付ける名前です。スクリプトファイル名ではありません。処理の内容が分かりやすい名前を付けておくのがよいと思います。 

`-ClusterRoleCollection`には、スクリプトを実行したいノードの種別を指定します。”HeadNode”はHadoopのネームノード(HA構成なので2台)、DataNodeはデータノード達です。
※ ヘッドノードとデータノードの両方を指定するときは、書き方に注意してください。

    [OK] -ClusterRoleCollection HeadNode,WorkerNode 
    [OK] –ClusterRoleCollection “HeadNode”, “WorkerNode” 
    [ダメ] –ClusterRoleCollection “HeadNode,WorkerNode”

3番目の書き方は、“HeadNode,WorkerNode”という一つの文字列になってしまいますので、正しく解釈されません。このオプションには配列を渡す必要があるのです。

`–Uri` にはスクリプトのフルパス名、というか URL を指定します。
`-Uri http://アカウント.blob.core.windows.net/scripts/hdistartup.ps1`
という感じで。

スクリプトは、PowerShell で記述してどこか適当な所 (全ノードからHTTPでアクセス可能なところ) に置いておきます。HDInsight なのでデフォルトの BLOB ストレージへ置いておくのが簡単です。私は、`Set-AzureHDInsightDefaultStorage`で指定するストレージアカウントに、 scripts というコンテナを作成して、そこへ置いています。 内容は、たとえばこんな感じです。(実際今日試したもの)

    setx HADOOP_OPTS "-Dfile.encoding=UTF-8" /M 

全然 PowerShell である必要がない一行ですね…これを `hdistartup.ps1`などと名付けて BLOB ストレージへ置いておくわけです。
 
# 権限

さて。賢明なる読者諸氏はすでにお気づきかもしれません。先ほどのスクリプト例、`setx`に /M をつけて「システム環境変数」をセットしていますが、これは管理者権限が必要な操作です。 

HDInsight のヘッドノードへログオンできるユーザーには管理者権限が付与されず、システム環境変数の設定やシステムロケールの変更、あるいはノードの再起動など様々な操作を封じられてしまっていますが、Script Action なら管理者権限が得られるわけです。これはいろいろ応用の幅が広そうですね！ 

# 注意点！  

Script Action によって実行されるスクリプトは、Azure の Cloud Services におけるスタートアップタスクと同様に、「何度も実行される」ことがあるという点に留意してください。HDInsight のクラスタは Worker ロールの塊ですから、何らかのタイミングで reimage 処理が走り、ロールインスタンスの再作成が起こることがあります。この際、Script Action のスクリプトも再実行されるわけです。 

現在の状態に依存せず、何度実行しても同じ結果が得られる、 idempotent な処理を記述するように心がける必要があります。 

# クラスタ作成スクリプトをどうぞ

さて、Azure 管理ポータルからの GUI によるクラスタ作成に比べると、 PowerShell スクリプトによる作成は若干面倒です(特に不慣れなうちは)。そこで、私が Script Action の実行を試す際に作成したクラスタ作成スクリプトを、GitHub へ置いておきました。よろしければご覧ください。 

[New-HDInsightClusterWithScriptAction.ps1](https://github.com/ksasagit/MoreThanOneScript/blob/master/New-HDInsightClusterWithScriptAction.ps1) 

Script Action 以外にも、 
- クラスタの仮想ネットワークへの配置 
- Hive/Oozie メタストアとしての SQL Database の指定

などやっておりますので、パクって使いやすいかと。
 
# 関連情報

割とわかりやすい情報がいくつか出ておりますので、ご覧下さい。日本語化もされていますが、英語版のほうが新鮮ですから、下記のリンクは英語版を貼っておきます。

基本的な使い方は、こちら
[Script Action development with HDInsight](https://azure.microsoft.com/en-us/documentation/articles/hdinsight-hadoop-script-actions/)

Apache Spark をインストールする例
[Install and use Spark on HDInsight Hadoop clusters](https://azure.microsoft.com/en-us/documentation/articles/hdinsight-hadoop-spark-install/)

そしてこちらは R をインストールする例
[Install and use R on HDInsight Hadoop clusters](https://azure.microsoft.com/en-us/documentation/articles/hdinsight-hadoop-r-scripts/)

Solrをインストールする例
[Install and use Solr on HDInsight Hadoop clusters](https://azure.microsoft.com/en-us/documentation/articles/hdinsight-hadoop-solr-install/)

Giraphをインストールする例
[Install Giraph on HDInsight Hadoop clusters, and use Giraph to process large-scale graphs](https://azure.microsoft.com/en-us/documentation/articles/hdinsight-hadoop-giraph-install/)

ぜひ、Script Action をご活用ください。

[@ksasakims](https://twitter.com/ksasakims)