こんにちは、オカザキです。
2019年の秋頃、AWSよりRDS Proxyの発表がありました。
今回はこのRDS Proxyを使用して今までアンチパターンとされていたLambdaからRDSへのアクセスを実際に試してつまずいた部分を共有したいと思います。
※2019年3月現在、プレビュー段階での記事となります
なぜアンチパターンなのか
LambdaからRDSへのアクセスがアンチパターンと言われる最大の理由は同時接続数の上限です。
Lambdaはリクエストごとに起動するためRDSのコネクションの上限数など気にせず起動するしてそれぞれのLambdaにてRDSに対してコネクションを張ろうとします。
そのため、コネクションの上限を超えたLambdaからのアクセスはRDSアクセス時にエラーとなってしまいます。
今回発表されたRDS Proxyを使うことでRDSに確立した接続をプール・共有してコネクションが上限を超えないよう管理しているようです。
Amazon RDS Proxyを利用してみよう
公式のドキュメントを参考に、実際にLambdaからRDSへ接続してみました。
Lambdaを実行した結果
公式のドキュメント通りに環境を作成し、Lambdaを実行しましたが以下のエラーとなりました。
“errorMessage”: “2020-03-24T12:56:44.589Z 2bc87ca4-4998-4403-8202-b1ef58dcd91f Task timed out after 3.00 seconds”
Σ(゜゜)
Lambdaの実行タイムアウトとなっていました。
実行タイムアウト時間が短かったのかと思い、30秒に伸ばしたりしましたが結果は同じくタイムアウトしてしまいました。
エンドポイントをRDS Proxyとせず、直でRDSのエンドポイントとすると問題なく接続できたことからRDS Proxyへの接続に何かしら問題あることがわかりました。
Lambda関数のVPCを設定する必要があった
AWS公式のユーザーガイドを読むとどうやらRDSと同じVPC内にLambda関数を配置する必要があったようです。(「プロキシへの接続の検証」参照)
Lambda関数のVPC設定をRDSを作成したVPCと同一VPC内に設定してあげることで、無事RDS Proxyを経由してRDSに接続することができました。
“Get 1 items from RDS MySQL table”
Lambda関数
公式ドキュメントではNode.jsを用いて接続していましたが、個人的にPythonの方が好きだったのでPythonにて実装しました。
import sys
import os
import pymysql
#rds settings
DB_USER = os.environ["user"]
DB_PASSWORD = os.environ["password"]
DB_HOST = os.environ["endpoint"]
DB_NAME = os.environ["db"]
try:
conn = pymysql.connect(DB_HOST, user=DB_USER, passwd=DB_PASSWORD, db=DB_NAME, connect_timeout=5)
except Exception as e:
print("Fail connecting to RDS mysql instance")
print(e)
sys.exit()
print("Success connecting to RDS mysql instance")
def handler(event, context):
item_count = 0
with conn.cursor() as cur:
cur.execute("select id, name from test_table")
for row in cur:
item_count += 1
print(row)
return "Get %d items from RDS MySQL table" %(item_count)
おわりに
AWSの機能でプレビュー版を初めて使いましたがワクワクしながら環境構築することができました。
3年近くAWSを利用していましたがRDS自体は触るのが初めてだった為勉強になることが多かったです。
最初にRDSをポチポチとたてて満足して放置していたら5,000円ほどの課金が発生したのはまた別の話です…
RDS Proxyを本稼働で使えるようになったら今後更にサーバーレスアーキテクチャが主流になっていくのではないでしょうか。
ぜひ皆様もRDS Proxyを活用してみてください!!
以上です。