Developers.IO 2019 in Nagoyaの発表資料です
re:invent2018以降に発表された新機能をサーバーレスアプリケーションの開発に採⽤してみて2019年9⽉12⽇CX事業本部 岩⽥ 智哉
View Slide
スライドは後で⼊⼿することが出来ますので発表中の内容をメモする必要はありません。写真撮影をする場合はフラッシュ・シャッター⾳が出ないようにご配慮くださいAttention
3⾃⼰紹介lクラスメソッド株式会社lサーバーレス開発部 改め CX事業本部l⼤阪オフィス所属l好きなAWSサービス: AWS Lambda岩⽥ 智哉
4今⽇話したいことre:invent2018以降に発表された新機能を実際のシステム開発に採⽤してみて得られた知⾒についてお話しします・どう便利になったのか︖・どういうことに気をつけるべきなのか︖等
5想定しているターゲット• サーバーレスの基礎的な知識を持っている⼈• 実際にサーバーレスで開発を⾏っている⼈• 過去に開発したサーバーレスアプリを改善したい⼈
6アジェンダ無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
7無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
8AWSにおけるサーバーレス開発無駄なコスト• マネージドサービスをフル活⽤してシステムを開発• AWSのサービスはどんどんアップデートされる• できなかったことができるようになったり...• アンチパターンだったアーキテクチャがそうではなくなったり...
9多数の機能が直近1年間にリリース...• Lambdaのランタイム追加• Lambdaのカスタムランタイム• Lambda Layers• ALBのLambdaサポート追加• API GWのWebソケット対応• DynamoDBのGSIが最⼤20個に• DynamoDBのオンデマンドモード• DynamoDB Transactions• AWS Lake Formation• Step Functionsの連携サービス追加• Step Functionsのネスト対応• SARのNested Applications• SARのリソースタイプサポート追加• Cognitoに管理者向けパスワードリセットAPI追加• Aurora Serverlessに Data API追加• AWS ToolKit• AWS CDK• AWS Amplify Consoleサーバーレスアプリケーションの開発に関連しそうなアップデートを抜粋
10AWSにおけるサーバーレス開発で重要なことこれらのアップデート情報を追いかけながらしっかりと追従していくことがより良いシステムを作るために重要
11無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
12DynamoDB Transactions無駄なコスト• ACID特性を保証した⼀連の操作を複数テーブルに跨って提供• ロックはされない• RDBのようにBEGIN,COMMIT,ROLLBACKの呼び出しはない• 分離レベルはSerializeとReadCommited• ※同時実⾏されるオペレーションによって異なる• 同⼀アイテムへの複数回操作は不可• CUの消費が⼤きい
13Batch...系APIとの違いDynamoDB Transactionsを利⽤することで、エラーチェックやリトライ処理の実装負荷が低減Batch...系のAPIは処理の⼀部だけ成功し、処理の⼀部は失敗するというケースが起こり得る。レスポンスのチェックやリトライ処理の実装が煩雑
14DynamoDB Transactionsのユースケース無駄なコスト• 1つのエンティティを複数のアイテムで表現する設計• ⾮キー属性に⼀意性を担保したい場合• 1つの処理の中で複数のテーブルに跨るような処理を実⾏する場合等
15DynamoDB Transactionsのユースケース①1つのエンティティを複数のアイテムで表現する設計• アイテムの属性を保持するために追加のアイテムを使うことで検索に柔軟性を持たせるパターン• アイテムの追加、更新、削除にTransactWriteItemsを利⽤id(PK) attr_name(SK) attr_data1 userName cm-iwata1 email [email protected]1 name 岩⽥テーブル GSIattr_name(PK) attr_data(SK) iduserName cm-iwata 1email [email protected] 1name 岩⽥ 1
16DynamoDB Transactionsのユースケース②⾮キー属性に⼀意性を担保したい場合• PKはパーティションキーなので、⼀意性が担保される• ユーザー名とメールアドレスについても⼀意性を担保したいid(PK) ユーザー名 メールアドレス 名前f25e34e8-8882-48c9-b249-8e387c252af4cm-iwata [email protected] 岩⽥
17DynamoDB Transactionsのユースケース②id(PK) ユーザー名 メールアドレス 名前f25e34e8-8882-48c9-b249-8e387c252af4cm-iwata [email protected] 岩⽥userName#cm-iwataemail#[email protected]• 新規登録時︓3アイテム追加のTransactWriteItems• 更新時︓1アイテム追加、1or2アイテム削除、1or2アイテム追加のTransactWirteItems• 削除時︓3アイテム削除のTransactWriteItemsSimulating Amazon DynamoDB unique constraints using transactionshttps://aws.amazon.com/blogs/database/simulating-amazon-dynamodb-unique-constraints-using-transactions/
18DynamoDB Transactionsのユースケース③1つの処理の中で複数テーブルに跨るような処理を実⾏する場合• データの削除ではなく無効化を⾏いたい• 無効化したデータは再度有効化できるようにしたい• 無効化したデータは⼀定時間経過後に⾃動削除id(PK) 名称1 hogehoge2 fugafugaメインテーブル 無効データテーブルid(PK) 名称 TTL
19DynamoDB Transactionsのユースケース③• 1アイテム追加、1アイテム削除のTransactWriteItems• 1つのテーブルで実現するよりも設計がシンプルにid(PK) 名称1 hogehoge2 fugafugaメインテーブル 無効データテーブルid(PK) 名称 TTL1 デバイス1 1567935907※説明簡略化のためにその他の詳細な要件は省略 これだけの要件であれば1テーブルで設計する⽅がシンプル
20直⾯した課題無駄なコスト• ユニットテストに使っていたライブラリmotoにTransact系のAPIが未実装 ⾃⼒でライブラリを拡張して対応• DynamoDB Localへの乗り換えも検討したが、当時はDynamoDBLocalもTransact系のAPIに未対応(※現在は対応済み)• Lambda実⾏環境にバンドルされている boto3はバージョンが古く、Transact系のAPIに未対応
21DynamoDB Transactionsを使ってみた感想無駄なコスト• 複数テーブル、複数アイテムへの操作の安⼼感が違う• 異常系を想定したコードが単純に 積極的にどんどん使いたい• モックを使ったテストに課題があるかも︖︖事前に確認を• DynamoDB Local、Local Stackは対応済み• オンデマンドモードを使えばCUの消費はあまり気にならない
22無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
23Lambda Layersとは無駄なコスト• 複数のLambda関数でコードを共有するための機能• Lambda実⾏環境には関数とLayerのコード両⽅が展開される• システム全体で共通利⽤するロジックやライブラリの配置に最適
24Lambda Layersができる前①ソースコード デプロイパッケージ Lambda関数.├── .gitignore├── Makefile├── docs├── node_modules│ └── some_library├── package-lock.json├── sam.yml├── src│ ├── func1.js│ ├── func2.js│ └── func3.js└── tests.├── func1.js├── func2.js├── func3.js└── node_modules└── some_libraryhandlerhandlerhandler
25Lambda Layersができる前②ソースコード デプロイパッケージ Lambda関数.├── .gitignore├── Makefile├── docs├── node_modules│ └── some_library├── package-lock.json├── sam.yml├── src│ ├── func1.js│ ├── func2.js│ └── func3.js└── tests.├── func1.js└── node_modules└── some_libraryhandlerhandlerhandler.├── func2.js└── node_modules└── some_library.├── func3.js└── node_modules└── some_library
26Lambda Layersができた後①ソースコード デプロイパッケージ Lambda関数.├── .gitignore├── Makefile├── docs├── node_modules│ └── some_library├── package-lock.json├── sam.yml├── src│ ├── func1.js│ ├── func2.js│ └── func3.js└── tests.├── func1.js├── func2.js└── func3.jshandlerhandlerhandlerレイヤー.└── nodejs└── node_modules└── some_librarylayerlayer
27Lambda Layersができた後②ソースコード デプロイパッケージ Lambda関数.├── .gitignore├── Makefile├── docs├── node_modules│ └── some_library├── package-lock.json├── sam.yml├── src│ ├── func1.js│ ├── func2.js│ └── func3.js└── tests.└── func1.jshandlerhandlerhandlerレイヤー.└── nodejs└── node_modules└── some_librarylayerlayer.└── func2.js.└── func3.js
28本当にそんなに便利︖︖
29Lambda Layersが無かった頃...• 元々デプロイパッケージの作成にはSAM等のツールを利⽤• デプロイパッケージの作成とデプロイはCI/CDで⾃動化全パッケージに共通部品を詰め込むのは⾮効率と理解しながらも、ツールが勝⼿にやってくれるので、⼤して困ってはいなかった
30とりあえず使ってみることに• デプロイの⾼速化⽬的• ライブラリはデプロイパッケージに含めずLayerで別途管理する• ライブラリに更新が無い限りは、Layerは更新しない• Pipfile.lockやpackage-lock.jsonのバージョンとLayerを1:1で管理⽅針とはいえデプロイが⾼速化できる可能性は魅⼒... まずは使ってみる
31直⾯した課題Layerと関数の関連性をどうテンプレートに落とし込むか• Layerと関数でテンプレートは分けたほうが良い︖• CI/CDはどう変えるべきなのか︖
32試⾏錯誤...• Layer⽤のテンプレートでLayerを⽣成し&Exportし、関数⽤のテンプレートからFn::ImportValue• ContentUriが同⼀の場合Layerは更新されない• Fn::ImportValueされていると、LayerのContentUriを更新できないCloudFormationのクロススタック参照はLambda Layersと相性が悪い
33結論• ライブラリを管理するファイルのハッシュ値をObjectKeyとしてLayer⽤のパッケージをS3にUP• PythonならPipfile.lock,Node.jsならpackage-lock.json• LayerのContentUriには上記ObjectKeyを指定• これをCI/CDパイプラインの中で⾃動化するライブラリの依存関係ごとにContentUriが変わるように制御する
34Lambda Layersを使ってみた感想• デプロイしたLambda関数がマネコンから⾒える︕︕• 開発段階ではマネコンから直接コードを編集できるのは結構魅⼒• デプロイが早くなったのかは疑問• Lambda関数作成〜作成完了までの時間が⻑くなった︖• コールドスタートは早くなった 原理は不明• CI/CDの作り込みが少し⾯倒に• 気になるほどのレベルでは無い
35無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
36CloudWatch Logs Insightsとは• CloudWatch Logsのログデータを検索・分析できるサービス• 独⾃のクエリ⾔語が利⽤可能• 最⼤20個のロググループに跨って検索可能(2019/7 Update!!)• 簡単な可視化も可能• 検索範囲は最⼤で24時間までしか指定できない
37できることクエリコマンド できることfields 指定したフィールドをログイベントから取得filter クエリの結果を1つ以上の条件に基づいてフィルタstats フィールドの値に基づいて集約・統計を計算sort 取得したログイベントをソートlimit 取得するログイベントの数を制限parse ログフィールドをパースして名前を付与、後続のクエリで利⽤可能にするこれらのクエリコマンドをパイプ(|)で繋いで利⽤する
38CloudWatch Logs Insightsによるクエリの例①AWS IoTのログからtest-thing-1のデバイスシャドウ更新に失敗したログを抽出fields @timestamp, @message| filter deviceShadowName = 'test-thing-1’and status = 'Failure'
39CloudWatch Logs Insightsによるクエリの例②AWS IoTのログからclientId,eventType別の件数を取得※集計関数が含まれているので⾃動的に視覚化まで⾏われるfields @timestamp, @message| filter clientId not like /iotconsole/ andispresent(clientId)| stats count(clientId) byclientId,eventType| sort clientId,eventType
40CloudWatch Logs Insightsによるクエリの例③Lambdaのログストリーム別に所要時間の最⼩値、最⼤値、平均値を取得fields @message| filter @type = 'REPORT'| limit 10| statsmin(@duration),max(@duration),avg(@duration)by @logStream
41CloudWatch Logs Insightsによるクエリの例④API GWのログからレスポンスボディのJSONをパースし、レスポンスJSONに含まれるcmd_idがxxxのログを抽出parse @message/¥((?¥S+)¥)¥s+(?Method response body aftertransformations:¥s)(?.*)/| filter ispresent(request_id)| parse req_body/.*"cmd_id":¥s"(?.*)".*/| filter cmd_id = ‘xxx'
42CloudWatch Logs Insightsではできないこと• 複雑なクエリ• 例えばSQLのWindow関数• 凝った可視化• 24時間以上にわたる検索CloudWatch Logs Insightsでは不⼗分なユースケースではAthena & QuickSightやAmazonES & Kibanaの利⽤を検討
43CloudWatch Logs Insightsを使ってみた感想• 諸々の調査が楽チンに• 多少クエリの学習コストアリ• 指定できる範囲が最⼤で24時間なので注意• ログを出⼒するならJSONで︕︕JSONは正義• 複数のログを横断的に繋げるために必要な項⽬をログに出そう
44無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
45※まだ実戦投⼊できていないですがインパクトの⼤きいUPDATEなのでご紹介します
46VPC Lambdaの改善とは︖︖• re:invent2018でアナウンスされたVPC Lambdaのアーキテクチャ改善• VPC Lambdaが抱える問題点を改善するために、ENI周りの処理をアーキテクチャ⾒直しを実施• 2019/9/3より順次適⽤開始のアナウンス
47元々VPC Lambdaが抱えていた問題• ENIもしくはIPアドレスが枯渇するリスク• ENI作成を伴うコールドスタート時の⼤幅な遅延• インターネットアクセスにNAT Gatewayが必要さらに、VPC Lambdaの主なユースケースであるRDB利⽤に当たっては• コネクションプーリングの問題• 同時接続数の問題等の課題も
48改善されること、改善されないこと• ENIもしくはIPアドレスが枯渇するリスク• ENI作成を伴うコールドスタート時の⼤幅な遅延• インターネットアクセスにNAT Gatewayが必要さらに、VPC Lambdaの主なユースケースであるRDB利⽤に当たっては• コネクションプーリングの問題• 同時接続数の問題等の課題もこれらの問題が改善されるこれらの課題は引き続き残る
49VPC Lambdaのライフサイクル(ENIの作成) コンテナの作成デプロイパッケージのロードデプロイパッケージの展開ランタイム起動・初期化関数・メソッドの実⾏コンテナの破棄20190402 AWS Black Belt Online Seminar Let's Dive Deep into AWS Lambda Part1 & Part2https://www.slideshare.net/AmazonWebServicesJapan/20190402-aws-black-belt-online-seminar-lets-dive-deep-into-aws-lambda-part1-part2
50Lambda実⾏環境のアーキテクチャ※説明を簡略化するために⼀部省略詳細は AWS公式の資料「 Security Overview of AWS Lambda 」を参照Micro VMLambda実⾏環境WorkerEC2モデル FirecrackerモデルLambda実⾏環境Lambda実⾏環境Micro VMLambda実⾏環境WorkerLambda実⾏環境Lambda実⾏環境Micro VM Micro VM• ENIはWorkerにアタッチされる• ENI Capacity = Projected peak concurrent executions * (Memory in GB / 3GB)Firecracker Firecracker Firecracker
51どこが変わるのか︖︖画像はre:invent2018「 SRV409 A Serverless Journey: AWS Lambda Under the Hood 」の発表資料より引⽤https://www.slideshare.net/AmazonWebServices/a-serverless-journey-aws-lambda-under-the-hood-srv409r1-aws-reinvent-2018?ref=https://dev.classmethod.jp/cloud/aws/reinvent2018-srv409/• コールドスタート時にENIを作成してWorkerにアタッチ• Lambda実⾏環境へのメモリ割り当て3G毎にENIを作成• ENIとIPアドレスを消費しがちな構成• Lambda関数作成時にENIを作成• Hyperplane ENIによるNATを経由して事前作成したENIを利⽤• より多くのLambda実⾏環境が1つのENIを共有
52改善効果https://aws.amazon.com/jp/blogs/compute/announcing-improved-vpc-networking-for-aws-lambda-functions/AWSのブログでは、コールドスタートが1秒未満の例が公開
53VPC Lambda Before & After• ENI作成のオーバーヘッドが無くなる• ENIの上限、IPアドレスの枯渇といった問題が改善変わること• コールドスタートという概念は残る• インターネットアクセスにはNAT Gatewayが必要変わらないことコールドスタートの遅延を理由にVPC Lambdaの採⽤を⾒送っていたようなケースでは、VPC Lambdaの利⽤が有⼒な選択肢に
54VPC LambdaとRDBの組み合わせ• 同時接続数に関する考え⽅• コネクションプーリングは使えない• 従量課⾦モデルのメリットが薄れるRDBを利⽤する場合は引き続き意識したいポイント
55無駄なコスト• AWSにおけるサーバーレス開発について 2分• Lambda Layersについて• DynamoDB Transactionsについて• CloudWatch Logs Insightsについて9分9分5分• VPC Lambdaの改善について• まとめ9分3分
56まとめAWSのサービスはどんどんバージョンアップされていきます。アンテナを⾼く張り、変化に追従していきましょう︕︕
57オススメの情報収拾源無駄なコスト• What's New with AWS (https://aws.amazon.com/new/)• AWS公式のアナウンス ⽇本時間の早朝が更新頻度が⾼い• AWS Blog(https://aws.amazon.com/blogs/)• AWS公式のブログ 様々な機能の詳細解説や、「やってみた」など• Developpers.IO(https://dev.classmethod.jp/)• 弊社の「やってみた」系ブログ• 毎朝早起きしてAWSのアナウンスを正座待機しているメンバーも...
58ご静聴ありがとうございました