AWS Lambdaを紐紐解く
2015.03.22
Amazon  Data  Service  Japan,
Solutions  Architect
Keisuke  Nishitani(@Keisuke69)
Twi$erでJaws	
  Daysに参加しよう!	
  
たくさんリツイートされた⼈人にプレゼント!	
  
@jawsdays
参加⽅方法は簡単!3ステップ	
  
@awscloud_jp +
#jawsdaysをつけてツイート投稿!
1番リツイート数を集めた⼈人が	
  
優勝者です!
AWS公式Twi0erとJAWS	
  DAYS公式Twi0erをフォロー
??
17:00〜~の懇親会で優勝者発表です。	
  
※9:00〜~16:50のTweetが対象です。
+
Kindle JAWS	
  Tシャツ
+
ウェアラブル	
  
Moff	
  Band
JAWS	
  Tシャツ
Step	
  1	
   (参加条件になります)
Step	
  2	
  
Step	
  3	
  
(Jaws	
  Daysに関する投稿なら何でもOK!)
JAWS	
  Tシャツ
⾃自⼰己紹介
•  名前
–  ⻄西⾕谷圭介
–  @Keisuke69
•  ロール
–  ソリューションアーキテ
クト
–  WebサービスやEC、ス
タートアップを担当
–  モバイルなどアプリ寄り
なプロダクトを担当
課題はシンプル
例例えば、
•  S3のバケットに画像
が保存されたらサム
ネイルイメージを⽤用
意したい
•  DynamoDBに保存さ
れるアドレスが全て
正しい形式かチェッ
クしたい
例例えば、
•  S3のバケットに画像
が保存されたらサム
ネイルイメージを⽤用
意したい
•  DynamoDBに保存さ
れるアドレスが全て
正しい形式かチェッ
クしたい
AWS  Lambda以前
•  解決⽅方法は複雑
–  アップロードを検知するためのサーバと仕組み
を⽤用意
–  イベントに応じて処理理を実⾏行行するサーバ群を⽤用
意
–  OSの設定や⾔言語環境の構築
–  パッチ適⽤用や更更新をし続ける必要もある
–  予測困難なリクエスト数に対し、スケールや耐
障害性を⾼高める仕組みを⾃自⾝身で構成
–  キャパシティや状態、セキュリティなどを24
時間365⽇日モニタリング
AWS  Lambda以降降
•  S3に画像がアップロードされたときにサムネイ
ルの⽣生成やリサイズを実⾏行行
AWS LambdaAmazon S3 Bucket イベント
元画像 サムネイル画
像
1
2
3
AWS  Lambdaとは
•  クラウド上で、イベントをトリガーに独⾃自のコード
を稼働させるComputeサービス
–  EC2インスタンスやOS等インフラの管理理作業が不不要
–  毎⽇日数件から毎秒数千件のリクエストまで⾃自動的にスケール
–  従量量課⾦金金、実際にコードが稼働した時間に対してのお⽀支払
–  新たに追加された情報(イベント)に対して即座に応答するアプリ
ケーションを、特別な仕組みなく簡単に実装できる
特徴
インフラの管理理が不不要
•  ビジネスロジックにフォーカスで
きる
•  コードをアップロードするだけで、
あとはAWS  Lambdaが以下をハ
ンドリング
–  キャパシティ
–  スケール
–  デプロイ
–  耐障害性
–  モニタリング
–  ロギング
–  セキュリティパッチの適⽤用
オートスケール
•  イベントのレートに合うように
Lambdaが⾃自動でスケール
•  プロビジョニング中や完了了を気に
する必要なし
•  コードが稼働した分だけのお⽀支払
い
Bring  your  own  code
•  Node.jsで書かれたコードを実⾏行行
•  コード内では以下も可能
–  スレッド/プロセスの⽣生成
–  バッチスクリプトや何らかの実⾏行行
ファイルの実⾏行行
–  /tmpのread/write
•  各種ライブラリも利利⽤用可能
–  ネイティブライブラリも可能
–  利利⽤用するライブラリを⼀一緒にアップ
ロード
細やかな料料⾦金金体系
•  100ミリ秒単位でのコンピュート
時間に対する価格設定
•  リクエストに対する低額の課⾦金金
•  ⼗十分な無料料枠
ユースケース
値チェックや別テーブルへのコピー
•  DynamoDBへの書き込みに応じて値チェックを
しつつ別テーブルの更更新やプッシュ通知を実⾏行行
AWS Lambda
Amazon DynamoDB
Table and Stream
プッシュ通知
別テーブルを更更新
監査と通知
•  S3に保管されるCloudTrailのログを分析し、怪
しい⾏行行動や異異常を検知したら通知する
AWS APIコール
AWS CloudTrail Logs
AWS Lambda
Bucketイベント プッシュ通知
⼝口コミアプリ
•  投稿の書き込み/表⽰示はDynamoDBと直接
•  レートの計算はモバイルアプリから直接Lambdaを実⾏行行し⾮非
同期で実⾏行行
1.  認証・認可
・  FBアプリと連携
Cognito
DynamoDBApp  with  
AWS  Mobile  
SDK
2.  ⼝口コミの投稿
・  投稿内容とレーティング
4.  過去の全データを元に平均値の計算と
    結果のDynamoDBへの登録等
