はじめに
Lambda+RDS=RDS Proxy(コネクションプールのため)みたいに考えてしまっていた。
しかし、RDS Proxyの「ピン留め」を考慮すると、RDS Proxyを用いることにメリットはない(no benefits)そうです。
ピン留めとは
複数のDBクライアントが安全にDB接続を共有できない場合、RDSProxyはコネクションプール内のDB接続を特定のDBクライアントに対して固定してしまいます
というもので、ピン留めの発生条件の一つにはPrepared Statementの使用があります。
Prismaは、Prepared Statementを用いているためピン留めを発生させる可能性があるということです。
じゃ、コネクションプールどうするのよ
RDS Proxyを利用しないとなると、「コネクションプールどうするの?」となりますが、実はPrismaがやってくれます。
PrismaClientは、コネクションプールを管理してくれるので、例えば
- 5リクエストくる
- Lambdaはリクエストごとにコンテナを生成
- 1リクエスト1コンテナの場合、5つのPrismaClientがそれぞれコネクションプールを管理することになる
- プールサイズが3の場合は、5×3=15ということになる。
ということです。
そのためリクエストが多くなるとコネクションの上限にすぐ到達してしまう可能性があるため
Start by setting the connection_limit to 1
の通り、サーバレス環境ではプールサイズを1にするように書かれています。
その他、サーバレス環境で考慮するべきこととしては
を参照してください。
また、押さえておくべきこととしてコンテナは
- 再利用される可能性がある
- 一定の時間後に破棄される(この時間を指定することはできません)
ため、
$disconnect()
↑のように、disconnectする必要はない点と、アプリケーション内でPrismaClientは使い回すようにしましょう。
その他
学んだことを置いておきます。
Lambdaは実行時に何が行われているのか
関数を実行する際はコンテナを作っています。必ずしもではないですが、5リクエスト=5コンテナという理屈です。
そして、Lambdaは
- コールドスタート
- Lambda関数実行時に通常より時間がかかること
- ウォームタート
- 起動時間を省略しての実行
のどちらかでスタートする。
コネクションの確認の仕方
まとめ
- 必ずしもLambda+RDS=RDS Proxyではない
- PrismaにはRDS Proxyは必要なく、コネクションプールはPrismaで管理するで基本問題ない
- サーバレス環境ではプールサイズを1にする
- ドキュメントを読む
参考
- https://www.keisuke69.net/entry/2020/09/29/131203
- https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/connection-management
- https://www.keisuke69.net/entry/2017/06/21/121501
- https://qiita.com/snaka/items/b6e7500c96e04c131d9e
- https://libitte.hatenablog.jp/entry/20141202/1417452564
- https://dev.classmethod.jp/articles/rds-proxy-avoid-session-pinning/
- https://qiita.com/keitakn/items/fac324cd44c4374d82e6