AWS Serverless デジタルバッジを取得する⑤　スケーリング編






[このデジタルバッジ](https://aws.amazon.com/jp/blogs/news/introducing-new-aws-serverless-digital-learning-badges/)取得のために、AWS Skill Builderの[このコース](https://explore.skillbuilder.aws/learn/lp/1585/serverless-learning-plan-japanese)を学習している記録

自分のスキルレベルは以下。
- SAAは取得
  - 4年前ぐらい
- 実務利用なし
  - 趣味レベルではあり





# Scaling Serverless Architectures (Japanese) (Sub) 日本語字幕版

https://explore.skillbuilder.aws/learn/course/14336/scaling-serverless-architectures-japanese-sub-ri-ben-yu-zi-mu-ban;lp=1585




## 大規模なサーバーレス化を検討する
- スケーリングのベストプラクティス
  - アプリケーションとデータベースを分離する。
  - AWS のグローバルクラウドインフラストラクチャの利点を活かす。
  - 高負荷を特定し、回避する。
  - パーセンタイルを監視する。
    - [Amazon CloudWatch 更新 – パーセンタイル統計およびダッシュボードの新ウィジェット](https://aws.amazon.com/jp/blogs/news/amazon-cloudwatch-update-percentile-statistics-and-new-dashboard-widgets/)
  - スケーリングに応じてリファクタリングする。
  - アプリケーションとデータベースを分離する。
- 既存AWS基盤との置き換え
  - Web層
    - ELB・NATゲートウェイ
    - API Gateway
  - AP層
    - EC2
    - Lambda
  - DB層
    - Memcached Amazon ElastiCache・RDS
    - DynamoDB
- 同時実行数
  - 同時実行数への要因
    - 呼び出しモデル
    - サービスの制限
  - 並列性
    - 同時実行数＝１秒あたりのリクエスト数＊平均実行時間
    - リクエスト率に関数の平均実行時間を乗算して同時実行数を測定。
    - 同時実行可能数を超えた場合、リクエストはスロットル。
  - Lambdaの仕様
    - 非同期イベントソースでは、失敗した、またはスロットルされたリクエストが 2 回再試行される。
      - 同期イベントソースには再試行は組み込まれません。
    - ストリーミングイベントソース (Amazon Kinesis Data Streams など) では、シャードの数で同時実行数が測定されます。各シャードでの Lambda の同時呼び出しは 1 回に制限
    - ほとんどのストリーミングサービスでは、レコード処理が正常終了するか、レコードの保持期間が終了するまで、Lambda はレコードの再試行を続行。
      - 失敗時は保持期間終了まで保持。
      - そのため、部分失敗の処理の検討が重要
    - Lambda では、ストリームがシャードごとに複数の関数を呼び出すための並列化係数がサポートされるようになりました。
      - [AWS Lambda は Kinesis および DynamoDB イベントソースの並列化係数をサポートします](https://aws.amazon.com/jp/about-aws/whats-new/2019/11/aws-lambda-supports-parallelization-factor-for-kinesis-and-dynamodb-event-sources/)



## サーバーレスサービスのスケーリングに関する考慮事項

- スケーリングに関する考慮事項
  - タイムアウト
  - 再試行動作
  - スループット
  - ペイロードサイズ

###  API Gateway のスケーリングに関する考慮事項
- API Gateway によるアクセスパターン管理上のメリット
  - Amazon CloudFront ディストリビューションが組み込まれたエッジ最適化エンドポイントを設定可能
  - オプションのキャッシュを設定で、バックエンドの負荷を軽減
  - APIキーと使用量プランでクライアントごとのリクエスト制限
  - アクセスパターンの分析
    - ユーザー
    - 場所
    - 頻度
  - AWS Lambda オーソライザー
    - リクエストパラメータを使用した呼び出し元のアイデンティティ確認
    - OAuth や SAML などのベアラートークン認証を使用するカスタム認証スキーム
    - Lambda 的には関数の一つ。
      - 実行制限数の超えないように注意
      - 認証キャッシュを有効にして、ユーザーが再アクセスした場合にオーソライザー関数が再度呼び出されないようにすることで回避可能
        - 認証キャッシュは5分～1時間

### Amazon SQS のスケーリングに関する考慮事項

- SQSのパラメータの値と上限値、パラメータの設定および変更方法まとめ


| パラメータ                                      | 値/上限                                                 | パラメータの設定/変更方法                  |
| ----------------------------------------------- | ------------------------------------------------------- | ------------------------------------------ |
| バッチに含めることができるメッセージの数        | 1～10                                                   | Lambda 関数のイベントソースで設定          |
| デフォルトのポーラーの数 (一度に返されるバッチ) | 5                                                       | Lambda サービスによって管理される          |
| Lambdaが並列ポーラーを増加させる割合            | 1 分あたり最大 60                                       | Lambda サービスによって管理される          |
| Lambda が同時に管理するバッチの数               | 最大 1,000                                              | Lambda サービスによって管理される          |
| 同時に実行できるLambda 関数の数                 | 1,000、関数の上限、アカウントの上限のいずれか少ないほう | 関数で上限 (予約済み同時実行数) を設定可能 |
| キューあたりのメッセージ                        | 上限なし                                                | 該当なし                                   |
| 可視性タイムアウト                              | 0 秒～12 時間                                           | キューで設定                               |
| 再試行の回数                                    | 1～1,000                                                | キュー (maxReceiveCount) で設定            |
| 関数タイムアウト                                | 0 秒～15 分                                             | 関数で設定                                 |

### Lambda のスケーリングに関する考慮事項



- Lambda のスケーリングに関する考慮事項
  - 同時実行数の上限
  - メモリ設定
  - 環境の再利用
- 同時実行数の上限
  - アカウントの同時実行数の上限
    - 関数の暴発の制御
  - 関数の同時実行数の上限を設定、アカウントの上限プールの一部を関数用に予約
  - 関数の同時実行数の上限を 0 に設定
    - 即時実行関数を0になり、停止
  - マルチアカウント戦略
    - AWS Organizations
      - カテゴライズ、ネストしての階層化
      - Control Towerも併用すると〇
- バースト時動作
  - Lambda 関数が実行されているリージョンの「同時実行数の即時増加」レベルまで同時実行数を即座に増加
  - その後、バーストを処理するのに十分な数になるまで、または関数またはアカウントの同時実行数の上限に達するまで、毎分 500 以上の呼び出しを追加します。
- メモリ設定
  - メモリ設定とCPUは連動している
    - 直線的スケール
    - 料金に注意
    - AWS Lambda Power Tuning も活用
      - 複数のメモリ設定で Lambda 関数を実行し、実行時間とコストにわたるフィードバックを提供するオープンソースプロジェクト
- サーバレスじゃないシステムとの連携
  - そっちがスケーラブルじゃない可能性があるので、注意。
- 環境の再利用
  - ベストプラクティス
    - 依存関係をローカルに保存して参照
      - 他サービスなどの外部ソースとすると、関数初期実行時に参照されない
      - 次回以降は参照の必要はない
    - 変数の最初期化を制限
    - 既存の接続を確認し再利用
      - 関数に接続が既にあるかを確認し、ある場合は再利用
    - キャッシュに/tmpを利用
    - バックグラウンドプロセスの完了を確認

### データベースのスケーリング
- サーバレス（DynamoDB）

| モード               | オンデマンド                                                                | プロビジョニング済み                                                           | AutoScalingによるプロビジョニング                                      |
| -------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| キャパシティー設定   | なし                                                                        | RCUとWCUを指定                                                                 | キャパシティーの上限と下限、および資料率の目標値を定義                 |
| スケーリングの動作   | 以前のトラフィックピークの２倍まで即座に処理                                | プロビジョニング済みキャパシティーを使用可能                                   | キャパシティーをスケール氏、トラフィックの増減をターゲット使用率に適用 |
| スロットリングの動作 | 次のピークが30以内に以前のピークの2倍を超えると、スロットリングされる可能性 | プロビジョニング済みキャパシティーを超過するとスロットル                       | 短時間のパースとはスロットルされる可能性。数分間であればスケール       |
| コストの検討         | R/Wに一定料金。トランザクションあたりのコストの評価が可能                   | プロビジョニング済みキャパシティーに比例。トラフィックが不変であればコスト低下 | 同左                                                                   |


- 従来のリレーショナルデータベースによるサーバーレススケーリング
  - 課題
    - 従来型リレーショナルデータベース接続をLambdaに適用した場合、固有の課題がある。
  - ベストプラクティス
    - 接続を管理する外部メカニズムを実装
      - データベースエンジンには、着信接続要求を管理し、関数間で共有できる永続的なデータベース接続を使用するプロキシプログラム
      - 動的コンテンツ管理と


### Step Functions と Amazon SNS のスケーリングに関する考慮事項

- Step Functions
  - 長時間実行タスクの調整
  - 待機状態・コールバックを使用
    - コスト削減に案る
  - タイムアウトを使用し、実行の遅延を回避
    - Amazon States 言語の TimeoutSeconds オプション
  - ステップ間のペイロード制限に注意
    - 各ステップに利用するサービスの上限に注意
  - Step Functions APIの制限を把握
- SNS
  - 並列タスクとネストしたアプリケーション開始
  - Event Fork PipelinesでSNSファンアウトをモデル化
  - Lambdaサブスクライバー利用


### Kinesis Data Streams のスケーリングに関する考慮事項
- Kinesis Data Streams
  - シャード数を増やし、スループット向上
    - エラーによるストリーム影響の軽減
  - 保持期間がタイムアウトすると処理されない
  - 拡張ファンアウト



### 参考資料
https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html

https://aws.amazon.com/jp/serverless/use-sqs-as-an-event-source-for-lambda-tutorial/

https://github.com/alexcasalboni/aws-lambda-power-tuning


https://aws.amazon.com/jp/blogs/architecture/rate-limiting-strategies-for-serverless-applications/

https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-fork-pipeline-as-subscriber.html

https://docs.aws.amazon.com/ja_jp/streams/latest/dev/enhanced-consumers.html


## ピーク負荷をテストする
### 構築、測定、学習、繰り返し
- 前提条件と意志決定の検証
  - オンプレなどと同じ内容の検証観点
  - 実データの利用してテスト
  - 統合ポイントのテスト
  - 実際のアクセスパターンでのテスト
- サーバレスの負荷テストのヒント
  - サービスの制限を監視
  - ツール利用
    - Amazon CloudWatch など。
  - DynamoDBを使用したテストはAutoScaling・オンデマンドモードを利用
  - ワークロードを掘り下げてテストを設計

### テストの心得的なもの
※いい言葉なので原文ママ
※コース内でも大切なことなので２回記載されていました。

負荷テストのための良いヒントを 1 つだけ挙げるとすると、それは、どの状況でも 100% 適用できるようなヒントやベストプラクティスはないということです。ワークロードを深く掘り下げておく必要があります。それをテストし、本番同様の条件下でそれをモニタリングします。

- テストのヒント
  - サービスの制限を監視します。
    - サービスの制限は、お客様をサービスの不正使用から保護するために設けられています。制限が適切にモニタリングされていないとサービスの低下またはスロットリングおよび追加コストが発生する可能性があります。多くの制限はソフトリミットです。制限の引き上げをリクエストできます。
  - テスト中および本番環境に移行するときは、利用可能なすべてのモニタリングツールを使用します。
    - Managed Services には、Amazon CloudWatch でモニタリングおよびアラームを設定できるログとメトリクスが組み込まれています。
  - 制御できないサービスのモックは作成しないでください。
    - 本稼働環境と同じ AWS 環境のサービスを使用して、統合テストとロードテストを実行します。
  - DynamoDB を使用する場合は、テストする負荷を処理するキャパシティーが設定されていることを確認してください。
    - パフォーマンステストのサイクルに対応するには、オンデマンドモードまたは Auto Scaling を使用します。


### 参考資料


https://aws.amazon.com/jp/blogs/architecture/ten-things-serverless-architects-should-know/


## まとめ・その他。

全体的に、トランスクリプトの中身に大切に有用な情報が散らばっていた気がします。
ナレッジチェック（確認テスト）でバグというか、Ture/Falseを紐づける問題でTure/Falseであるかではなく、選択肢の場所が内部的に指定されているのでエラーとなるものがありました。
ここまでくると、重複した内容もあるように見えます。