NLBを利用してRDSの負荷分散を行う。

# はじめに
マスターとなるRDSの負荷が上がってきたら、まずはリードレプリカを作成して分散すると思います。
大抵の場合はリードアクセスによる負荷が高くなるので、そのリードレプリカでも捌くのが難しくなるようであればもう一台増やす必要があるでしょう。
その場合、RDSだとリードレプリカごとにエンドポイントができてしまいます。
ですがNLBでリードレプリカを束ねることで、１つのエンドポイントで負荷分散が行えます。


# 前提
今回は以下の図のような構成を作成します。

![サーバーレス.png](https://qiita-image-store.s3.amazonaws.com/0/82090/f23abd2d-150b-a127-de6f-11af1dba6386.png)

また、前提としてEC2インスタンスとRDS2台は用意した状態で始めます。


# NLBの作成
## ターゲットグループの作成
まずはターゲットグループを作成します。
「**EC2 > ロードバンランシグ > ターゲットグループ**」 から **ターゲットの作成** を行います。

![スクリーンショット 2018-02-22 15.33.13.png](https://qiita-image-store.s3.amazonaws.com/0/82090/8be6e29c-3ea1-03c1-7983-d3638db81ee4.png)

ここでのポイントは 「**ターゲットの種類**」 を **ip** にすることです。
というのも、インスタンスにしてしまうとターゲットの追加がEC2しかできないからです。

作成したら次はターゲットの追加です。

# ターゲットの追加
まずはRDSのエンドポイントからIPを調べます。

```bash:IP確認1
$ host koh3i-01.cmhex6vatlc7.ap-northeast-1.rds.amazonaws.com
koh3i-01.cmhex6vatlc7.ap-northeast-1.rds.amazonaws.com has address 10.0.1.114
```

```bash:IP確認2
$ host koh3i-02.cmhex6vatlc7.ap-northeast-1.rds.amazonaws.com
koh3i-02.cmhex6vatlc7.ap-northeast-1.rds.amazonaws.com has address 10.0.2.222
```

IPがわかったら以下のようにターゲットを追加します。

![スクリーンショット 2018-02-22 16.19.00.png](https://qiita-image-store.s3.amazonaws.com/0/82090/a06d76bf-1e59-ed6d-75af-65fa976ee650.png)


## ロードバランサーの作成

- ロードバランサーの種類の選択

「**EC2 > ロードバンランシグ > ロードバランサー**」 から **ロードバランサーの作成** をクリックして **Network Load Balancer** を作成します。

![スクリーンショット 2018-02-22 16.19.29.png](https://qiita-image-store.s3.amazonaws.com/0/82090/ff8551cc-aebe-19b0-fa49-49c5c7668c41.png)

### ステップ１：ロードバランサーの設定

![スクリーンショット 2018-02-22 16.20.13.png](https://qiita-image-store.s3.amazonaws.com/0/82090/11ebfb76-1cfc-c668-4f0f-cb73c24de902.png)

RDSの負荷分散なので内部トラフィックしかないため **スキーマ** を **内部** にします。

![スクリーンショット 2018-02-22 16.20.36.png](https://qiita-image-store.s3.amazonaws.com/0/82090/b394d599-74b7-e713-84b1-cec17705131f.png)

設定が終わってしばらくすると_　healthy_　になるはずです。

![スクリーンショット 2018-02-22 16.28.24.png](https://qiita-image-store.s3.amazonaws.com/0/82090/1ebc7894-e44f-f555-6c83-e062469dd9bc.png)

そうしたら登録完了です。
もし、_healthy_にならない場合はセキュリティグループを確認してみてください。
RDSに付与されているセキュリティグループで、NLBが利用しているサブネットからのアクセス許可が入っていないはずです。


# max_connect_errorsの設定
「**Amazon RDS > パラメータグループ**」 からRDSで利用しているパラメータグループを選択し、 「**パラメータグループアクション**」 の **編集** を行います。

- 変更内容

```
max_connect_errors の値を 18446744073709547520 へ変更。
```

このパラメータは再起動不要なので設定したらすぐに反映されます。


# 接続確認
それでは接続してみます。

```bash:mysql
$ mysql -hNLB4RDS-a3b3aefb0002a0e2.elb.ap-northeast-1.amazonaws.com -uroot -phogehogehoge
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2249
Server version: 5.6.37 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, 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> 
```

無事接続できました。


また、もし `max_connect_errors` の設定を行なっていないと、

```bash:error
$ mysql -hNLB4RDS-a3b3aefb0002a0e2.elb.ap-northeast-1.amazonaws.com -uroot -phogehogehoge
ERROR 1129 (HY000): Host '10.0.2.59' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
```

となり、接続がブロックされてしまいます。
これはNLBが行うヘルスチェックが原因でRDS側は不正接続されていると判断してしまうからです。


# ポイント
今回のポイントはセキュリティグループとパラメータグループです。
1.セキュリティグループの設定でNLBからRDSに対しヘルスチェックができるようにすること。
2.パラメータグループの設定でヘルスチェックのアクセスによってブロックされないように`max_connect_errors`を調整すること。


# おわりに
このソリューションによってリード負荷を「RDSを並べることで軽減」することができるようになりました。
でも、可能であればAuroraを使う方が良いとは思います。