【手順と注意点】 AWSインスタンスサイズを下げ２台構成にし、稼働率とコスパを上げた

#サービスリリース時に立てた巨大なサイズのインスタンスの見直しをする
###現状立っているインスタンス
| 項目 |  m4.xlarge  |
| --------------- | --------------- |
| メモリ| 16G |
| CPU| 400％（4基） |
| network | 高い（と書いてある） |

###変更したいインスタンス(2台構成)
| 項目 |  t2.medium  |
| --------------- | --------------- |
| メモリ| 4G |
| CPU| 200％（2基） |
| network | 低〜中（と書いてある） |

##現状のサーバーリソース状態の確認項目
### Mackerelを用いてリソース使用状況の計測
<a　href="http://qiita.com/rorensu2236/items/30c1bd58a0801ab49f99">mackerelのインストール方法はこちら</a>

| 項目     | 鯖リソース | 使用率 |
| ------- | --------------- |:---------------:|
| CPU     | 400% | 14% |
| メモリ    | 16G | 1G |
| LoadAVE | 4 | 0.4 |


**なんだこれ全然使ってねえ!!**

※Load Averageとは1CPUにおける単位時間あたりの実行待ちとディスクI/O待ちのプロセスの数を示します



* CPU4基構成なので最大で400％まで処理を行うことが可能ですが、現状の最高CPU使用率は14％

* メモリはMackerel上では98％使用していることになっていたので、サーバに入りfreeコマンドを試した。
15Gはバッッファとキャッシュなので、この時点での実際の利用率は低い。
<img src="https://qiita-image-store.s3.amazonaws.com/0/69647/fe5c5cc7-f896-4693-f782-aafe5b90130e.png" width="70%">

* cloudWatchLogsAgentを使用して、計測することでメモリも綺麗に監視できる様です。
参考: http://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html


* loadaverageは1に達することがなく、全ての処理が待たされずに実行できていることがわかる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/69647/94da8aa6-f749-6921-73bf-c001d450f0ba.png" width="70%">

### load　averageの適正値
* 1以下：実行プロセスが待たされることなく実行されている
* 2~3：CPU不足やディスクIO書き込み待ちにより、プロセス実行待ちが起きている
* 3以上：1プロセスあたり2件の処理が実行できていない状態となり、体感値として重いと感じるようになる


##リソース利用率目標値は80％
もっともサーバーのリソースを有効活用できる利用率が**80％〜90％**だと言われていますので、
**無駄に大きい**インスタンスのスペックを下げて、サーバの**負荷を上げ**てコスパを上げたいと思います


| 現状のインスタンス   | 数値 |
| --------------- |:---------------:|
| インスタンスサイズ | m4.xlarge |
| メモリ | 16G |
| CPU | 4コア |
| Net | 750Mbps |


この状態だと非常にリソースが余ってしまうので、AWSインスタンス一覧から下げても大丈夫そうなインスタンスをさがします。

##サーバスペックを下げる際にチェックしたポイント
* インスタンスタイプ
* cpu
* メモリ
* ネットワーク速度


### インスタンスタイプをt2以外からt2へ下げた際の注意事項
```txt:3/31日hiroki_konishiさんよりコメントをいただき追記
インスタンスタイプをt2以外からt2へ下げた際には注意が必要です。
t2タイプでは、CPUクレジットを考慮する必要があります。(40%程度なら、問題なさそうですが。念のため。)
```
参考：http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/t2-instances.html#t2-instances-cpu-credits

### インスタンスのざっくりとした特徴

| インスタンスタイプ   | 特徴         |
| --------------- |:---------------:|
| Tシリーズ | 最小規模でテスト環境用 |
| Mシリーズ | 中規模サイト、DBの運用といった一般的なインスタンス |
| Cシリーズ | CPU、分散処理重視型 |
| Rシリーズ | メモリ最適化 |
| Gシリーズ | グラフィック最適化（GPU強化） |
| Iシリーズ | 並列演算処理 |

参考：https://aws.amazon.com/jp/ec2/instance-types/
またはインスタンスの作成ボタンを押した後のページで詳細な情報を閲覧することができます。

各インスタンスごとに特徴があるのでインスタンスタイプを変更する際はネットワーク速度、cpuの性能などが変わることも考慮したほうが良いとおもわれます。

今回で言うと m4.xlarge と同系統のタイプの m4.large　に変更するのが一番安全な変更になります。

ただ現状サーバのリソース使用状況からは t2.medium まで下げても問題ないと判断しました。


| 項目 |  m4.xlarge  | 使用状況 |
| --------------- | --------------- |:---------------:|
| メモリ| 16G | 1G |
| CPU| 400％（4基） | 14%(1基で十分) |
| network | 高い | 低 |

メモリを4G、CPUは4基構成から1基構成に変更しました。
ネットワーク速度がここで高い〜中に変更され若干気になりますが、そこは　実際の速度をあとで計測してみて判断したいと思います。


| 項目 |  t2.medium  | 使用状況 |
| --------------- | --------------- |:---------------:|
| メモリ| 4G | 1G |
| CPU| 200％（2基） | 14%(1基で十分) |
| network | 低〜中 | 低 |

インスタンスタイプを決めたら実際にスケールダウンする手順に移ります。

#安全なサーバスケールダウン手順
インスタンスタイプを変更する際はサーバを停止する必要があります、そのためその時間をメンテナンス時間としてサービスを止めるか、２つのサーバを立てて一時的にもう片方のサーバに処理を行ってもらう必要があります。

