Windows Azure PDTのバージョンと制約
前回 に引き続き、WorkerRoleで動作するMySQLをWindows Azureにデプロイしてみます。まず、Azure環境のエミュレータ「コンピュートエミュレータ」で動作を確認し、次に、設定ファイルなどを書き換えてAzure上にデプロイし、phpMyAdminを使ってMySQLの動作を確認します。
その前にいくつか補足があります。まず、現在入手できるWindows Azure Tools for Eclispeを組み込んだEclipse PDT(WIndows Azure PDT)では、昨年11月に公開されたAzure SDKの新バージョン1.6(Windows Azure SDK for .NET - November 2011)を直接利用できなくなっています。
これは、1.5まではSDKのbinディレクトリ(C:\Program Files\Windows Azure SDK\v1.5\bin)に含まれていたコンピュートエミュレータ関連のプログラム(csrun.exeなど)が、専用のディレクトリ(C:\Program Files\Windows Azure Emulator\emulator)にインストールされるようになり、Eclipse PDTから自動的に起動できなくなっているためです。
コマンドラインを指定できればいいのですが、GUIからは設定ができないようです。そのためここでは、前回から引き続き、SDKの1.5を利用することにします。なお、1.5のスタンドアロン版はこらち から入手可能です。
また、これまでローカル環境については32bit、64bitを明示してきませんでしたが、前回からWindows 7 64bit版を利用しています。前回インストールしたMySQLは64bit版ですが、32bit版のWindowsと32bit版のMySQLを利用する場合でも、今回説明する手順でWindows Azure上でMySQLが動作することは確認済みです。
それでは、Azure環境のエミュレータでMySQLを動作させてみましょう。
エラーの確認とファイルの修正
まずは、前回発生した下記のエラーに対処します。
Error : CloudServices41 : The entrypoint WorkerRole1.dll is not a valid assembly. Please provide a relative path to the binary that implements the entrypoint.
エラーにあるWorkerRole1.dllというのは、WokerRoleで動作させるプログラムの処理を決めるC#等で作成されるdllです。Visual Web DeveloperなどのIDEを用いる場合は、WorkerRole.csを自分で作成しデプロイ時にどのプログラムを起動しどう動作させるかを決めることができます。
ただ、今回利用しているEclipse PDTでは、Windows Azure Tools for Eclispe(windowsazure4e)のソースコード内にWorkerRole1.dllやMysql_WorkerRole.dllが埋め込まれており、コンピュートエミュレータの起動やデプロイするパッケージの作成についても自動で行われます。エラーの要因は、その際に利用するdllのファイル名の受け渡しがうまくいかないことが原因と思われます。
Windows Azure SDKのコマンドラインツールを利用して、その引数に適切なdllを指定することもできるのですが、ひとまずここでは、Windows Azure PDTだけでMysqlを動作させるという意図で進めます。具体的には、決してスマートとは言えない方法なのですが、Windows Azure PDTが自動生成したWorkerRole内のMysql_WorkerRoleという名称のファイルをWorkerRole1に変更してしまいます。
ファイル名を変更するのは、Mysql_WokerRole.dll、Mysql_WorkerRole.dll.conifg、Mysql_WorkerRole.pdbの3つで、それぞれ、WorkerRole1.dll、WorkerRole1.dll.conifg、WorkerRole1.pdbに変更します。
図1 Mysql_WokerRole.dllなどが自動生成される
図2 WokerRole1.dllにファイル名を変更する
この状態で、メニューから「Run Windows Azure PHP Project in Development Fabric」を実行すると、エラーは表示されなくなります。
MySQLが起動しない問題への対処
ただ、この状態でもなおMySQLは起動しません。厳密には、起動しようとしますが、エラーで落ちてしまいます。原因は、my.ini内にある「skip-locking」が最近のMySQLでは推奨されていないからです。
コンピュートエミュレータのログが、ユーザーのホームディレクトリ内のAppData\Local\dftmp\resource\文字列\directory\MySQLDatastore\コンピュータ名.errに記録されていますので、それを確認すると、以下のように、「 unknown option '--skip-locking'」となり、Shutdownしていることがわかります。
図3 unknown option '--skip-locking'でMySQLが起動しない
なお、ログの所在(上の「文字列」 )は、タスクバーのアイコンからコンピュートエミュレータを表示すると、WorkerRoleのログから知ることができます。
図4 コンピュートエミュレータのWorkerRoleのログ
エラーに対処するためにまず、my.iniをEclipseのエディタなどで開き、30行目のskip-lockingをコメントアウトします(または、skip-external-lockingに変更する) 。
図5 skip-lockingをコメントアウト
さらに、ServiceDefinition.csdefとServiceConfigulation.cscfgから、mysql-init.txtに関連する箇所をコメントアウトします。mysql-init.txtは、パスワードのリセットなどの初期化処理を行うものですが、このファイルが指定場所に存在しない場合は、やはりMySQLがエラーで起動しません。
具体的には、図6 と図7 のように、ServiceDefinition.csdefの33行目とServiceConfigulation.cscfgの29行目をコメントアウトしておきます(なお、コメントアウトせずに、空のmysql-init.txtをSample2_WorkerRole\mysql以下に置いても大丈夫です) 。
図6 <Setting Name="InitFILE"/>をコメントアウト
図7 <Setting Name="InitFILE" value="mysql-init.txt"/>をコメントアウト
エラーへの対処は以上です。なお、ここで用いるmy.iniは、Windows Azure PDTが自動的に作成したAzure向けのmy.iniです。MySQLをインストールしたフォルダにあるmy.iniをコピーしてもうまく動きませんので注意が必要です。
コンピュートエミュレータでの動作確認
次に、メニューから「Run Windows Azure PHP Project in Development Fabric」を実行するわけですが、コンピュートエミュレータの動作確認を正しく行うために、MySQLの起動状態やデータファイルを確認しておきます。
まず、タスクバーのアイコンを右クリックして、コンピュートエミュレータを終了させます。コンピュートエミュレータを終了させると、エミュレータが起動させたプログラムも一緒に終了します。また、タスクマネージャーを使ってローカル環境にインストールしたmysqld.exeが起動していないかどうかを確認し、もし起動している場合は終了させます。
図8 mysqld.exeを終了させておく
次に、前回設定したrootのパスワードなどを含むMySQLのデータファイルをプロジェクトに追加します。具体的には、Windows ExplorerなどでSample2_WorkerRole\mysqlを開き、dataフォルダ内を削除したうえで、C:\ProgramData\MySQL\MySQL Server 5.5\dataフォルダ内のmysqlフォルダ、performance_schemaフォルダなどをコピーします(実際には、この段階ではrootのパスワードしか設定していませんので、\data\mysql内のuser.MYDとuser.MYIを上書きコピーすれば大丈夫です) 。
図9 MySQLのデータをプロジェクトに追加する
これでようやく設定が終わりましたので、メニューから「Run Windows Azure PHP Project in Development Fabric」を実行します。しばらく待っていると、Eclipse内に、index.phpが表示され、また、コンピュートエミュレータがmysqld.exeを起動させたことを示す、下記のようなWindows Firewallの警告が表示されます。
図10 MySQLが起動した場合のWindows Firewallの警告
アクセスを許可してから、Eclipse内に表示された画面で、アドレスに http://127.0.0.1:81/phpmyadmin を指定します。すると、次図のようなphpMyAdminのログイン画面が表示されるはずです。
図11 phpMyAdminのログイン画面
ここでサーバに「localhost:20000」 、ユーザー名に「root」 、パスワードに事前に設定したパスワードを指定して、ログインしてみます。無事、ログインできると次の画面が表示されるはずです。なお、Windows Azure PDTでは、MySQLのポートはデフォルトで20000に設定されます。
図12 ログイン後の画面
以上で、コンピュートエミュレータ上でのMySQLの動作は確認できました。
Windows AzureにデプロイするためのPHPとMySQLの設定
続いて、パッケージを作成して、Windows Azure上にデプロイしてみます。第3回でデプロイしたように、メニューから「Create Windows Azure Service Package for Windows Azure PHP Project」を選択してパッケージを作成しますが、このままAzureにデプロイしても正しく動作しません。デプロイする前に、いくつか設定が必要です。
1つは、php.iniの変更です。PHPはローカル環境で動作しており、Azure上で動作するphpと参照するディレクトリなどが異なります。Eclipse PDTではあらかじめ組み込まれたPHP(5.3.4)のほか、個別にインストールしたPHPを利用できます。
今回は、第2回でインストールしたVC9 x86 Non Thread SafeのPHP(5.3.8)を利用していますが、このphp.iniを用いて、Azure上のphpMyAdminを動作させようとすると、以下のようなエラーで、ログイン画面そのものが表示されません。
図13 PHP設定ファイルがエラー
これは、Windows Azure上では、WindowsフォルダはC:ではなくD:にあることから、php.iniで指定したsessionの保存先が読み込めないためです。
そこで、Eclipseのエディタでphp.iniを開き、session.save_pathに、C:ドライブが指定されている箇所をD:ドライブに設定します。
具体的には、910行目(行番号は環境やバージョンにより異なると思います)にあるC:\Windows\TempをD:\Windows\Tempとします。同じようにC:ドライブが指定されている箇所も書き換えておきます。
図14 php.iniの変更点
もう1つは、MySQLの設定です。さきほど、phpMyAdminからログインするサーバとして、localhost:20000を指定しましたが、Azure上にデプロイされたWebRoleやWorkerRoleには、それぞれ異なるプライベートIPアドレス(エンドポイント)が割り振られます。そのため、phpMyAdminのログイン画面から、localhost:20000を指定してもログインできないのです。
WebRoleで動作するphpMyAdminからWorkerRoleで動作するMySQLにアクセスするためには、localhostではなく、10.x.x.xのように、エンドポイントを個別に指定する必要があります。また、localhost以外のホストからログインできるユーザーを作成しておく必要があります。具体的には、以下のようにします。
まず、コンピュートエミュレータを終了させ、ローカル環境でMySQLサーバを立ち上げます。mysqlコマンドを使ってログインし、ユーザーとデータベースと作成します。ここではそれぞれsampledbuer、sampledbとします。このあたりは、Linux環境でのMySQLの操作と変わりません。具体的には、コマンドプロンプトを立ち上げて、以下のようにします。
cd C:\Program Files\MySQL\MySQL Server 5.5\bin
start mysqld.exe
mysql -u root -p
Enter password:
MySQLサーバにログインしたら、以下のようにします。
mysql> create database sampledb;
mysql> grant all on *.* to sampledbuser identified by '********';
mysql> flush privileges;
ユーザーを作成するときに、sampledbuser@localhostなどとすると、Azure上でログインできなくなるので注意が必要です。
データベースとユーザーの作成が終わったら、MySQLからログアウトし、タスクマネージャを使ってmysqld.exeを終了させます。
そのうえで、さきほどrootパスワードを設定したファイルをコピーしたのと同じように、C:\ProgramData\MySQL\MySQL Server 5.5\dataにあるファイルをSample_WorkerRole\mysql\dataにコピーします。実際には、前回から更新のあった、\data内のsampledbフォルダと\data\mysql内のuser.MYDとuser.MYIをコピーすれば大丈夫です。
また、ログインのために必要なWorkerRoleのエンドポイントとポートは、「 MySQLIP」と「MySQLPort」という変数に設定されますので、PHPプログラムからそれぞれ、$_SERVER["MySQLIP"]、$_SERVER["MySQLPort"]として取得できます。
ここでは、WebRoleのindex.phpに下記を追加し、ログイン時に値がわかるようにしておきます。
<p>WorkerRoleIP: <?php echo $_SERVER["MySQLIP"]; ?></p>
<p>WorkerRolePort: <?php echo $_SERVER["MySQLPort"]; ?></p>
図15 index.phpを編集
なお、index.phpに、phpinfo()を記述しておけば、これらの値もPHP Variableなどとして記載されていますので、それを参照してもいいでしょう。
以上で、デプロイのためのパッケージ作成の準備が整いました。
パッケージの作成とAzureへのデプロイ
では、パッケージを作成して、Azureへデプロイしてみましょう。パッケージは、ServiceConfiguration.cscfgとServiceDefinition.csdefがあるプロジェクト名と同じフォルダ(ここではSample2)に作られます。メニューから「Create Windows Azure Service Package for Windows Azure PHP Project」を実行して、しばらく待っているとフォルダが自動的に開き、Sample2.cspkgが作成されていることが確認できます。
ブラウザでWindows Azureの管理ポータル を開き、ホステッドサービスに新規運用環境としてデプロイします。
図16 デプロイの画面
ここでは、ホステッドサービス名としてphpmyadminmysql01としてデプロイしました。下図のようにWebRoleとWokerRoleが「準備完了」になれば、アクセス可能です。アクセスする際のURLは、http://phpmyadminmysql01.cloudapp.net となります。
図17 WebRoleにphpMyAdmin、WorkerRoleにMySQLをデプロイした画面
アクセスすると、index.phpの結果が表示されています。ここでは、WorkerRoleのIPが「10.62.96.167」となりました。
図18 index.phpの表示結果
次に、URLにphpmyadminの文字列を追加して、phpMyAdminのログイン画面を表示させます。うまく表示されたら、先ほどのIPアドレス「10.62.96.167」と、デプロイ前に作成したユーザー名「sampledbuser」 、パスワードを使ってログインします。
図19 Azureで動作しているphpMyAdminのログイン画面
うまくログインできると、下の画面が表示されるはずです。
図20 AzureのWorkerRoleで動作しているMySQLをphpMyAdminから操作する
これで、AzureのWorkerRoleでMySQLが動作していることが確認できました。
WorkerRoleでMySQLを動作させる際の課題
もっとも、この状態で動作はするものの、MySQL内のデータはインスタンスの再起動にともなって消えてしまいます。また、PHPプログラムからMySQLにアクセスするためのIPアドレスも固定というわけではありません。さらに、インスタンスを複数立ち上げてスケールアウトを図ろうとする場合、どのようにデータを同期させるかという問題もあります。そのため、MySQLに継続的にアクセスするためのプログラム側の処理やデータを永続化する工夫が必要になります。
実は、WorkerRoleでMySQLを動作させる方法は、2009年のPDCで発表 されており、そのためのアクセラレータ(容易に導入するためのパッケージのようなもの)も「Windows Azure MySQL PHP Solution Accelerator」 として公開されています。
このアクセラレータでは、複数のMySQLを立ち上げ、マスター/スレーブ構成を設定できるなど、WorkerRoleのMySQLが持つ課題の解決を図っています。とはいえ、4年近く前に公表されたものであり、その後の周辺アプリケーションのバージョンアップなどにより、すんなり動作させることがほとんどできない状態です。
また、Web PIのAzure版とも言うべき、Azure上でアプリケーションを簡単に導入できるツール「Windows Azure Companion」 もマイクロソフトから公表されていたのですが「試験的ツールだった」として、2011年7月に配布が終了してしまいました。
今回利用しているWindows Azure PDTもマイクロソフトのサポートを得ながら開発されているものですが、1年近く更新が止まっており、最新SDKへの対応やMySQLのサポートについての改善は進んでいません。もう少し簡単にMySQLを動作できるようになればいいのですが、現時点では、今回紹介した方法が最も少ない手順だと思います。
次回は、WokerRoleの課題などを踏まえつつ、MySQLのデータをストレージに保存したり、Windows Azureドライブを利用してMySQLを動作させたりする方法を検討してみたいと思います。