MongoLab で、Cloud な MongoDB 活用

最近アナウンスがあったが (ここ に日本語で紹介してくれている)、 Azure store で提供されているサービスが、Azure Portal から使えるようになった。Azure 上で Multi tenant で提供されている著名なサービス (例えば、MySQL のクラウド版の ClearDB や、SMTP メールの SendGrid など) とか、 データを提供する各種サービスが Azure ポータルから使えるわけだ。

ここで嬉しいのは、Amazon (AWS) だけでなく、Azure からも MongoLab が扱える点だ。(MongoLab は、MongoDB 版の “Database as a Service” と思ってもらえば良い。データベース サーバーの監視や起動・停止、バックアップなど、SLA を自分で実装するのではなく、契約ベースで利用する。)
Azure Virtual Machine (Azure VM) で、Linux や Windows で MongoDB を立てても良いが、 Azure ポータルから MongoLab のデータベースを立て、「MongoDB のサービス」として Azure 上の C# などからアクセスできるようになる。つまり、すべて PaaS のプラットフォームを使って簡易に利用できる。(この場合、もちろん、使用する MongoDB は Azure 上の Region で hosting される。)

残念なのが、現段階 (2012/11/03) の Azure Preview では、アカウント Profile が United States の場合しかアドオンを利用できないようで、つまり、日本で契約している場合は、まだ上図の画面を拝むことはできない。(この制約はいずれなくなるらしいが、少なくとも今は無理だ。)
2012/12/25 追記 : ようやく、日本語の Azure Preview Portal からも使えるようになった。
そこで、ClearDB なども同じだが、本家の MongoLab のサイト (https://mongolab.com/home) から Azure の MongoLab が使えるので、 今回は、その手順で、簡単に使い方を紹介したい。(MongoDB そのものに関する細かな手法については、専用のサイトを参照してほしい。)

Sign-up と Database の作成

まずは、MongoLab のサイト (https://mongolab.com/home) に行ってサインアップをおこなう。ちなみに、0.5 GB までの Shared Plan (他のデータベースと、仮想マシンを共有) なら無償で使える。

そして、データベースを作成するが、ここで、下図の通り、Provider として Azure を選択しよう。

データベース作成の際に、Database User の作成とパスワードを設定するが、このあと説明するように、パスワードは URI としても使用されるので、できるだけ @ (アットマーク) など URI の予約語は使わないほうが良い。

なお、残念ながら、現時点の MongoLab では、Windows Azure 用の Dedicated VM Plan はないらしく、 専用の VM で作って VNET (Virtual Network) で構成するなどの使い方は試せない。(まあ、Amazon 版の Dedicated VM Plan も、まだ Beta なんだけどね)

データベースが作成されたら、データベースが使用している xxxxxxxx.mongolab.com のサーバーの名前解決をしてみると良いだろう。ちゃんと、 zzzzzzz.cloudapp.net という Azure のドメインで動いていることがわかる。 また、データベースの管理画面 (下図) を見て、使用している MongoDB のバージョンもチェックしておこう。下図の通り、 右下に mongod プロセスのバージョンが表示されているが、 現在は、バージョン 2.0.7 であることがわかる。(このため、C# から Linq とかも問題なく使える。)

このあと見ていくように、MongoLab は、MongoDB のコマンドライン ユーティリティ (mongo) を使って管理できるが、 この際、できる限り、同じバージョンの MongoDB を入れておいたほうが良い。そのためにも、使っている mongod のバージョンはちゃんと把握しておこう。

Command Line からの管理

では、実際に、コンソール (mongo) から管理をおこなってみよう。 上図の画面の通り、MongoDB の接続先のアドレスが表示されているので、MongoDB をインストールして、コマンドライン ユーティリティ (mongo) でこのアドレスに接続する。(下記の dbuser と dbpassword は、データベース作成時に追加したユーザー情報だ。また、server name, database port の部分もテナントによって異なるので注意してほしい。)

mongo <server name>.mongolab.com:<database port>/<database name>
  -u <dbuser> -p <dbpassword>

いつものようにプロンプトが表示されるので、 あとは、普通の MongoDB の使い方と同じだ。 例えば、下記では、現在使用しているデータベースの名前を取得している。

> db.getName();
testdb

下記では、 Orders コレクションの Name プロパティに Index 作成をおこなっている。

> db.Orders.ensureIndex({Name:1});

コマンドラインを使う場合、1 つ注意点がある。Azure の癖を知っている人には説明の必要はないと思うが、 Azure は、一定時間 Idle 状態の接続は強制切断される。このため、 コマンドライン ユーティリティも長時間ログインしたままにせず、面倒かもしれないが、仕事が終わったら、まめに exit しよう。(Socket エラーなど、切断されていたら、再度、mongo で入りなおす。)

プログラミング言語 (Driver) からの接続

プログラミング言語からも、いつものように利用できる。(なので、特に説明の必要はないが、念のため書いておこう)
例えば、C# から接続する場合、いつものように、10gen の Official C# driver を NuGet から取得する。

あとはプログラミングをおこなうだけだ。Driver から接続する際の接続文字列も、上記の管理画面に表示されている。以下のフォーマットの接続文字列となる。

mongodb://<dbuser>:<dbpassword>@<server name>.mongolab.com:<server port>/<database name>

以下のコードを記述すると、登録や検索が問題なくできることがわかる。何度も繰り返すが、一般的な MongoDB の使い方と何ら変わらない。(下記は、ASP.NET MVC のサンプル コードだ。)

using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Driver.Linq;

public class Order
{
  public ObjectId _id { get; set; }
  public string Name { get; set; }
  public int Price { get; set; }
  public string Category { get; set; }
}

public ActionResult Test1()
{
  MongoServer server = MongoServer.Create(@"mongodb://<dbuser>:
    <dbpassword>@<server name>.mongolab.com:<server port>
    /<database name>");
  MongoDatabase db = server["<database name>"];
  MongoCollection col = db.GetCollection("Orders");

  // save
  Order obj1 = new Order()
  {
    Name = "test1",
    Price = 100,
    Category = "material"
  };
  col.Insert(obj1);
  Order obj2 = new Order()
  {
    Name = "test2",
    Price = 200,
    Category = "material"
  };
  col.Insert(obj2);
  Order obj3 = new Order()
  {
    Name = "test3",
    Price = 150,
    Category = "food"
  };
  col.Insert(obj3);

  // find (Linq)
  Order sel = (from c in col.AsQueryable()
        where c.Name == "test2"
        select c).FirstOrDefault();

  ViewBag.Message = string.Format("_id:{0}, Price:{1}",
    sel._id, sel.Price);

  return View();
}

あとは、完成したアプリケーションを Azure に発行すれば、 同じ Region で動作する MongoLab を使ったクラウド アプリケーションの出来上がりだ。(パフォーマンスなどを考慮し、できるだけ、MongoLab のデータベースと同じ Region に発行しておこう。)

Bulk の処理などを実行してもらうとわかるが、まあそれほど違和感ない速度で返ってくる。(ただし、Shared なので、いろいろ状況に応じ変わってくるとは思うが。。。)

(追記) Dedicated 登場

Mongolab : Announcing New MongoDB Instances on Microsoft Azure」にあるように、MongoLab の Dedicate 版が提供された。

以前はスケーラブルな構成がむずかしかったが、この Dedicated 版により、待望の Replica Set、さらに「Mongolab : Plans & Features」によると Sharding Cluster も利用できるようなので、是非 お試しあれ。(まだ試していない)

Advertisements

AWS Elastic Beanstalk による .NET 開発 (手順)

Amazon Elastic Beanstalk や RDS for SQL Server を使った .NET 開発について書こうと思う。

基本的な流れ

まずは、どんな風に使っていくか簡単に書いておこう。 当然だが、利用するためには、事前に Amazon Elastic Benastalk にサインアップをしておく。(Security Credential にアクセスし、そこに表示されている口座番号 (Account Number)、Access Key ID、Secret Access Key をコピーしておく。)

つぎに、Visual Studio の入っている開発環境には、AWS Toolkit for Microsoft Visual Studio をインストールしておく。(なお、今回は、Visual Studio 2010 を使った。)

Visual Studio を起動すると、AWS 用に「AWS Console Project」、「AWS Web Project」などのプロジェクト テンプレートが表示されるが、Azure と違って、他のプロジェクト テンプレートを使用しても、そのまま AWS に配置できる。例えば、プロジェクト テンプレートから ASP.NET MVC Application を選択して普通にプロジェクトを新規作成し、開発 (プログラミング) をおこなって、AWS に配置することもできる。

プロジェクト作成の際は、ターゲット フレームワークに注意してほしい。現時点 (2012/05) の Amazon Elastic Beanstalk では、.NET Framework 2.0、.NET Framework 4 が使用可能なため、このいずれかのフレームワークで構築しておく。(今回は、.NET Framework 4 を使った。)

適当にコードを作成したら、「Publish to AWS」で AWS に発行できる。

この際、発行用の AWS アカウントの情報を入力する画面が表示されるので、上記でコピーした Account Number (口座番号)、Access Key ID、Secret Access Key を入力して「OK」を押す。

以降はウィザードが表示されるので、ウィザードに従って、Region、配置方法、ドメイン (URL)、Container Type (これは、現在は 2008 R2 / IIS 7.5 だけのようだ)、ターゲット フレームワーク (.NET 2.0 か .NET 4) などの基本情報を設定して先に進み、「Deploy」ボタンを押す。 配置が完了すると、設定した URL でアプリケーションに接続できるようになる。(なお、Windows Azure のように、パッケージ (zip ファイル) を作成して、あとから AWS Management Console でアップロードすることもできる。)

内部では、配布用のパッケージ (.zip) が S3 上にアップロードされ、環境への配置時に EC2 のインスタンス作成や、Elastic Load Balancer (ELB)、Auto Scaling Group などの設定がおこなわれているようだ。(このため、配置後は、これらを個別に管理することもできる。) また、配置後は、指定した URL を使った health check が走り、ローカルでちゃんと動いていても、AWS への配置で接続できない場合などは、この health check のエラーとなる。このため、このエラーが表示される場合は、実際に Fiddler などを使って接続先の URL が返すエラーの内容を確認してみると良いだろう。

Beanstalk アプリケーションの管理

配置後の管理は、主に、AWS Management Console で可能だ。(Windows Azure の管理ポータルと同じだと思えば良い。) この画面を使うと、ログの確認や、構成の変更 (例えば、インスタンスの最大数など)、インスタンスの開始、停止、Terminate など、さまざまな設定と管理をおこなうことができる。 通常の AWS の利用では、EC2、ELB など設定を個別でおこなう必要があるが、この画面で Elastic Beanstalk を管理すると、関係する EC2 インスタンスや ELB などの設定を同時におこなってくれる。(例えば、Scaling のインスタンス数の設定を増減させた場合など。) また、SSL (https) 関連などの基本的な設定も、この管理画面でおこなうことが可能だ。

また、Visual Studio の「表示」 – 「AWS Explorer」メニューを選択して表示される AWS Explorer を使うと、(Visual Studio 上で) 簡単な管理や状態の確認などがおこなえる。(RDS の管理などもできる。) ここでは、上記で設定した配置の際のアカウントの編集なども可能だ。

Amazon RDS for SQL Server

Amazon RDS でも SQL Server が使えるため、例えば、ASP.NET の Membership database を SQL Server に作成して、Beanstalk アプリケーション (ASP.NET アプリケーション) から利用することなども可能だ。さっそく使ってみよう。

まず、AWS Management Console で「RDS」を選択し、「Launch DB Instance」をクリックすると、SQL Server (Express Edition、Web Edition、Standard Edition、Enterprise Edition)、MySQL、Oracle などが表示されるので、該当の Edition の SQL Server を選択して、インスタンスを作成する。(その際に表示されるウィザードで、Allocated Size や、Matser DB の UserName / Password などを設定する。)

インスタンスが作成されて利用可能 (Available) になったら、ポータルを使ってエンドポイント (サーバー名) やポートの確認が可能だ。

サーバー名と、Master DB の UserName / Password を入力することで、sqlcmd (コマンドライン ユーティリティ) や SQL Server Management Studio (GUI のユーティリティ) で接続できる。(あとは、いつも通りの要領で、SQL Server を管理すれば良い。) 例えば、接続先のサーバー (エンドポイント) が xxxxxxxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com の場合、sqlcmd でログインして、aspnetdb という名前のデータベースを作成する場合は、下記のコマンドになる。(1433 はポート番号だ。)

sqlcmd -S xxxxxxxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com,1433 -U testadmin -P Password
1> create database aspnetdb
2> go

試しに、Visual Studio コマンド プロンプトから Aspnet_regsql.exe を実行して、上記で作成したデータベース (aspnetdb) にメンバーシップ データベース (テーブル、ストアド プロシージャなど) を作成し、Beanstalk のアプリケーションでこのメンバーシップ DB を使用してみたが、まったく問題なく使用できた。(ただし、Beanstalk アプリケーションの発行の際に、接続先の RDS インスタンスとして、上記を選択すること。)

ドキュメントをちゃんと読むとわかるが、実は、RDS for SQL Server でも、そこそこ「クラウドならでは」の制限はある。しかし、この程度の内容で比べてみると、SQL Azure の場合は、専用のスクリプト を使用する必要があるが (クラウド環境にあわせて、使えない機能がかなりあるため)、RDS for SQL Server の場合には、「SQL Server そのまま」といった感じで使えることがわかる。

Remote Desktop による接続

ちょっと上の用語と混同してしまうが、今度は Remote Desktop Service の “RDS” の話。

Windows Azure 同様、Remote Desktop Protocol (RDP) を使ったリモート インスタンスへの接続も可能だ。(Beanstalk というより、要は、EC2 におけるただの Remote Desktop 接続なんだけど。。。)

改めて、知らない人のために設定方法を書いておくと、まず、いくつか準備が必要だ。AWS Management Console で「EC2」を表示して、「NETWORK & SECURITY」 – 「Key Pairs」で Key Pair を作成しておく。この際、.pem ファイルのダウンロードを促されるので、このファイルをローカルに保存しておく。そして、上記の Beanstalk アプリケーションの配置の際に、下図の通り Key Pair を指定して配置をおこなっておく。

Beanstalk アプリケーションの配置後には、AWS Management Console で「EC2」を表示し、作成された EC2 インスタンスの Action で「Get Windows Admin Password」を選択する。

すると、下記の画面が表示されるので、「Privete Key」に、上記でダウンロードした .pem ファイルの内容をコピーして貼り付け、「Decrypt Password」ボタンをクリックすると、マシンの Administrator のパスワードが表示される。(同時に、接続先のマシンのアドレスなども表示される。)

あとは、Remote Desktop を使用して直接接続するか、AWS Explorer から Elastic Beanstalk のインスタンスを表示して「Connect to Instance」ボタンを押すことで、Remote Desktop を使って AWS のインスタンスにログインできる。(Scaling でインスタンスが複数ある場合は、インスタンスを選択する画面が表示される。なお、AWS Management Console の EC2 の管理画面から Remote Desktop で接続することも可能。)

上図の「Connect to Instance」を使用すると、パスワードを使用せず、前述した .pem の Private Key で接続することもできる。

AWS の Remote Desktop を使用した接続では、ローカルのドライブ (使用しているマシンのドライブ) もマウントされているため、ローカルからリモートへのファイル コピーなども容易だ。

サーバー側における、Beanstalk アプリケーションの管理 (イベント ビューアーの確認など) や、ちょっとしたファイルの設定など、簡単な管理に使うことができて便利だ。(もちろん、ちゃんと incremental deployment をした場合と異なり、配置パッケージのバージョン管理の対象からは外れてしまうが。。。)

結局のところ …

このように、AWS (Elastic Beanstalk) と Windows Azure (Cloud Service) の基本的な構築と管理の流れは似ている。どうやら、今後は、こういった PaaS スタイルの構築と公開にも、さらに慣れておいたほうが良さそうだ。

ただ、ちゃんと見てみると、上記の通り、同じ PaaS の概念ではあるが、性質 (位置づけ) が異なっているのも事実だ。.NET 開発に限って言うなら、Azure では PaaS 用にプラットフォームのベースから洗練されているのに対し、こちら (Elastic Beanstalk) は、IaaS 上の .NET の開発・配置を簡素化 (サポート) してくれるユーティリティーといったほうが正確だろう。使用されているベースは、EC2 など、IaaS のそれと変わらない。(そもそも、AWS 自体は IaaS のプラットフォームなだけに、当たり前だが。) Windows Update の適用 (セキュリティー面) や、環境そのもののバージョン アップなど、いろいろ細かなことを考えると気になるところだ。

しかし、逆に、こうした概念のため、上記のように、作成するプロジェクトもクラウド用の特別な設定は比較的 少なく、使用しているプラットフォームも PaaS 特有の設定 (例えば、Azure ではお馴染みの、PaaS 独自の自動化された部分や、ドライブごとの役割の違い、など) は比較的少ない。つまり、ポータブルで、分かりやすいという点はメリットだろう。

無論、この Beanstalk は、細かなことを考え始めると、まだまだ本格的な .NET 開発には足りない部分が多い。.NET を使うなら Azure のほうが良いにきまっているが、こうした「分かり易さ」という点は、”あり” かもしれない。(いろいろな特徴の PaaS が出てきて、選択できるのは良いかも。。。)