[WIP] 3. Javaで開発したWebアプリケーションの実行環境をAWSに構築する(RDS)

# 概要

Java(Spring-Bootを使用)で開発するWebアプリケーションの実行環境をAWS上に構築した作業内容のまとめです。
この記事は[Javaで開発したWebアプリケーションの実行環境をAWSに構築する(EC2初期設定)] (http://qiita.com/rubytomato@github/items/42d490de16b5f5eb9f07)からの続きになります。この記事では「RDS」を書きました。

* 1. [Javaで開発したWebアプリケーションの実行環境をAWSに構築する(VPC&EC2作成)] (http://qiita.com/rubytomato@github/items/329e6c44627d0fa6e3fe)
* 2. [Javaで開発したWebアプリケーションの実行環境をAWSに構築する(EC2初期設定)] (http://qiita.com/rubytomato@github/items/42d490de16b5f5eb9f07)
* 3. Javaで開発したWebアプリケーションの実行環境をAWSに構築する(RDS)
* 4. Javaで開発したWebアプリケーションの実行環境をAWSに構築する(Webアプリケーションのbuild&deploy) (未)

**参考**

* [Amazon Relational Database Service (Amazon RDS) とは?] (https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Welcome.html)
* [Amazon RDS での MySQL] (https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_MySQL.html)
* [MySQL データベースログファイル] (https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_LogAccess.Concepts.MySQL.html)
* [付録: MySQL に関連する一般的な DBA タスク] (https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.MySQL.CommonDBATasks.html)
* [Route 53のPrivate DNS対応を試してみた] (http://dev.classmethod.jp/cloud/aws/route53-private-dns/)
* [Amazon RDS における MySQL 5.6 のパラメータ設計例] (http://bekkou68.hatenablog.com/entry/2014/09/16/200122)


## RDSの構築手順

* サブネットの作成
 * Privateサブネット(1a)の作成
     * ルートテーブルの作成
     * ルートテーブルの付け替え
 * Privateサブネット(1c)の作成
     * ルートテーブルの付け替え
* サブネットグループの作成
* パラメータグループの作成
* VPCセキュリティグループの作成
* RDSインスタンスの作成


### サブネットの作成

まずはRDS用のサブネットから作成します。
RDSインスタンスを作成するには2つ以上のAZが異なるサブネットが必要です。

#### Privateサブネット(1a)の作成

AZ 1aのPrivateサブネットを作成します。
CIDRブロックは`10.0.3.0/24`としました。

![50-private-subnet-rds-01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/59bdbe00-62f8-cafc-7a88-480ba8344562.png)

##### ルートテーブルの作成

上記で作成したPrivateサブネットのルートテーブルを作成します。このルートテーブルはこの後に作成するもう1つのPrivateサブネットでも使用します。
VPC内からのアクセスだけなのでルートの追加は行いません。

![51-private-subnet-rds-rtb-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/881e105e-17b5-5ea4-c86b-1cb94db1e1f3.png)

##### ルートテーブルの付け替え

上記で作成したルートテーブルで、Privateサブネットのデフォルトのルートテーブルと付け替えます。

![52-private-subnet-rds-rtb-03.png](https://qiita-image-store.s3.amazonaws.com/0/22772/dc8e90e9-bcff-54a8-f93e-c2a24e3954f4.png)


#### Privateサブネット(1c)の作成

AZ 1cのPrivateサブネットを作成します。
CIDRブロックは`10.0.4.0/24`としました。

![53-private-subnet-rds-01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/f53c97b4-a6d9-b3b9-d380-041de5632403.png)

##### ルートテーブルの付け替え

上記で作成したルートテーブルで、Privateサブネットのデフォルトのルートテーブルと付け替えます。

![54-private-subnet-rds-rtb-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/25e7bcd1-6554-3973-3215-f1077822bdf0.png)


### サブネットグループの作成

上記で作成した2つのサブネットで構成するサブネットグループを作成します。

![55-subnet-group-rds-01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/a84f9bc6-e912-fea2-daa6-a1ae6720a980.png)

![56-subnet-group-rds-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/25a5cd5c-23ba-6853-a4b0-ed21f5535f35.png)


### パラメータグループの作成

![57-subnet-group-rds-param-01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/146b37d0-3997-7d64-7ddb-54d99ada569c.png)

![58-subnet-group-rds-param-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/6356ecb7-04ab-c989-bcdc-43532b987a64.png)

**文字コード関連**

utf8mb4で設定しました。

![59-subnet-group-rds-param-03.png](https://qiita-image-store.s3.amazonaws.com/0/22772/0d7ed3c7-0cca-3138-9082-dcc2676f86f2.png)

**time_zone**

![60-subnet-group-rds-param-04.png](https://qiita-image-store.s3.amazonaws.com/0/22772/f8f14ba0-34a2-d136-01d2-37d54f9a5a93.png)

**general_log**

有効にしました。

![rds-pg-02-general.png](https://qiita-image-store.s3.amazonaws.com/0/22772/c8be4ada-a41b-8e37-49f8-f8d44dd4321c.png)

**slow_log**

有効にしました。

![rds-pg-04-slow.png](https://qiita-image-store.s3.amazonaws.com/0/22772/f6e50ee3-43da-3a17-f3cc-57b7bdf5ec39.png)

![rds-pg-03-long_query_time.png](https://qiita-image-store.s3.amazonaws.com/0/22772/e3a69449-201e-a409-d693-8be20817843a.png)

**performance_schema**

有効にしました。

![rds-pg-01-performance.png](https://qiita-image-store.s3.amazonaws.com/0/22772/91b5d36f-86ad-b30c-8389-8df3c515c94b.png)


### VPCセキュリティグループの作成

![61-rds-sg-01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/8544f709-5008-d539-6f86-c8c7098d3825.png)

送信元に2つのセキュリティグループを指定します。これでこのセキュリティグループに属するEC2インスタンスからの接続が可能になります。
実際にRDSと接続するのはWebアプリケーションだけなので、ルールは1つだけでいいのですが開発の便宜上両方のEC2インスタンスから接続できるように設定しました。

* sg-5625a032 : Webアプリケーションを実行するEC2インスタンスが属するセキュリティグループ
* sg-961c99f2 : nginxを実行するEC2インスタンスが属するセキュリティグループ

![62-rds-sg-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/5deace10-70e2-ab44-3302-e3949bf324dc.png)

* [Amazon RDS セキュリティグループ] (http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Overview.RDSSecurityGroups.html)

> セキュリティグループにより DB インスタンスに対する送受信トラフィックへのアクセスを制御します。
> Amazon RDS では、DB セキュリティグループ、VPC セキュリティグループ、EC2 セキュリティグループという 3 種類のセキュリティグループを使用します。簡単に説明すると、DB セキュリティグループは VPC の外にある DB インスタンスへのアクセスを制御します。VPC セキュリティグループは VPC 内の DB インスタンス（または他の AWS インスタンス）へのアクセスを制御します。EC2 セキュリティグループは EC2 インスタンスへのアクセスを制御します。


### RDSインスタンスの作成

エンジンには`MySQL`を選択しました。

![64-rds-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/271e6fde-7aa7-3595-33f2-00833d68e78a.png)

開発用なので、右側の`開発/テスト`を選択しました。

![65-rds-03.png](https://qiita-image-store.s3.amazonaws.com/0/22772/ae43315d-cfa3-ec51-5f80-673095e97b8c.png)

開発用?だからだと思いますが、マルチAZ配置は選べませんでした。

![66-rds-04.png](https://qiita-image-store.s3.amazonaws.com/0/22772/7b0a54b5-30e3-47a7-d064-08655475c6bd.png)

サブネットグループ、VPCセキュリティグループ、パラメータグループには上記で作成した設定を指定します。
オプショングループは特に設定するものが無いのでデフォルトを指定しました。

![67-rds-05.png](https://qiita-image-store.s3.amazonaws.com/0/22772/0c2f104a-9082-9d5b-6ceb-0168fa25e369.png)

* [オプショングループを使用する] (http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_WorkingWithOptionGroups.html)

> DB エンジンによっては、データとデータベースの管理を容易にしたり、データベースのセキュリティを強化したりするための、追加の機能が用意されている場合があります。Amazon RDS では、オプショングループを使用してこれらの機能を有効にして設定します。

RDSインスタンスの作成直後の状態です。

![69-rds-07.png](https://qiita-image-store.s3.amazonaws.com/0/22772/e8d9fc4f-6000-41f7-a2a0-79d2e40c1e2e.png)


#### EC2インスタンスからの接続確認

EC2インスタンスにインストールしたMySQL Clientより接続できるか確認します。

```bash
[ec2-user@ip-10-0-1-196 ~]$ mysql -h my-rds-20160503.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -uroot -p mydb
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 305
Server version: 5.6.27-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```


## RDS Tips

### エンドポイントに別名(Alias)を付ける

Route53のPrivate DNSでRDSのエンドポイントに別名を付けることができ、この別名を使ってRDSへ接続することができます。

![71-route53-02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/10302139-c88a-ecdc-f1eb-2024edaf8e97.png)

Type:に、`Private Hosted Zone ...`を選択します。

![72-route53-03.png](https://qiita-image-store.s3.amazonaws.com/0/22772/d9b3928a-d14b-b2cc-7621-ee0a0ce1df21.png)

![73-route53-04.png](https://qiita-image-store.s3.amazonaws.com/0/22772/22eedbff-74c0-c912-615a-2940ab14f8e8.png)

Value:に、RDSのエンドポイントを入力します。
Name:に、別名を入力します。

![74-route53-05.png](https://qiita-image-store.s3.amazonaws.com/0/22772/13efaaab-7a62-181f-8e1f-e49727b35403.png)


別名を使って接続してみます。

```bash
$ mysql -h db01.rds.local -uroot -p mydb
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 368
Server version: 5.6.27-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

* [Route 53のPrivate DNS対応を試してみた] (http://dev.classmethod.jp/cloud/aws/route53-private-dns/)



### MySQLキャッシュウォーミング

http://aws.typepad.com/aws_japan/2014/09/rds-mysql-cache-warming.html

> 本日、InnoDBのキャッシュウォーミングをサポートすることで、Amazon RDS for MySQLを強化いたしました。 MySQLを実行しているAmazon RDSのDBインスタンスをシャットダウンする際、バッファープールの状態を保存し、後でインスタンスを起動する際に、リロードするよう設定することができます。 インスタンスはウォームアップを必要とせずに、効率的な方法で、一般的なクエリを処理できるようになります。

```
mysql> show global variables like '%buffer_pool%';
+-------------------------------------+----------------+
| Variable_name                       | Value          |
+-------------------------------------+----------------+
| innodb_buffer_pool_dump_at_shutdown | OFF            |
| innodb_buffer_pool_dump_now         | OFF            |
| innodb_buffer_pool_filename         | ib_buffer_pool |
| innodb_buffer_pool_instances        | 8              |
| innodb_buffer_pool_load_abort       | OFF            |
| innodb_buffer_pool_load_at_startup  | OFF            |
| innodb_buffer_pool_load_now         | OFF            |
| innodb_buffer_pool_size             | 625999872      |
+-------------------------------------+----------------+
8 rows in set (0.00 sec)
```

* [Amazon RDS のキャッシュウォーミングを有効にしてみました] (http://bekkou68.hatenablog.com/entry/2014/09/12/204909)


## MySQL Workbench

WindowsにインストールしたMySQL WorkbenchからRDSへ接続するにはsshポートフォワーディングを利用する方法があります。
なお、この方法が成立するのは「WindowsからEC2へsshでログインできること」「そのEC2からMySQL ClientでRDSへ接続できること」という条件を満たしている場合です。
下記の2種類の方法で接続確認を行いました。

### plinkを使用する方法

sshクライアントにはPuTTY付属のplinkを使用しました。(PuTTYでも可能です。)

```bat
> plink.exe -ssh -2 -C -N -L 13306:my-rds-20160503.********.ap-northeast-1.rds.amazonaws.com:3306 -i my-aws-keypair-20160503.ppk -P 22 ec2-user@xxx.xxx.xxx.xxx
Using username "ec2-user".
```

* ec2-user@xxx.xxx.xxx.xxxのIPアドレスは、PublicサブネットにあるEC2インスタンスのパブリックIPアドレスです。

#### Windowsのmysqlクライアントから接続

この状態でWindowsにインストールしてあるMySQL Clientから接続できるか確認してみます。
ホスト名には`localhost`、ポートにはポートフォワーディングで指定した13306を使用します。

```bat
> mysql -h localhost -P 13306 -uroot -p mydb
Enter password: **********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.6.27-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

#### WindowsのMySQL Workbenchから接続

MySQL Clientで接続した情報をそのまま使えばMySQL Workbenchから接続することができます。

![workbench_01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/904c607d-bcc0-d931-c8ec-fd7eb02608fa.png)

"Test Connection"ボタンを押して接続できるか確認します。

![workbench_02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/2fdc3009-a68f-838d-f8a2-8fb24f1fac14.png)

MySQL Workbenchのサーバーステータスの画面です。

![workbench_03.png](https://qiita-image-store.s3.amazonaws.com/0/22772/b32ebeda-15cb-d8d8-619e-d9ebd062c74a.png)

* [Amazon VPC 内の RDS(MySQL) に SSH のポートフォワードを利用して接続するメモ] (https://blog.cloudpack.jp/2014/12/16/connect-to-amazon-rds-mysql-in-vpc-with-ssh-portforward/)


### MySQL WorkbenchのStandard TCP/IP over SSHを使用する方法

plink.exeを使用しなくてもMySQL WorkbenchだけでRDSへ接続する方法がありました。

* Connection Method:に`Standard TCP/IP over SSH`を選択
* SSH Hostname:にsshログインするEC2インスタンスのpublic IPと接続ポート(`22`)を入力
* SSH Key File:にプライベートキーファイルを指定
* MySQL Hostname:にRDSのエンドポイントを入力

![workbench_04.png](https://qiita-image-store.s3.amazonaws.com/0/22772/48e27912-0280-c50e-11a6-6c8f23d407a3.png)

"Test Connection"ボタンを押して接続できるか確認します。

![workbench_05.png](https://qiita-image-store.s3.amazonaws.com/0/22772/21568139-d9fd-c640-4837-52e5c8a1931a.png)