今回はサービスを停止するわけにはいかないので２つのサーバを立ててスケールダウンをする手順で作業を行いました。

OSは既存のサーバと合わせ、ポートの開放をお忘れなく行いましょう。
<img src="https://qiita-image-store.s3.amazonaws.com/0/69647/733a1454-fd69-a87c-ec13-586dda1a4b58.png" height="300px">

* インスタンスタイプを下げたAWSインスタンスを新しく１つ別途作成する
* その新しいインスタンスに本番環境を構築し、旧インスタンスと同じ処理ができるように環境構築、デプロイを行う。
* そのスペックのインスタンスで良いかチェックする（下記に方法記載）
* ELB(イラスティックロードバランサー)の設定に新インスタンスを追加し、新サーバと旧サーバの両方でトラフィックを受ける状態にする
* 旧インスタンスをELBから外してスケールダウン完了

##2台構成で新規サーバを立てる際の注意点

スケールダウンして浮いたコスト分で、逆にスケールアウトする構成にすることで冗長性をもたせることができます。高いサーバ1台よりも安いサーバ2台という戦略です。ただし、複数台構成にすることで気をつけなければいけないポイントがあります。

* 新規にサーバを立てるので既存のサーバとIPアドレスが変わります
* IPアドレスごとに承認されている外部サービスとの連携を確認
* 決済サービス
* GoogleXMLSiteMap
* FeedForce
* 両方のサーバで決済など連携を確認しましょう。

またはNATサーバなど外部に向かうトラフィックを1本化するという手もありますね。

##ApatchBenchによるサーバ負荷テスト
このコマンドを用いることで任意のアドレスに対してアクセスを大量に送ることができます。
サーバースペックを下げた際にどれだけのリクエストに答えらる数が減ったのか、速度が低下したのかを確認することができます。

```bash:合計1000クリエストを同時アクセス数100で送信
ab -n 1000 -b 100 before-server.jp
ab -n 1000 -b 100 after-server.jp
```

```bash:合計2000クリエストを同時アクセス数200で送信
ab -n 2000 -b 200 before-server.jp
ab -n 2000 -b 200 after-server.jp
```

```bash:合計3000クリエストを同時アクセス数300で送信
ab -n 3000 -b 300 before-server.jp
ab -n 3000 -b 300 after-server.jp
```

### ApatchBenchでの性能実験、実行結果
移行した低スペックサーバでの数値

| 項目 |  t2.medium  | 使用状況 | 変更前との差分 |
| --------------- | --------------- |:---------------:|:---------------:|
| メモリ| 4G | 1G | なし |
| CPU| 200％（2基） | 44%(1基で十分) | +30% |
| network | 低〜中 | 低 | なし |


| 項目 |  m4.xlarge  | 使用状況 | 変更前との差分 |
| --------------- | --------------- |:---------------:|:---------------:|
| メモリ| 16G | 1G | なし |
| CPU| 400％（4基） | 14%(1基で十分) | 20%(1基で十分) |
| network | 高い | 低 | なし |


正直数値を見る限りまだまだ余裕でこれ以上下げることも可能。
ただこれ以上下げるとさすがに心配、なおかつコストもあまり変わらないので今回は保留。

リージョン違いのサーバを2基構成にできただけでも稼働率に対してかなり効果があるはず。

# サーバー移行結果
###サーバー移行前

| 項目 |  m4.xlarge  | 使用状況 | 使用率 |
| --------------- | --------------- |:---------------:|:---------------:|
| メモリ| 16G | 1G | 6.25% |
| CPU| 400％（4基） | 14%(1基で十分) | 3.5% |
| network | 高い | 低 | 不明 |

###サーバー移行後(２台の合計値)

| 項目 |  t2.medium  | 使用状況 | 使用率 |
| --------------- | --------------- |:---------------:|:---------------:|
| メモリ| 4G | 2.2G | 55% |
| CPU| 200％ | 10% | 5% |
| network | 低〜中 | 低 | 不明 |

メモリCPUの使用率は上昇しましたが、CPUに関しては全体合わせて10％程度。
移行前との比較ですが4％ほど下がっていて、２台構成にして処理が分散したのかなという印象です。

![image](https://qiita-image-store.s3.amazonaws.com/0/69647/d55304c2-df43-ab0a-d446-12d2eafa59d4.png)

こちらが実際のMackerelで確認したCPUの数値、最大でも5％ほどしか使用されておらず、
実質サーバーを変更しても問題がなかった様に思えます。

むしろこれでもオーバースペックすぎるのでもっと下げても大丈夫なのですが。
一応重要なサーバなので今回はこのサイズで。

個人でサービスを提供するときはもっと低くて良いと思います。


##Tips
### 指定したURLでアクセスした際に、特定のIPに固定で行く様に設定する方法（Route53周りをいじる時に必須）
pcのhostsファイルを開き、ドメイン名とIPアドレスを紐付ける。

```
sudo vim /etc/hosts
```

```
13.293.41.112 www.hoge.net.jp
```
www.hoge.net.jpにアクセスした際にランダムで２つのIPに移動するのがELBの基本的な設定なのですが。

このように記載しておくことでwww.hoge.net.jpに接続した際に13.293.41.112このIPアドレスを強制的に見に行ってくれます。

AmazonのRoute53よりもこちらが優先されて接続されます。