【セッションレポート】サーバーレス開発のベストプラクティス ~より効果的に、より賢く使いこなすために~(AWS-30)#AWSSummit
はじめに
AWS Summit Japan 2024 に参加しました。
「サーバーレス開発のベストプラクティス~より効果的に、より賢く使いこなすために~」のセッションレポートです。
セッション概要
サーバーレスアプリケーションの開発においては、AWS Lambda や Amazon API Gateway、Amazon DynamoDB、Amazon EventBrige など様々なサービスをビルディングブロックとして組み合わせることができたり、開発作業を効率化するツールチェインも多く提供されるようになってきました。AWS Step Functions は Amazon Bedrock と統合され、生成系 AI アプリケーションをシームレスに開発できるようになります。サーバーレスアーキテクチャの能力を最大限に活用するために、私たちはその組み合わせ方を考えなければいけません。アプリケーションを拡張したり、より高いパフォーマンスとより低いコストを実現するにはどのような手段がとれるでしょうか。本セッションでは、サーバーレスアプリケーションをより効果的に、より賢く使いこなすために最適な手法やベストプラクティスをご紹介します。
セッションスピーカー:淡路 ⼤輔
所属:アマゾン ウェブ サービス ジャパン合同会社 ガバメントクラウド技術本部
アジェンダ
- サーバレスとは?
- サービスフルなサーバレス
- 生成AIとサーバレス
- まとめ
セッションレポート
サーバレスとは?
サーバレスの歴史
- AWS Lambdaが登場して10年経つ
- その後、API Gateway、Step Functions、SQS、EventBrigeなどがリリースされた
- 昨年 Amazon Bedrockが登場
サーバレスに求められること
- サーバーやインフラ管理が不要で実行できること
- 複雑なインフラを管理することなく、顧客に価値提供できること
- → 年々、求められることが変化してきている
サービスフルなサーバレス
サーバーレスアプリケーション
- 「イベントソース→Lambda→直接サービス」の構成から、「イベントソースから直接サービス」
- 直接的なサービス統合 = サービスフル
- Lambdaが不要になることで、コードの保守不要などのメリットが大きい
- Lambdaは、Transport(転送)ではなくTransform(変換)に使用する
- イベント連携やフロー管理のサービスを活用し、「つなげるLambda」を減らす。
- 独自にやりたい処理にのみLambdaを使う
オンプレミスからクラウドに移行(リフト&シフト)
- 構成:API Gateway → Lambda → S3
- アプリケーションのコードがLambdaに移されただけである
Lambdaから別のサービスに責務を移譲する
- S3
- フロント
- API Gateway
- 認証
- キャッシュ
- スロットリング
- Step Functions
- リトライ
- エラーハンドリング
単一責務の原則とLambda関数の単位
- 1つのLambdaで3つの関数を持つ場合、3つのLambdaに分割してみる
- パフォーマンス向上
- IAMの権限も狭められる
- Lambda-lith
- 1つのLambda関数内で全てのロジックをルーティングする
- Lambdaのメモリが過剰になったり、IAM権限が大きくなる
- 1つのLambda関数内で全てのロジックをルーティングする
- Micro Lambda
- API単位でLambda関数を分ける
- Lambdaのメモリ適正、IAM権限は最小限になる
- 運用は大変
- API単位でLambda関数を分ける
- Pragmatic Lambda
- 適切な粒度(グループ)で分ける
- 粒度が大きいと、パフォーマンス低下やIAM権限が大きくなる
- 粒度が小さいと運用は大変
- グループ化の例
- 境界づけられたコンテキスト
- 開発組織の構造
- メモリ割り当て
- 共通的なコードの依存関係
オーケストレーションとコレオグラフィ
- オーケストレーション
- サービス間の通信を管理して、処理を順序付けるコーディネーターがいる
- 例:Step Functions
- コレオグラフィ
- それぞれのサービスが自律。非同期で対応
- 例:EventBridge
オーケストレーションとコレオグラフィの使い分け
- ServerlessVideo(サンプルアプリケーション)
- サーバーレスアーキテクチャで構築されたライブビデオストリーミングサービス
- 特徴
- 生成AIによるタイトル生成
- BedrockとTranscribeを利用し、ビデオからタイトルと説明分を生成する
- プラグインアーキテクチャ
- Step FunctionsとEventBridgeによって、拡張が容易な構成
- 選択的なサーバレスコンピュート
- ビデオの長さに応じて、LambdaやFargateを使い分ける柔軟性を持つ
- 生成AIによるタイトル生成
- Step FunctionsとEventBridgeを組み合わせている
- ドメインごとの処理をオーケストレーションする
- コンピューティングサービスの選択
- 可能な限りサービス統合を使用する
- 完了したらイベント送信
- ドメインごとの処理をオーケストレーションする
Step Functions
- AWS SDK 統合
- Lambdaが特定のサービスを呼び出すだけであれば、Step Functionsで代替可能である
- ソースコードが削除できる
- Lambdaが特定のサービスを呼び出すだけであれば、Step Functionsで代替可能である
Amazon API Gateway統合
- Lambdaをプロキシとして機能している場合、Lambdaを削除する
- Lambdaがプロキシとして機能
- API Gateway → Lambda → AWSサービス
- 直接統合可能
- API Gateway → AWSサービス
- Lambdaがプロキシとして機能
コードによるインテグレーション
- DynamoDB Streams → Lambda → EventBrige enent bus
- Lambdaを置き換え)DynamoDB Streams → EventBrige pipes → EventBrige enent bus
シンプルなLambda関数を削除して組み込みの統合に置き換えることができるか考えることが重要
生成AIとサーバレス
ServerlessVideo(サンプルアプリケーション)の要件
- 要件1:動画から複数のタイトル、説明を作成する
- 要件2:人間にフィードバック依頼する
- 要件3:ビデオ用のアバター画像を作成する
要件1:動画から複数のタイトル、説明を作成する
- 動画の音声を文字起こしし、文字起こし内容から動画のタイトルや説明文を作り返す
Step Functionsのジョブ実行パターン
- リクエスト-レスポンス:HTTPレスポンスだけを待ってすぐに次に進む
- ジョブ実行 sync:ジョブの完了を待ってから次に進む
- コールバック:タスクトークンが返却されるまで待つ
Step Functionsから、Amazon Transcribe APIと直接統合してビデオをテキストに変換できる
- リトライも可能
- エラーハンドリングも可能
サービス間の直接統合
- LambdaからDynamoDBにクエリする場合
- SDKのインポートする
- クライアントオブジェクト作成
- エラーハンドリングする
- ハンドラー内で呼び出す
- ログを出力する
- コードを書くということは、責任範囲が広がる
- Step Functionsに置き換える場合
- 単一タスクの「ワークフロー」であっても、以下が組み込まれている
- エラー処理
- キャッチ
- 再試行
- 可観測性
- カスタムコードの削除
- ロギング
- 単一タスクの「ワークフロー」であっても、以下が組み込まれている
基盤モデルへのアクセス
- Bedrockでは様々な基盤モデルを提供している。シンプルなAPIで利用できる
- LambdaからBedrockを呼び出す場合
- エラーハンドリングを書く
- ログを書く
- Step Functionsに置き換えることができる
- BedrockのAPIが直接呼び出せる
- 他にも、モデルのカスタマイズジョブも可能
パブリックAPIへのアクセス
- 面倒事が多い
- 認証方法(Basic認証やOAuth認証)
- シークレットの管理
- OAuth tokenのハンドリング
- I/Oハンドリング
- リトライの制御
Lambdaで実装する場合
- クレデンシャル取得
- Secrets Manager
- トークンの保存
- DynamoDB
- プロンプトの取得
- S3に保存
- APIの呼出し
- パブリックAPI
上記の実装は、ビジネスの差別化とならない重労働である
パブリック HTTPS API 統合(API Endpointへの直接統合)
Step Functionsの場合、以下が用意されている
- エラーハンドリング
- HTTPステータスコードでハンドリング
- 認証/認可
- OAuth、Basic,APIキー認証
- データ加工
- URLエンコーディング、リクエストボディの加工
- テストステート
- ステップを独立してテストする
- ビジネスロジックを検証する
Step Functionsで並列処理する際、エラーになった場合は、Redrive from failureの機能で失敗した時点から再実行可能である
要件2:人間にフィードバック依頼する
Callback pattern
- 人や外部システムにおける処理が介在する場合、トークンを用いてタスクに待機状況を実現する
- フィードバックループ
- 非同期チャネル
- モバイルのインターフェース
- レスポンスを返すAPI
- Choice Stateを使用した分岐
- 再生成もループ処理する
要件3:ビデオ用のアバター画像を作成する
Step Functionsでの処理の流れ
- 並列処理
- Bedrockでタイトルと説明文を生成
- 外部APIでタイトル概要生成
- 結果をブラウザの画面に表示
- ユーザーは結果を選択する
- ビデオのアバター画像を生成する
プロンプトチェーン
- 複数のプロンプトを接続し、複雑なコンテンツを生成する
- あるモデルから次のモデルに応答をフィードする
- ユースケース
- ブログを書く
- 応答の検証
アーキテクチャ
- 全体の構成:API Gateway → SQS ← Lambda → Step Functions
- タイトルと説明の生成リクエスト
- API Gateway
- ワークフローの実行
- SQSをバッファとして利用
- LambdaからStepfunctionsを起動
- タイトルと説明をUIに表示
- AWS IoT Core
- 複数から1つを選択する
- アバター画像の署名付きURLが発行される
まとめ
より効果的に、より賢く使いこなすために
- サービスフルなサーバレスによってLambdaの処理を委譲し、クラウドの中でアプリケーションを組み合わせる
- オーケストレーションとコレオグラフィを組み合わせ自律的で、拡張容易性を高めるサーバーレスアーキテクチャ
- 生成AIアプリケーションのために Step Functionsをより効果的に使いこなす
感想
本セッションで特に印象的だった点は、Lambdaの使用を最小限に抑え、AWSの各サービスや外部APIを直接統合する「サービスフル」なサーバーレスです。
サービスフルなサーバーレスにより、コード管理の負担を減らしつつ、より堅牢なシステム構築ができる点が魅力的だと感じました。
セッションで強調されていたLambdaからStep Functionsへの置き換えも学びになりました。
Step Functionsを活用することで、エラー処理、リトライ機能、可観測性が組み込まれ、カスタムコードが削減できます。
これは単にコード量を減らすだけでなく、信頼性の向上とメンテナンス性の改善にもつながります。
さらに、Step Functionsは複雑なワークフローを視覚的に管理できるため、システムの全体像を把握しやすくなります。
Step Functionsには多くのメリットあると学びましたので、今後Step Functionsの利用を検討していきたいと思います。