[[AWSメモ]] > AWS LambdaからRDSに接続する
* AWS LambdaからRDSに接続する [#ude5d771]
#mynavi(AWSメモ);
#setlinebreak(on);

#TODO(画像を貼る)

* 目次 [#e7345327]
#html(<div style="padding-left: 10px;">)
#contents
-- 関連
--- [[AWSメモ]]
--- [[AWS LambdaでRDS接続時のパフォーマンス調査]]
#html(</div>)

** RDSインスタンス 及び DBの作成 [#j4f4daf0]
* はじめに [#d966fb6b]
#html(<div style="padding-left: 10px;">)
パフォーマンスが要求されるようなケースや大量のアクセスを捌く必要があるケースでは &color(red){''Lambda&RDSはアンチパターン''}; である事を認識しておく。
※コールドスタート時、VPC内に配置したLambda起動時にはENIアタッチが発生する為、Lambdaの起動に時間がかかる。
※インスタンスが持続して残る訳ではないので、コネクションプールがあまり意味を持たない為、結局はDBへの接続コストがかかる。
 (大量のアクセスを捌く場合は最大接続数も問題になる)

** AWS sdk のインストール [#c8430add]
#html(<div style="padding: 0 5px; border: 4px solid #f93; display: inline-block">)
[追記]
2018年の  Re:Invent で ”リモートNAT” として紹介されていた仕組みが実装され、VPC Lambda のコールドスタート時の ENI周りのパフォーマンスが大幅に改善された模様。
”ハイパープレーンENI” という名前でアナウンスされており、14.8 sec -> 933 ms に改善されたとの事。

** Lambda関数の作成 [#mb92c8d4]
https://aws.amazon.com/jp/blogs/compute/announcing-improved-vpc-networking-for-aws-lambda-functions/
※東京リージョンは 2019年9月27日 にアップデートされたとの事。
#html(</div>)

&br;

| DB | 参考URL(同時接続数) |h
| MySQL | https://dev.mysql.com/doc/refman/5.6/ja/too-many-connections.html |
| AuroraMySQL | https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.html#AuroraMySQL.Managing.MaxConnections |

#html(</div>)

* RDSインスタンス 及び DBの作成 [#j4f4daf0]
#html(<div style="padding-left: 10px;">)
#TODO
#html(</div>)

* AWS sdk のインストール [#c8430add]
#html(<div style="padding-left: 10px;">)
#TODO
#html(</div>)

* Lambda関数の作成 [#mb92c8d4]
#html(<div style="padding-left: 10px;">)

以下、ローカルでの作業

*** Lambda関数用のディレクトリを作成し、MySQLモジュールをインストール [#g9105aa6]
** Lambda関数用のディレクトリを作成し、MySQLモジュールをインストール [#g9105aa6]
#html(<div style="padding-left: 10px;">)
#myterm2(){{
mkdir rds-access1
cd rds-access1
npm install mysql
}}
#html(</div>)

*** Lambda関数の作成 [#p71dcfcf]
** Lambda関数の作成 [#p71dcfcf]
#html(<div style="padding-left: 10px;">)

index.js
#mycode2(){{
var AWS = require('aws-sdk');
//var dynamo = new AWS.DynamoDB.DocumentClient();
var mysql = require('mysql');

const createResponse = (callback, statusCode, body) => {
	var res = {
		"statusCode": statusCode,
		"headers": { "Test-Headr": "1234" },
		"body": JSON.stringify(body)
	}
	callback(null, res);
}

exports.handler = function(event,context,callback){
    var connection = mysql.createConnection({
      host     : 'testdbinstance-cluster-1.cluster-cef24caqtt2c.ap-northeast-1.rds.amazonaws.com',
      host     : 'testdbinstance-cluster-1.cluster-xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com',
      user     : 'example_user',
      password : 'example_pass',
      database : 'example_db'
    });
    connection.connect();
    connection.query('select * from books', function(err, rows, fields) {
      if (err) throw err;
      console.log(rows);
      console.log(fields);
      var list = JSON.stringify(rows);
      createResponse(callback, 200, { "list": list });
    });
    connection.end(function(err) {
      context.done();
    });
}
}}
#html(</div>)

** ロールの作成 [#n977d54b]
#html(</div>)

* ロールの作成 [#n977d54b]
#html(<div style="padding-left: 10px;">)
[[マネージメントコンソールのIAM - ロール:https://console.aws.amazon.com/iam/home?region=ap-northeast-1#/roles]] から以下のポリシーを持つロールを作成する。

・AmazonRDSFullAccess
・AWSLambdaFullAccess
・AmazonVPCFullAccess

作成したロールの「ロールARN」を確認しておく。
#html(</div>)

* Lambda関数のアップロード [#qcccf6af]
#html(<div style="padding-left: 10px;">)

** Lambda関数のアップロード [#qcccf6af]

*** zip の作成 [#a015542e]
#html(<div style="padding-left: 10px;">)
#myterm2(){{
cd rds-access1
rm -rf rds-access1.zip
zip -r rds-access1.zip .
}}
#html(</div>)

*** アップロード [#u38f20f7]
** アップロード [#u38f20f7]
#html(<div style="padding-left: 10px;">)
#myterm2(){{
aws lambda create-function \
  --function-name rds-access1 \
  --runtime nodejs6.10 \
  --role 上記で確認したロールARN \
  --handler index.handler \
  --zip-file fileb://rds-access1.zip
}}
#html(</div>)

** AWS API Gateway からアクセスできるようにする [#ga226a9b]
#html(</div>)

*** API の作成 [#h171a2fa]
* AWS API Gateway からアクセスできるようにする [#ga226a9b]
#html(<div style="padding-left: 10px;">)

** API の作成 [#h171a2fa]
#html(<div style="padding-left: 10px;">)
[[マネージメントコンソール - API Gateway:https://ap-northeast-1.console.aws.amazon.com/apigateway/home?region=ap-northeast-1#/apis]]にアクセスし、以下の通り作成する。

|API 名|rds_access|
|リソース名|rds-access|
|リソースパス|/rds-access|
|メソッド|GET|
|統合タイプ|Lambda関数|
|Lambdaプロキシ統合の使用|on|
|Lambda リージョン|Lambda関数を作成したリージョン|
|Lambda 関数|作成したLambda関数名|

◆注意
Lambdaプロキシ統合の使用を on にした場合、event から 様々な httpリクストの情報が得られるが、
レスポンスデータの形式もルールに従う必要がある。
参照 : http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-output-format
#html(</div>)


*** デプロイ [#n8562572]
** デプロイ [#n8562572]
#html(<div style="padding-left: 10px;">)
作成したら、アクションの「API のデプロイ」からデプロイする。
※ステージ名は、ここではとりあえず dev とかにしておく。(このへんは運用次第)
#html(</div>)

*** URLの確認 [#t1a3a010]

** URLの確認 [#t1a3a010]
#html(<div style="padding-left: 10px;">)
デプロイしたら「ステージ」から対象の API を選択すると「URL の呼び出し」という箇所で APIのURLが確認できる。
#html(</div>)

#html(</div>)


トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS