AWSでmongoを動かしてみる(AutoScale対応)

# AWSでmongoを動かしてみる(AutoScale対応)
Advent Calendar2014ということで、mongoの枠が余ってたので書いてみることにした。他の人達がシャーディングがどうこう言っている中で、１人だけ超初心者投稿だけど頑張る。

今回作ったサンプルのレポジトリ
https://github.com/KeitaMoromizato/mongosample

## 前置き
取り急ぎAWSでmongoを動かしてみたいときは普通にインスタンスにmongoをインストールすればいい。ただしそれだとAutoScaleした時に困る。インスタンスがそれぞれ別のDBを見ていたらデータがおかしな事になってしまうから。
RDBMSなら、AWSにはRDSという便利なサービスがあってDBサーバだけ切り出すことができる。AutoScaleしたインスタンスはそれぞれ同じRDSを見に行けばいい。mongoにはそれが無い。

そんなときはインスタンスをもう一つ立ち上げるのです。

## アプリケーションインスタンスを作る
プログラムを走らせるために、AWSのElasticBeanstalkでアプリケーションインスタンスを作る。

### 1.アプリケーション名を適当に設定

![1.png](https://qiita-image-store.s3.amazonaws.com/0/52054/6b53785f-4ad4-9a47-bd8c-dd9c0ed7f70c.png)

### 2.sails.jsを使うのでnode.jsのWebServer

![2.png](https://qiita-image-store.s3.amazonaws.com/0/52054/6be96644-24bf-a61c-7cfd-2e441f566473.png)

### 3.環境名を指定

![4.png](https://qiita-image-store.s3.amazonaws.com/0/52054/c0a1d8dd-0da8-c04e-7a8c-a7c85d6ed64d.png)

### 4.RDSはいらない

![5.png](https://qiita-image-store.s3.amazonaws.com/0/52054/bf423368-d8ce-05f7-4336-56b98a730991.png)

### 5.カギとかもろもろ設定してLaunch!

## mongoインスタンスを作る

### 1.とりあえずのAmazon Linuxで
![9.png](https://qiita-image-store.s3.amazonaws.com/0/52054/cf3de1b5-9926-8bc5-b285-c22c71233cfe.png)

### 2.色々設定してLaunch!

### 3.名前がついてなかったのでEC2コンソールからmongoインスタンスに名前を付ける
![13.png](https://qiita-image-store.s3.amazonaws.com/0/52054/870012f7-9e65-547c-0c00-f9f16bfaf0fe.png)

### 4.mongoインスタンスのSecurityGroupを確認(リンクを飛ぶ)
![15.png](https://qiita-image-store.s3.amazonaws.com/0/52054/db3d3106-7c63-c0b2-71cb-d1f4da6937c6.png)

### 5.mongoインスタンスのSecurityGroupのInboundでmongo用ポートを開放
![20.png](https://qiita-image-store.s3.amazonaws.com/0/52054/ca4c2f80-e0e4-febf-3858-0955a9d7161a.png)

OK!

## mongoインスタンスの設定
mongo用インスタンスにsshログイン、mongoの設定をしていく。
まずはインストールのためのレポジトリ追加。以下のファイルを作成する。

```
$ sudo vim /etc/yum.repos.d/10gen.repo
```

``` /etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
enabled=1
```

インストールが完了したら起動する前に、重要な設定を変更します。mongoの設定ファイル`/etc/mongod.conf`にて`bind_ip=127.0.0.1`をコメントアウト。これがあるとlocalhostからのアクセスしか受け付けないので大変です。

```
vim /etc/mongod.conf

# bind_ip=127.0.0.1
```

設定が完了したらサービスを開始。

```
$ service mongod start
```

## アプリケーションインスタンスとmongoインスタンスの接続


## Sails.jsでサンプルプログラム作成
最近自分の中でSails.jsブームが来ているのでサンプルはSailsで。アプリケーションを作ります。

```
$ sails new mongosample
```

mongoを使いたいのでmongoモジュールをインストール。

```
$ npm install sails-mongo --save
```

Production環境を認識するための環境変数定義。

``` .ebextensions/00environment.config
option_settings:
  - option_name: NODE_ENV
    value: production
```

`connection.js`にmongoの設定を記述。mongoインスタンスのIPアドレスを設定。

``` config/connection.js
module.exports.connections = {
  //省略

  someMongodbServer: {
    adapter: 'sails-mongo',
    host: process.env.NODE_ENV === "production" ? 'xx.xx.xx.xx' : 'localhost',
    port: 27017,
  },

  //省略
}
```

上で書いた設定を使いますよという命令を`models.js`に記述。これでSails.jsのmongo設定は完了。

``` config/models.js
module.exports.models = {
  connection: 'someMongodbServer',
  migrate: 'alter'
};
```

超適当にAPIを作る。

```
$ sails generate api Hoge
```

もっと適当にViewを作る。

``` views/homepage.ejs
<form method="post" action="/hoge">
<p><input type="text" name="text" size="50"></p>
<p><input type="submit" value="送信する"></p>
</form>
```

## 実行

AWSコンソールからアプリケーションにアクセス。適当にメッセージを入力して「送信」

![17.png](https://qiita-image-store.s3.amazonaws.com/0/52054/2eda62f8-a0ff-aecb-d266-c5f1ecbcc608.png)

レスポンスがちゃんと返ってきたら、mongoインスタンスにsshで接続して確認。データが保存されてたら成功！

![18.png](https://qiita-image-store.s3.amazonaws.com/0/52054/55ba68e2-05ce-07b0-7685-0c59b44a962a.png)

## 注意点
今回はとりあえず動かしてみた、というレベルなので実運用の時には気をつけること。

* mongoインスタンスにしているEC2は何かの拍子にリブートすると真っさらになります。mongoをインストール/設定した段階で、AMI(イメージ)を作成し、リブート後もそのイメージから再生できるようにしましょう。
* 同様に、mongoDBのデータも消えるので実際はS3とかに保存するか定期バックアップを取るべき。
* mongoインスタンスのSecurityGroupの設定でIPをすべて許可しているので、これはアプリケーションインスタンスからに限定する。ELB(ロードバランサ)のIPにしたらたぶんOK
* デフォルトではmongoのUserName/Passwordが設定されていないので設定しましょう。