RDS Proxyの挙動検証（lambda → RDS Proxy → RDS)

AWS RDS Proxyがどのように挙動するのかを検証する。
主にDB接続数まわり。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy.html

# 検証環境
## 検証用処理
- `s3:ObjectCreated`のイベント発生をトリガに、lambda起動→RDS通信(特定カラムのupdate) という処理で検証する。([検証用lambda](https://github.com/tatsukoni-pra/lambda-rds-test))
- トリガとなるバケットパスにファイルを100個まとめてアップロードし、lambda関数を100個起動 → RDS接続を100個発生させる。

## 検証用RDS
- エンジンバージョン: `Aurora MySQL 5.7`
- DBインスタンスサイズ: `db.t2.small`(DB最大同時接続数は45)

# 検証
## RDS Proxy未使用時（lambda → RDS直接続）
処理前は以下の感じ。

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 5     |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 10    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

lambda100個起動させると

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 5     |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 110   |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

単純なDB疎通処理だったので(処理時間が短すぎて)現在のDB接続数は見れなかったが、累積でのDB接続数はlambda起動分だけ増えていることから、都度DB接続が作成されていることがわかる。
lambda起動(100回)を2, 3と繰り返していくと、その分だけ累積DB接続数が増加していく。

```
MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 310   |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

前述したように1つのDB疎通時間が短すぎるので、メトリクス上では同時接続数の目立った増加は見られない。
(1つ続いている接続は、踏み台経由でDBアクセスしているもの)
![スクリーンショット 2022-01-12 18.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/3c8da6bf-772d-bdf5-1efb-20ad1989bde5.png)


## RDS Proxy使用時 検証1: 1回の実行
プロキシ設定

|項目 |設定値 |
|---|---|
|エンジンの互換性 |MySQL |
|Transport Layer Security |有効でない |
|認証 |Secrets Managerを使用 |

ターゲット設定

|項目 |説明 |設定値 |
|---|---|---|
|idle_client_timeout(s) |アイドルクライアントの接続タイムアウト |1800 |
|connection_borrow_timeout(s) |接続借用タイムアウト |120 |
|max_connections_percent(%) |接続プールの最大接続数 |50 |
|max_idle_connections_percent(%) |接続プール内のアイドル状態のデータベース接続切断の制御(※後述) |10 |

処理前は以下の感じ

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 7     |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 11    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

RDSのみ使用時と比べて初期のDB接続数が2個多いのは、RDS Proxy経由の接続が貼られているから。

```
MySQL [local]> SHOW PROCESSLIST;
+----+---------------+------------------+-------+---------+------+----------+------------------+
| Id | User          | Host             | db    | Command | Time | State    | Info             |
+----+---------------+------------------+-------+---------+------+----------+------------------+
|  4 | rdsproxyadmin | Subnet IP: Port  | NULL  | Sleep   |    1 | NULL     | NULL             |
|  6 | rdsproxyadmin | Subnet IP: Port  | NULL  | Sleep   |    1 | NULL     | NULL             |
| ...他プロセス...
+----+---------------+------------------+-------+---------+------+----------+------------------+
7 rows in set (0.00 sec)
```

lambdaを100個起動すると

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 13    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 17    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

DB接続は6つ貼られた。
lambda処理が全て完了しても、接続は継続して貼られている。
7分ほど経過させると

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 11    |
+-------------------+-------+
1 row in set (0.00 sec)
```

2接続減った。
そのまま、アイドルクライアントの接続タイムアウトとして設定している30分を経過させたが、DB接続数は変わらず11で残っていた。
![スクリーンショット 2022-01-12 20.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/8b8b666b-8b9d-9c68-b38c-bb7b0bdaf308.png)

周辺の時間帯で、メモリ・CPUで大きな変動は見られない。
![スクリーンショット 2022-01-12 20.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/f309d494-7c32-6e90-05ac-a8c1832d9432.png)
![スクリーンショット 2022-01-12 20.16.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/64abf431-e712-177b-561e-0787d6a40364.png)

また、ピン留めも(メトリクス上では)見られない。
![スクリーンショット 2022-01-12 20.22.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/a652cd2c-be71-3cb8-4f29-093dce274b63.png)

## RDS Proxy使用時 検証2: 複数回の検証
検証1終了状態から、lambdaの100個起動をおよそ1分の間隔を開けて、計10回繰り返す。
検証1時点では、lambda100回起動でDB接続が6つ増え、そのうち4つは接続が残り続けている。
また、RDS Proxy > RDSの方向で使用できるDB接続数は、

`45 / 2 := 23`

つまり、4接続ずつ増え続けると考えれば、5回目で`20接続 + 検証1で残っている4接続 = 24接続`に達するから、接続不能に陥るはずである。
その辺りも含め検証する。

<strong>1回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 12    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 18    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>2回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 12    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 18    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>3回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 18    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 24    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>4回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 22    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 28    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>5回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 22    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 31    |
+-----------------------------------+-------+
7 rows in set (0.01 sec)
```

処理上でのDB接続はできている。

<strong>6回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 17    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 32    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>7回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 19    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 34    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>8回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 20    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 36    |
+-----------------------------------+-------+
7 rows in set (0.01 sec)
```

<strong>9回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 20    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 38    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

<strong>10回目

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 20    |
+-------------------+-------+
1 row in set (0.01 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 40    |
+-----------------------------------+-------+
7 rows in set (0.01 sec)
```

<strong>結果</strong>
使用上限に達してDB疎通不可能になるタイミングはなく、全ての時点において、lambdaから実施されるDB処理は成功していた。
また、10回目の実行から5分ほど経過すると、検証1時点のDB接続数である11まで戻った。
以降は検証1と同じく、接続数11で維持されていた。
![スクリーンショット 2022-01-12 21.11.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/b7c4c017-feba-075c-2ba3-e74d87c8df2e.png)

メモリ・CPUに大きな変動は見られない。
![スクリーンショット 2022-01-12 21.12.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/b4e73ec5-76cf-a7f5-33ed-88ed878c9d2a.png)
![スクリーンショット 2022-01-12 21.13.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/c131a011-89d2-55e6-fe89-2f5e1963057e.png)

ピン留めの発生も見られない。
![スクリーンショット 2022-01-12 21.14.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/40a5e54a-8880-d6a2-e338-3e60119b211a.png)

検証2を経て、以下2つの不明点がある。

- 接続数11以降の、DB接続数の上がり方と、元に戻る時間間隔
- RDS Proxyで使用できる最大接続数に達したのちの挙動

後続で検証していく。

## RDS Proxy使用時 検証3: DB接続数上がり幅と、元に戻る時間間隔

DB接続数上がり幅と、元に戻る時間間隔を調べる。
検証2終了時の、DB接続数11の地点からlambdaを100個起動する。

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 13    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 42    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

DB接続数の増加数は2。
そして6分ほど経過すると、元の接続数に戻った。
何度か繰り返してみる。

|項目 |1回目 |2回目 |3回目 |4回目| 5回目
|---|---|---|---|---|---
|DB接続数増加数 |2 |1 |2 |3 |2
|元に戻る時間(分) |6 |6 |7 |6 |5

![スクリーンショット 2022-01-12 22.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/d4c69469-65c6-203a-f426-8668842cab63.png)

本検証の設定値だと、lambda100個起動につきDB接続は2ほど増加。また6分ほどで元の接続数に戻ることが分かった。
この辺の数値については、lambda起動個数によっても違ってくるのだろう。

## RDS Proxy使用時 検証4: RDS Proxyで使用できる最大接続数に達したのちの挙動

上述しているように、RDS Proxyで使用できる最大DB接続数については、`max_connections_percent`を50%で設定しているので、以下式で計算ができる。

`45 / 2 := 23`

検証4では、lambda関数を連続して起動することでDB接続を多数発生させ、使用できる最大DB接続数に達した後の挙動(正常疎通できるのかどうか)を検証する。
lambda300個起動を, 間隔を開けずに3回実施すると

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 23    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 81    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

ここから100回起動を繰り返すと

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 23    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 84    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 23    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 86    |
+-----------------------------------+-------+
7 rows in set (0.00 sec)
```

DB接続数23 というのが使用できる接続上限のようで、これ以上は増加しなかった。(維持されている)
また接続数が増えるにつれ、増加幅が減少している挙動が見てとれる。
![スクリーンショット 2022-01-13 8.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/96f39f2e-0a83-e90e-9e51-fdeb505fef3f.png)

一方上限に達しても、疎通エラーなどが発生することはなかった。lambda側で発生したエラーもなし。
![スクリーンショット 2022-01-13 8.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/5ba62a6a-e2c2-28b4-09f4-a4e44d2ba2ce.png)

メトリクスについては大きな変動はなし。
![スクリーンショット 2022-01-13 8.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/e74f7bbe-5ddc-50f2-1b6d-3c093900d8b4.png)
![スクリーンショット 2022-01-13 8.39.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/f445a305-9436-6477-9f7f-1a13cc0f9132.png)

## RDS Proxy使用時 検証5: アイドルクライアントの接続タイムアウトの調整
RDS Proxyの設定値「アイドルクライアントの接続タイムアウト」を変更して、挙動を観察してみる。

### アイドルクライアントの接続タイムアウトとは
> アイドル状態のクライアント接続のタイムアウト。プロキシがクライアント接続を閉じるまでに接続がアイドル状態を継続できる時間を選択します。デフォルトは 1,800 秒 (30 分) です。クライアント接続がアイドル状態と見なされるのは、前のリクエストの完了後、新しいリクエストが指定時間内にアプリケーションから送信されない場合です。基となるデータベース接続は開いたままで、接続プールに返されるため、新しいクライアント接続で再利用できます。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy-setup.html

### アイドルクライアントの接続タイムアウト: 1800sの場合

検証1~4で実施していた設定値。
初期状態からlambdaを100個起動 & 経過観察すると
![スクリーンショット-2022-01-13-9-11-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/0874a313-2c97-41d4-c9d1-0854fcf49d3c.png)

1つの段になっているのは、DBインスタンスに対して踏み台経由で接続していた分。
検証3実施内容と同様に、6~7分ほどで接続数が元に戻っている。
メトリクス上では、元に戻った後接続数6が維持されているが、これは
![スクリーンショット 2022-01-13 9.13.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/416d3981-1ca6-6573-2a17-1c0e663daab1.png)

のように、DB接続せず放置しても残っているので、RDS Proxyが初期状態で作成している接続だと思われる。

### アイドルクライアントの接続タイムアウト: 120sの場合
次に、アイドルクライアントの接続タイムアウトを120s(= 2分)に設定して、同様の挙動を検証する。
![スクリーンショット 2022-01-13 9.50.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/dfd2e0ff-016d-1db4-2b23-d8170102f938.png)

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 13    |
+-------------------+-------+
1 row in set (0.00 sec)
```

![スクリーンショット 2022-01-13 10.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/2fce92f8-f7ce-3be2-9d32-f4beaa7ee76c.png)

元の接続数に戻る時間間隔は、踏み台経由の接続を除くと5分ほど。
また、DB接続数の増加幅も大きく変化はなかった。
何度か繰り返して実施すると、

|項目 |1回目 |2回目 |3回目 |4回目| 5回目
|---|---|---|---|---|---
|DB接続数増加数 |3 |1 |3 |1 |4
|元に戻る時間(分) |5 |5 |6 |6 |5

![スクリーンショット 2022-01-13 12.46.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/52c0a340-e85a-852c-f55a-091f412b5123.png)

DB接続増加数の幅が若干大きく(不規則に)なったのと、元に戻る時間がやや短くなったようにも見えるが、今回の検証条件では際立った違いは見えなかった。
アイドルクライアントの接続タイムアウトを2分に設定していると、接続数が元に戻る時間も2分になるのかと思ったが、直で関連しているわけでもなさそう。

各種メトリクスについても大きな変動はない。
![スクリーンショット 2022-01-13 12.50.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/c2cd7460-7817-36ff-ad88-a5eb2045baa6.png)
![スクリーンショット 2022-01-13 12.50.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/60500dce-40ef-986b-fbcc-a6dc86590219.png)
![スクリーンショット 2022-01-13 12.51.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/e2d9b19c-0d17-a50e-956c-3b3377dac80f.png)

## RDS Proxy使用時 検証6: MaxIdleConnectionsPercentの調整
RDS Proxyの設定値「MaxIdleConnectionsPercent」を変更して、挙動を観察してみる。
※ マネージドコンソールからは設定できないので、CLIかAPIなどで設定する必要がある。本検証ではterraformの[aws_db_proxy_default_target_group.max_idle_connections_percent](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group)から設定している。
※ その他設定値は、検証用設定値状態。

### MaxIdleConnectionsPercentとは
> 接続プール内のアイドル状態のデータベース接続をどのようにプロキシが切断するのかを制御できます。この設定では、AWS CLI や API の DBProxyTargetGroup の MaxIdleConnectionsPercent パラメータを使用します。値を大きくすると、プロキシではアイドル状態のデータベース接続の大部分を開いたままにします。値を小さくすると、プロキシではアイドル状態のデータベース接続の大部分を閉じます。Aurora MySQL では、ターゲットグループが使用する RDS DB インスタンスまたは Aurora DB クラスターの max_connections 設定に対するパーセンテージで表されます。デフォルト値は 50% です。MaxIdleConnectionsPercent の値を変更するには、CLI コマンド modify-db-proxy-target-group または API 操作 ModifyDBProxyTargetGroup を使用します。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy-managing.html

### MaxIdleConnectionsPercent: 10%の場合
検証1~4で実施した挙動。

### MaxIdleConnectionsPercent: 50%の場合
lambdaを100個起動すると

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 15    |
+-------------------+-------+
1 row in set (0.00 sec)
```

![スクリーンショット 2022-01-13 14.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/8a2209fd-f025-4d51-1041-8506433434d7.png)

1時間近く接続数が維持されている。
この状態から、lambda起動を繰り返し実施してみる。

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 18    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 19    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 20    |
+-------------------+-------+
1 row in set (0.01 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 21    |
+-------------------+-------+
1 row in set (0.00 sec)
```

DB接続は増加し続け、かつ維持されている。
![スクリーンショット 2022-01-13 15.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/a235d4a8-6589-44b4-57d9-38b9a167ece3.png)

そして接続数23まで増加した後は、DB接続数が増加しなくなる。
（lambdaからのDB疎通は正常に挙動している）
「`値を大きくすると、プロキシではアイドル状態のデータベース接続の大部分を開いたままにします。`」ということなので、アイドル状態の接続が開かれたままになっているのだと考えられる。

他メトリクス(メモリ, CPU)については、大きな変動が見られず他検証と大差ないので割愛。

### MaxIdleConnectionsPercent: 30%の場合
接続数が元に戻る部分を観測できなかったので、少し値を変えて検証。

```
MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 13    |
+-------------------+-------+
1 row in set (0.00 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 16    |
+-------------------+-------+
1 row in set (0.01 sec)

MySQL> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 18    |
+-------------------+-------+
1 row in set (0.00 sec)
```

と接続数が上昇していき、接続数19で維持される挙動をした。
その後は、DB接続増加幅は3くらい, 元の接続数に戻る時間は6分ほどで、他と大差ない。
![スクリーンショット 2022-01-13 17.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351743/2d90bc1d-5ddb-7cdf-4f1a-01f26659c945.png)

他メトリクス(メモリ, CPU)については、大きな変動が見られず他検証と大差ないので割愛。

# まとめ
- RDS Proxyを用いることで、DB接続数を節約できることがわかった。
- ただしその分、一定数の接続は残り続ける（接続プールを形成している）
- アイドルクライアントの接続タイムアウト設定による挙動の違いは、本検証条件では確認できなかった
- MaxIdleConnectionsPercent設定値については、設定された数値(%)が小さいほど、残り続けるDB接続数が少なくなった。（それ以外の明確な挙動の違いは本検証では観測できず。設定された数値が大きいほど、都度つどのDB接続の増加数は少なくなっているようには見える）

DBインスタンスサイズによって、より明確な挙動差が出ると思うので、追って検証する。