MySQL: Heroku ClearDB と AWS RDS どちらにすべきか

Heroku でアプリをデプロイする場合、デフォルトのデータベースは PostgreSQL ですが、**MySQL を使うこともできます。**

MySQL の一般的な導入方法は次の2つです:

1. Heroku アドオンの [ClearDB](https://elements.heroku.com/addons/cleardb) を利用する
（導入手順は[こちら](https://devcenter.heroku.com/articles/cleardb)）
1. Amazon RDS MySQL を利用する（参考記事は[こちら](https://stackoverflow.com/questions/35247347/point-heroku-application-to-aws-rds-database)）

Heroku で MySQL を使う場合、これら2つのうち、どちらを採用すべきか検討してみました。

# 検討の前提

* 新規開発のDBとして利用
* 初めは少人数開発・低予算
* 求められるストレージ容量はそこまで大きくない（はず）
* 将来的に拡張する可能性有

# 結論

結論から言うと、**今回は Amazon RDS を使うことにしました。**

その理由は、ざっと次のとおりです。

* 将来的にウェブサーバを Heroku で運用し続けるか未定
* 容量が1GBを超えた場合に固定料金を49.99ドルも払いたくない
* 設定は必要だが、それなりの作業量で導入可能

詳細は以下の「Heroku ClearDB と Amazon RDS の比較」をご参照ください。

# Heroku ClearDB と Amazon RDS の比較

次の４点について比較検討します。

* 導入コスト
* ランニングコスト
* セキュリティ
* 拡張性

## 導入コスト

Heroku アプリに導入するためのコストを検討します。

### ClearDB

Heroku のアドオンなので、コマンド1つで導入できます。

### RDS

[参考記事](https://stackoverflow.com/questions/35247347/point-heroku-application-to-aws-rds-database)にある通り、Heroku から RDS に接続するための設定が必要です。設定の全体的な流れは、次の通りです。

1. AWS: CA証明書のダウンロード
1. RDS: `REQIRE SSL` の設定
1. AWS: セキュリティーグループの調整
1. Heroku: `DATABASE_URL` の設定

## ランニングコスト

月々の利用料金について検討します。

### ストレージ容量の調べ方

MySQLでのストレージ容量の調べ方は[こちらの記事](https://qiita.com/ikenji/items/b868877492fee60d85ce)をご参照ください。

既存プロジェクトのストレージ容量は、新規プロジェクトの見積もり時に参考になります。

### ClearDB

プランごとの固定料金が課金されます。

[料金ページ](https://elements.heroku.com/addons/cleardb)

無料プランの Ignite だと容量が5MBしかないので、**Punch (1GB, 月$9.99)ぐらいから利用することになりそうです。**

Punch の次のプランは  Drift (5GB, 月$49.99) なので、**容量が1GBを超えた場合、利用料がいきなり40ドル/月も上がってしまいます。**

### RDS

DBサーバの稼働時間とストレージ容量、バックアップなどについて、利用した分だけ課金されます。従量課金なので「損」はありませんが、ClearDB の固定料金と比較すると少し分かりづらいです。

[料金ページ](https://aws.amazon.com/jp/rds/mysql/pricing/)

稼働時間単価は、DBサーバのスペックごとに異なります。

最安の「db.t3.micro」の場合、時間単価は「$0.017」なので（シングルAZ・**バージニア北部**）、**月ごとの稼働料金は最低でも12.65ドルかかります。**

*※ バージニア北部を選んでいるのは、Heroku-RDS 間のレイテンシーを最小限にするため。*

これに加えて、ストレージ料金「毎月 0.138USD/GB」やデータ転送などのコストも発生しますが、ざっくり見積もっても**「月15-30ドル」では利用できるでしょう。**

## セキュリティ

データベースのセキュリティ面について検討します。

### ClearDB

手元で確認したところ、発行される CLEARDB_DATABASE_URL の情報で、**どのIPからでもデータベースにリモート接続できます。**

また**デフォルトではSSL接続していない**ので、必要な場合は自分で証明書の設定をしなくてはいけません（詳細は[こちら](https://devcenter.heroku.com/articles/cleardb#using-ssl-with-cleardb-and-rails)）。

### RDS

Heroku から RDS に接続する場合、その RDS が属する VPC の**アクセスIP制限を一部開かないといけません。**

[Herokuの記事](https://devcenter.heroku.com/articles/amazon-rds) では、すべてのIPを許可する `0.0.0.0/0` が例示されています。この設定だと、ClearDB のデフォルトと同様、どのIPからでもデータベースにリモート接続できます。

アクセスできるIPは制限した方が望ましいですが、そのためには Heroku のアドオン（[Fixie](https://elements.heroku.com/addons/fixie) など）でアプリ側のIPアドレスを固定しないといけなさそうです。この場合、リクエスト数に応じてアドオンの課金が発生します。

なのでコストを抑えたいなら、ClearDB と同じようにすべてのIPを許可するしかないです。（最低限、ユーザ名・パスワードは複雑なものにしましょう。）

なお、SSL接続については、Heroku から RDS に接続する場合は必須です。

## 拡張性

データベースやサービスの拡張性を検討します。

### ClearDB

スペック・容量に応じたプランが用意されているので、サービスの拡大に伴いアップグレードしていけます。

ただし Heroku のアドオンなので、Heroku アプリと合わせて使っていくことになるでしょう。（Heroku 以外のサーバで利用できるかは不明です。）

したがって、AWSなどの他サービスへの移行は、DBのせいでフットワークが重たくなってしまう可能性があります。

### RDS

こちらもサービスの拡大に伴い、スペックをアップグレードしていけます。

ClearDB と比較すると、Heroku 以外のサービスとの連携など、柔軟性はより高いでしょう。

# まとめ

|               |    Heroku   ClearDB    |   Amazon RDS      |
|:--------------|:-----------------------|:------------------|
| 導入コスト     |         1コマンドのみ　   |      設定が必要   |
| ランニングコスト(月)| 9.99-49.99ドル(固定) | 15-30ドル(?)    |
| セキュリティ   | IP制限なし| IP制限可           |
| 拡張性        | Heroku限定              | Heroku以外も可    |

# References

- [ClearDB MySQL](https://devcenter.heroku.com/articles/cleardb)
- [Amazon RDS for MySQL](https://aws.amazon.com/jp/rds/mysql)
- [AWSで動いているサービスをHerokuに移行した話](https://engineer.crowdworks.jp/entry/2017/08/03/111813)
- [Point Heroku application to AWS RDS database](https://stackoverflow.com/questions/35247347/point-heroku-application-to-aws-rds-database)