3.  Lambda  functionの起動
Lambda
Followers
写真共有モバイルアプリ
4.  メタデータをDynamoDBに登録
-‐‑‒  タイトル、コメント等
1.  認証・認可
・  FBアプリと連携
6.  Push通知
-‐‑‒  フレンドやフォロワーに通知
Cognito
Mobile  Analytics
DynamoDB
S3
SNS7.  画像をポストしたことをAnalyticsに登録
3.  画像のリサイズ
2.  S3への画像アップロード
5.  結果をSNSへ通知
App  with  
AWS  Mobile  
SDK
AWS  Lambdaの使い⽅方
Lambdaファンクション
•  コードはJavaScript(Node.js)で記述
•  コードはZip形式にしてアップロードもしくはコンソール上で直接記述
–  各種ライブラリはZipファイルに含めることで利利⽤用可能
•  メモリ容量量はデフォルトで128MB
–  64MBごとに設定可能
–  容量量に応じてCPU能⼒力力なども変動
•  実⾏行行時間のタイムアウトはデフォルトで3秒、最⼤大60秒まで
•  Lambdaファンクションの起動と実⾏行行でそれぞれIAM  Roleを設定
•  /tmpに対してread/write可能
•  それぞれが隔離離されたコンテナ内で実⾏行行される
ネイティブライブラリ
•  ファンクション内で利利⽤用するネイティブライブラリを独
⾃自にビルドして、パッケージすることも可能
–  Node.jsがインストールされたAmazon  Linuxと同等のマシンが必要
–  Amazon  Linuxに含まれるライブラリを使⽤用してビルドする必要がある
–  ライブラリおよび依存関係はスタティックにコンパイルするかダイナミッ
クリンクを指定してコンパイルする必要がある
–  ドキュメントに記載のあるAmazon  LinuxのAMIを使って起動したEC2イン
スタンスを利利⽤用するとよい
http://docs.aws.amazon.com/lambda/latest/dg/lambda-‐‑‒
introduction.html
(例例)OpenCVを導⼊入する場合
1.  LambdaがサポートするAMIを利利⽤用してEC2イ
ンスタンスを起動(⼿手順は割愛)
2.  OSアップデートと必要なライブラリ、ツール
とNode.jsをインストール
$ sudo yum update
$ sudo yum install gcc44 gcc-c++ libgcc44 cmake python26-devel –y
$ wget http://nodejs.org/dist/v0.10.33/node-v0.10.33.tar.gz
$ tar -zxvf node-v0.10.33.tar.gz
$ cd node-v0.10.33 && ./configure && make
$ sudo make install
$ sudo easy_install pip
$ pip install numpy
(例例)OpenCVを導⼊入する場合
3.  ネイティブライブラリのダウンロード
$ wget http://downloads.sourceforge.net/project/
opencvlibrary/opencv-unix/2.4.9/opencv-2.4.9.zip	
$ mkdir opencv_install	
$ mkdir opencv_example	
$ unzip opencv-2.4.9.zip –d ./opencv_install/ && cd
opencv_install
4.  スタティックライブラリ⽤用に設定
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D BUILD_SHARED_LIBS=NO -
D CMAKE_INSTALL_PREFIX=~/opencv opencv-2.4.9/
(例例)OpenCVを導⼊入する場合
5.  モジュールのビルドとインストール
6.  npmを⽤用いてパッケージのインストール
npm  install実⾏行行前にPKG_̲CONFIG_̲PATHの指定を⾏行行い、静的にコン
パイルされたバージョンのOpenCVを⽤用いてOpenCVライブラリをコ
ンパイル
$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:~/opencv/lib/
pkgconfig/	
$ npm install –prefix=~/opencv_example opencv
$ make && make install
コード
•  基本
–  現時点ではNode.jsで記述し、Node.jsのベストプラクティスに従う
–  AWS  SDKは組み込み済みで使えるようになっている
–  ImageMagickグラフィックライブラリを標準で利利⽤用可能
•  ステートレス
–  データを永続化するためにはS3、DynamoDBもしくはその他のインターネット経由
で利利⽤用可能なストレージを利利⽤用すること
–  実際に実⾏行行されるサーバは毎回異異なり、ログインもできない
•  その他
–  プロセス、スレッド、/tmp、ソケットの利利⽤用可能
–  各種ライブラリを利利⽤用可能
–  インバウンドのソケット接続は不不可能
プログラミングモデル
•  handler_̲nameがLambdaが呼び出す関数名となる
–  ファンクション作成時ならびにコードのアップロード時に指定する
•  イベントのデータをパラメータとして渡す
–  JSON形式
–  サービスごとに異異なる
–  カスタムイベントの場合はInvokeAsync発⾏行行時の引数として渡した任意のJSON形式の値
•  終了了時にはcontext.done()を呼び出す(後述)
exports.handler_name = function(event, context) {
console.log("value1 = " + event.key1);
console.log("value2 = " + event.key2);
...
 context.done(null, "some message");
}
context.done()
•  context.done()を呼び出すとファンクションが終了了したものと⾒見見な
される
–  処理理終了了を明⽰示するために必ず呼び出す
–  呼び出さないと必要以上に⻑⾧長く実⾏行行されてしまう可能性がある
•  第1引数
–  成功の場合はnullにする。値が⼊入っているとエラーとして解釈される
–  null以外の値は⽂文字列列化されて⾃自動的にCloudWatchのログに記録され、リトライが⾏行行われ
る場合がある
•  第2引数(オプション)
–  メッセージ⽂文字列列
–  テスト実⾏行行の際、コンソール画⾯面下部のログ出⼒力力に表⽰示される
–  成功/失敗両⽅方で使える
コード例例
console.log('Loading event');
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
exports.handler = function(event, context) {
console.log('Received event:');
console.log(JSON.stringify(event, null, ' '));
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
s3.getObject({Bucket:bucket, Key:key},
function(err,data) {
if (err) {
console.log('error getting object ' + key + ' from bucket ' + bucket +
'. Make sure they exist and your bucket is in the same region as this
function.');
context.done('error','error getting file'+err);
}
else {
console.log('CONTENT TYPE:',data.ContentType);
context.done(null,'');
}
}
);
};
Lambdaファンクションの作成
•  コンソールに組み込まれたコードエディタ
–  サンプルテンプレートを⽤用いて簡単に始めることが可能
–  名前とIAM  roleを設定するだけという簡単な設定
•  Zipファイルによるコードのアップロード
–  ZipファイルのアップロードはSDKならびにCLIもサポート
–  ライブラリを含める場合
–  ディレクトリが含まれない形でZipファイルにまとめる必要あり
•  コードのあるディレクトリに移動した上で以下のようなコマンドで圧縮するのがおすすめ
zip  -‐‑‒r  lambda-‐‑‒sample.zip  .
•  リソースサイズの設定
–  128MBから1GBの範囲で64MBごとにメモリサイズを設定
–  使ったメモリ量量はログに出⼒力力されるため後から調整が可能
–  タイムアウトは1秒から60秒の間で設定(デフォルトは3秒)
イベントソースの設定
•  S3
–  AWS  Lambdaのコンソール上でS3
のバケットを選択
–  S3のコンソール上でバケットイベン
トに対応するLambdaファンクショ
ンを選択する
•  DynamoDB
–  DynamoDBのコンソール上で
Streamを作成し、それに対応する
Lambdaファンクションを選択する
•  Kinesis
–  AWS  SDKもしくはCLIを利利⽤用して
Kinesis  Stream内のメッセージを処
理理するようLambdaを設定すること
も可能
Amazon DynamoDB Console
(Preview)
Amazon S3 Console
イベントソースの設定
イベントソースの設定(CLI)
$ aws lambda add-event-source 
--region us-east-1
--function-name ProcessKinesisRecords 
--role invocation-role-arn 
--event-source kinesis-stream-arn 
--batch-size 100 
※実際は⼀一⾏行行で実⾏行行
イベント
•  イベントはJSON形式でLambdaに渡される
•  Lambdaファンクションはイベントごとに実⾏行行される
–  PUSHモデル:  Amazon  S3とカスタムイベント
•  順不不同
•  サービスもしくはアプリケーションがInvokeAsyncを呼んで直接実⾏行行する
•  3回までリトライ
–  PULLモデル:  Amazon  DynamoDB  と  Amazon  Kinesis
•  順序性あり。ストリームに⼊入ってきた順に処理理される
•  イベントソースとして登録したストリームに対してLambdaが⾃自動的に取得しに
いく
•  イベントごとに複数のレコード
•  データが期限切切れになるまでリトライ
イベント例例(S3)
{
"Records": [
      -- 省省略略 –
      "s3": {
"s3SchemaVersion": "1.0",
"configurationId": "testConfigRule",
"bucket": {
"name": "sourcebucket",
"ownerIdentity": {
"principalId": "A3NL1KOZZKExample"
},
"arn": "arn:aws:s3:::mybucket"
},
"object": {
"key": "sourcebucket/HappyFace.jpg",
"size": 1024,
"eTag": "d41d8cd98f00b204e9800998ecf8427e"
}
}
}
]
}
イベント例例(Kinesis)
{
"Records": [
{
"awsRegion": "us-east-1",
"sequenceNumber": "196800000000000000000374",
"partitionKey": "2efdb0ea22685b46993e42a67302a001",
"eventSource": "aws:kinesis",
"data": "SOME CUSTOM DATA 1"
},
{
"awsRegion": "us-east-1",
"sequenceNumber": "196800000000000000000571",
"partitionKey": "2efdb0ea22685b46993e42a67302a003",
"eventSource": "aws:kinesis",
"data": "{ "key": "value" }"
}
]
}
モニタリング
•  ダッシュボード
–  全てのLambdaファンク
ションのリスト
–  可視化されたメトリクス
•  CloudWatchを⽤用いた
Metricsの監視
–  リクエスト数
–  エラー数
–  レイテンシ
デバッグ
exports.handler =
function(event, context) {
console.log('Received event:');
var bucket =
event.Records[0].s3.bucket.name;
var key =
event.Records[0].s3.object.key;
console.log(‘Bucket: ‘+bucket);
console.log(‘Key: ‘+key);
…
•  実⾏行行ログがCloudWatchに出⼒力力される
–  各Lambdaファンクションごとのログ
グループ
•  実⾏行行開始/終了了と消費したリソースに関する
デフォルトのログエントリ
–  メモリ使⽤用量量(Max  Memory  Used)
–  実⾏行行時間(Duration)
–  課⾦金金対象時間(Billed  Duration)
•  カスタムログエントリの追加も可能
–  ファンクション内でconsole.logを⽤用い
て出⼒力力
Lambdaファンクション作成時の注意事項
Lambdaファンクション作成時の注意事項
•  ロールを正しくセットアップする
–  Execution  rolesはLambdaファンクションができることを決定
する
–  Invocation  rolesは誰がファンクションを実⾏行行できるかを決定
する
•  再帰処理理は慎重に
–  イベントハンドラ内部でS3やDynamoDBへオブジェクトの書
き込みを⾏行行うと、別のイベントがトリガーされ無限ループに陥
る可能性がある
ちょっとだけ深い話
コンテナのライフサイクル
開始
•  ファンクション作成後、もしくはコードや設定
更更新後の初回実⾏行行時は新たにコンテナが作成さ
れ、ファンクション⽤用のコードがコンテナ内に
ロードされる
•  Node.js側では、ハンドラが最初に呼び出され
る前に初期化コードがコンテナの⽣生成ごとに⼀一
度度だけ実⾏行行される
終了了
•  Timeout
–  ユーザが指定した実⾏行行時間を超えた場合。その時どういう処理理が⾏行行われているかは関係なく、即時
停⽌止される
•  Controlled  termination
–  コールバックの1つがcontext.done()を呼び出して終了了した場合。この時点で他のコールバックが
実⾏行行されてるかに関わらず終了了する
•  Default  termination
–  全てのコールバックが終了了してファンクション⾃自体が終了了した場合。この時、context.done()を
実⾏行行していなくてもログに“Process  exited  before  completing  request”と出⼒力力される
•  クラッシュもしくはprocess.exit()を呼び出すことでも終了了
–  例例えば不不具合のあるライブラリが含まれていて、セグメンテーション違反を起こした場合、そのコ
ンテナは実⾏行行終了了となる
–  ログには以下のようなメッセージが出⼒力力される
“Process  exited  before  completing  request”
再利利⽤用
•  実⾏行行からある程度度時間が経過した後に再度度実⾏行行され
る場合は新たにコンテナが作成される
–  初回実⾏行行時と同様
•  コードの変更更がなく前回の実⾏行行から時間が⽴立立ってい
ない場合は以前のコンテナを再利利⽤用することがある
–  Node.jsの初期化処理理をスキップできるなどパフォーマンス上のア
ドバンテージ
–  再利利⽤用された場合は最後に/tmpに書き込んだ内容も残っている
プロセスの凍結と再開
プロセスの凍結と再開
•  ファンクションの終了了時に実⾏行行中のバックグラウン
ドプロセスがある場合、Lambdaはプロセスを
freezeさせ、次回ファンクションを呼び出した際に
再開する
–  ただし、コンテナが再利利⽤用される場合だけであり保証はされていな
い
•  この場合、バックグラウンドプロセスは残っていて
も処理理は⾏行行われていない
–  プロセス再作成のオーバーヘッドを減らせる
制限事項
•  Lambdaファンクションのリソース
リソース 制限
/tmpスペース 512MB
ファイルディスクリプタ数 1024
プロセス数およびスレッド数(合計) 1024
同時リクエスト数(プレビュー期間中) 50リクエスト/秒
1リクエストあたりの実⾏行行時間(プレビュー期間中) 60秒
•  インプット
インプット 制限
zipファイル(圧縮) 30MB
zipファイル(無圧縮) 250MB
InvokeAsyncのリクエストボディ(JSON) 128KB
料料⾦金金体系
•  リクエスト  (全リージョン)
–  ⽉月間100万リクエストまでは無料料
–  超過分は$0.20/100万リクエスト
(1リクエストあたり$0.0000002)
•  実⾏行行時間  (全リージョン)
–  100ms単位で課⾦金金
–  100ms以下は繰り上げで計算
–  メモリー容量量により単価および無料料時間
が異異なる
•  かなり複雑なのでこちらも参考に
–  http://qiita.com/Keisuke69/items/
e3f79b50b6039175401b
Memory
(MB)
Price per 100ms
($)
Free tier seconds
per month
128 0.000000208" 3,200,000
192 0.000000313" 2,133,333
256 0.000000417" 1,600,000
320 0.000000521" 1,280,000
384 0.000000625" 1,066,667
448 0.000000729" 914,286
512 0.000000834" 800,000
576 0.000000938" 711,111
640 0.000001042" 640,000
704 0.000001146" 581,818
768 0.00000125" 533,333
832 0.000001354" 492,308
896 0.000001459" 457,143
960 0.000001563" 426,667
1024 0.000001667" 400,000
参考資料料
•  ブログ
–  https://aws.amazon.com/blogs/compute/
•  ドキュメント
–  http://docs.aws.amazon.com/lambda/latest/dg/
AWS  Lambda  Hands  Onやります
•  4/9(⽊木)  19時〜~
•  30名(抽選)
•  http://kokucheese.com/event/index/275296/
2015.06.02-‐‑‒03  Save  the  Date
Run  Code  in  the  cloud!

AWS Lambdaを紐解く