AWS Cloud Practionerへの道 #1 クラウド・コンピューティングの基本

AWS Summit 2023に参加してAWSちゃんと基礎から学ぼうと思ったのでAWS Cloud Practioner取得目指します。AWSはEC2でサーバー立てたりAmplifyつかってWebアプリを立ち上げたりした経験があるぐらいですが、そのサービス周りしか知らないのでクラウド初心者視点のメモとして残していきます。

AWS Skill Builderでの勉強を中心にしていきます。
https://skillbuilder.aws/

## AWS Cloud Practionerとは何か

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

> AWS Certified Cloud Practitioner は、AWS クラウドの概念、サービス、および用語の基礎的な理解を提供します。過去に IT やクラウドの経験がない非技術職の方や、オンプレミスでの IT 経験があり、AWS クラウドへの基本的な知識が必要な方にとって、良いスタート地点となる資格です。この認定は、ロールベースの AWS 認定に挑戦する候補者に自信を与えてくれます。

つまりAWSの基礎ですね。AWS Cloud Practioner(以下AWS CP)は非IT系の方向けでもあるので、アジャイルコーチでエンジニアのバックグラウンドがある自分としてはちゃんと理解したいところ。

## クラウドとは何か

クラウド前はオンプレミスと呼ばれる、サーバーやらネットワークやらそれらを動かす/それらの上で動くソフトウェアすべてを自前で用意し自分たちで管理する方法でクライアント・サーバーモデルを実現していた。それがそのサーバーやネットワークやソフトウェアをAmazonが用意し、インターネットなどのネットワーク越しにそれらを柔軟に使えるようにしたのがクラウド。つまり、ハード＆ソフトのインフラやアプリを専門の会社に任せながら、自分たちはアプリケーション開発に集中できる時代がクラウドによってもたらされた。

AWSはなぜたくさんサービスがあるのか、なぜなら、ビジネスが必要としているから。一般的なMySQLやLambdaだけを提供していてもビジネスの差別化には繋がらない。その中のコードや様々なサービスの組み合わせが、ビジネス上のアドバンテージを作る。インフラの準備にお金や時間をかけず、そのアーキテクチャーやコードの部分、ビジネスのコアの部分に時間をかけられるのがクラウドの最大のメリット。

### クラウドの何がいいの？

多くのコストメリットがあります：

- インフラ構築の費用と時間がかからない
- Pay as you go（従量課金）なので使わないとお金がかからない
- 小さな状態から始めやすい（初期費用がないかつ従量課金なので）
- 必要性に合わせた動的なスケールの自動化も可能
- 必要な容量の計算などはいらない（クラウドの利用料の計算はいる）
- スケールメリット

他にも色々メリットたくさん：

- 高いセキュリティ
- スピードと俊敏性の向上
- 数分でグローバルに展開
- 高い可用性（事業継続性）
- 世界展開がしやすい（ロケーションが豊富）
- 通信のレイテンシーを抑えられる（ロケーションやエッジサーバーの活用）
- たくさんのサービスで大抵のことは実現できる（もちろん知識は必要！）

## EC2 (Elastic Compute Cloud)

EC2はバーチャルなサーバー。オンプレミスの時代ならサーバーのスペックを選んで、注文して、届くのを待ってセットアップして……買って使わなかったり違ったと思ってもそのどでかいサーバーはそこにあり続ける。バーチャルなサーバーなら必要な時に必要なスペックを選んで数分で開始終了できます。EC2は実行中のサーバーのインスタンスにだけ課金されます。つまり必要ないときは魔法のようにお金がかかりません。

- フレキシブル
- コスト
- 迅速性

実態としては１台のサーバーの中にスーパーバイザーが居てそのサーバーのリソース（CPUパワーやメモリ）をバーチャルサーバーでどう使用するかをそのスーパーバイザーが命令しています。

EC2はその設定が様々に用意されていて、Windows, Linux, 自前のアプリ、サードパーティのアプリなどあらゆるサーバーを建てることができます。

EC2は自分のやりたいことに対して適した特性や性能を持つインスタンスタイプを選ぶことができ、性能もネットワークもカスタマイズできます。

インスタンスタイプ

- 汎用（バランス型、アプリケーション、ゲームサーバー、小中規模DB）
- コンピューティング（ゲームサーバー、ハイパフォーマンス、バッチ処理ワークロード）
- メモリ（インメモリデータベース、非構造化データのリアルタイム処理）
- 高速コンピューティング（浮動小数点処理、グラフィック）
- ストレージ（データのパフォーマンス）

また、課金の形態も色々ある

- On-demand （オンデマンド）
    - インスタンスタイプに応じて時間単位か秒単位で課金
    - 1年を超えるような長期間の利用が見込まれる場合はReserved Instancesの方が安くなるため推奨
- Savings Plan
    - 1年か3年単位の契約で、最大72%の割引
    - 契約を超えるインスタンスの利用料は通常料金かかる
- Reserved Instances
    - 1年か３年単位の契約で、最大75%近くの割引
    - 予測可能なワークロードに対して予約する
    - 期間が切れるとインスタンスを停止するか、新たなReserved Instanceを購入しないと通常料金がかかる
- Spot Instances
    - 利用されていないインスタンスをスポット活用し、最大90%近くに割引
    - インスタンスに空きがない場合は後回しにされる
    - AWSはインスタンスを2分の警告とともに利用権を得る
    - バッチ作業や空いている時間に進める作業に向いている（中断可能なワークフロー）
- Dedicated Hosts
    - 物理サーバーの単位で契約する
    - コンプライアンスの遵守のためなどに使われる
    - 料金が高い（そりゃそうだ）


## スケーラビリティとエラスティシティ

顧客のシステム利用量は時期により異なる。ECであればセールやクリスマスには利用者が増えるように。オンプレだと、この問題に対してハードウェアをどう用意するかは２パターン考えられる。１つは、サーバーのワークロードの平均や中央値に対応できるスペックを用意する、もう１つは、サーバーの高負荷時に対応できるスペックを用意する、という２パターン。平均に対応できる場合は平均のケースまでは問題なく顧客からのリクエストをさばけるが、平均を超えると顧客の利用体験が損なわれるような性能低下を招く。高負荷時に対応できるスペックでは、顧客は不満を覚えることはないが、コストが高く付く。

クラウドでは、この問題に対して、動的にリソースを提供することで、負荷の問題もコストの問題も同時に対応している。これがスケーラビリティ（規模や利用負荷に応じて動的な対応ができること）。EC2 Auto Scalingでは２つのアプローチがとれる。ダイナミックスケーリングと、プレディクティブ（予測）スケーリング。

- ダイナミックスケーリング：負荷の増加に応じて、インスタンスを追加する
- プレディクティブスケーリング：予測できる負荷の増加に対して、インスタンスを予約する

組み合わせてもいい。これらのスケーリングをどう自分のEC2に対して行うかはEC2 Auto Scalingというサービスで、インスタンスの最小値(Minimum)、希望値(Desired)、最大値(Maximum)を設定し柔軟に対応可能。Desiredっていうのがどういうことか分かりにくいが、基本Auto Scalingに任せるならMinimu=DesiredにすることでMaximumまでの間、自動でスケーリングしてくれそう。

またスケーリングについては２パターンの考え方ができる。

- 垂直スケーリング（スケールアップ）
    - サーバーのスペックを高くする
- 水平スケーリング（スケールアウト）
    - サーバーを並行して走らせて負荷を分散させる

EC2はオートスケーリングで需要に合わせてインスタンスの追加削除を自動でやってくれる。

## トラフィックの問題

リクエストが来た時に、トラフィックがどのインスタンスにより捌かれるかを決める必要がある。均等にトラフィックを分散させ、負荷を分散させる必要がある。これをロードバランシングと呼びます。そのためのインスタンスが必要で、AWSではElastic Load Balancing (ELB)を提供している。
ELBはRegional Construct、つまりリージョン単位で動作する。ELBはスケーラブルでトラフィックが増えた場合、コストを増やすことなく適切なインスタンスへトラフィックをさばく。ELBは外からのトラフィックだけでなくAWSのシステムの内部のトラフィックのコントロールにも使われる。スケーリングに伴い、増減したインスタンスへのルートの追加削除もしてくれる便利なやつ。これにより、フロントとバックで切り離されたアーキテクチャーでも、お互いがお互いのインスタンスの数を気にせずに連携できるとのこと。


## メッセージングとキューイング

リクエストの受け取りとその処理の実行が同期的な場合、処理が完了するまで次のリクエストが受け取れなくなる。リクエストを受け取り、それを処理するためのキューに追加することで、実行は非同期的になりリクエストを捌けるようになる。

1. リクエストを受け取る
1. キュー（順番待ち）に入れる
1. 処理はキューにあるリクエストを来た順に実行していく

キューがあることで、システムの繋がりが密結合から疎結合になる。疎結合になることで、例えば処理を実行する側のインスタンスが落ちたとしても、キューに実行予定が残っているので、インスタンスが復活すれば処理が再開できる。これが密結合で１つのインスタンスの中で行われていると、キューの仕組みがあってもインスタンス全体へのエラーで、リクエストの受け取りも、キューの処理も、バックエンドの処理もすべてに影響が生まれてしまう。

### Amazon Simple Que Service SQS

キューの仕組みを持ったサービス。

- メッセージの送信
- メッセージの保存
- メッセージの受信
- ソフトウェアのコンポーネント間の連携

マクドナルドのオーダー番号が書いてあるディスプレイのイメージ。メッセージ内のデータはペイロードと呼ぶ。たとえば、オーダー番号、実際に頼んだ商品の情報。

### Amazon Simple Notification Service

Publish-Subscribe(Pub-Sub)モデル。SNSのように、Publish（発行）したらSubscribe（登録）している人にメッセージが届く仕組み。Subscriberは様々な設定ができる。例えばWebサーバー、Eメールアドレス、AWS Lambda、その他色々設定が可能。Subscribeの単位も細く設定ができ、例えば興味のあるトピック単位でのSubscribeをして情報発信できる。例を挙げるとすれば、年齢ゾーンに合わせたSubscribeなどが実現可能。

## その他のコンピューティングサービス

EC2はバーチャルマシーンなのでかなりフレキシブルでスケーラブルだが、インスタンスの管理が必要であったり、コストが多少かかったりする（それでもオンプレミスに比べたら楽で安い）。そこで選択肢としてサーバーレスなサービスがある。

サーバーレスなサービスは、サーバーマネジメントレスととらえるといいかも。スケーリングやパッチの適用などは開発者は気にする必要がない。どういう違いがあるか、EC2とLambdaを例に開発者としてのざっくり作業を表すと以下のような形：

- EC2
    - インスタンスのプロビジョニング（スペック、スケーリング、その他の設定）
    - インスタンスの環境構築
    - コードのデプロイ
    - インスタンスの管理
- AWS Lambda
    - コードのデプロイ
    - トリガーの設定

### AWS Lambda

アプリケーションのコードだけを用意して、トリガーが引かれればアプリケーションが実行される。トリガーが引かれる量が多ければ、Lambdaは自動でスケールする。ただし15min以下の動作制限があるため、機械学習やレンダリングなどには向いていないが、多くのWebサービスでは有効活用できる。処理の分割などで大きなワークロードもなんとかできそうな気もするが、それも同時実行数に制限がある。

参考：[落とし穴にハマるな！AWS Lambdaを利用するときの6つの注意点](https://www.skyarch.net/column/aws-lambda-important-point/)

Lambdaはリクエスト数と利用時間（ミリ秒単位）での課金。ミリ秒単位ってすごいな。以前は100ミリ秒単位で、切り上げでの請求だったようなので、軽い処理が50ミリ秒で終わるものであれば半額で済むということ。親切だなぁ。

### Amazon Elastic Container Service

DockerのContainerのサービス。EC2インスタンス上で動作するコンテナを管理することが可能。

### Amazon Elastic Kubernetes Service

KubernetesをAWSで実行するためのサービス。Kubernetesはオープンソースで、AWSはKubernetesコミュニティとも協働しているとのこと。

### AWS Fargate

ECSやEKSはEC2に展開が可能だが、EC2のマネジメントが面倒ならばAWS Fargateというサービスを使うこともできる。EC2はコンテナ向けのサーバレスサービスで、サーバーのプロビジョニングや管理が不要になる。Fargateを選ばずにEC2を選ぶ理由はあったりするんだろうかと気になるな。より細かな管理をしたい場合？

2018年のものですが公式の情報がありました：[EC2 or AWS Fargate?](https://containersonaws.com/introduction/ec2-or-aws-fargate/)

- 大きなワークロードで、金額的な最適化がしたいならEC2（割引を活用する場合）
- 小さなワークロードで、たまにスパイクがあるならFargate
- とても小さなワークロードやバッチならFargate（EC2を起動し続けるのに比べて金額的に効率的）

## まとめ

- Cloud Computingとは利用量に応じて利用料を払う
- スケールはVerticalとHorizontalの2つがある
    - Vertical: インスタンスのスペックをあげる
    - Horizontal: インスタンスを複数起動する
- EC2はスペックをあげることでVerticalにスケールできる
- EC2は複数インスタンスを起動することでHorizontalにスケールできる
- Auto Scalingを使うことで設定に応じた自動的なインスタンスの増減を実現できる
- スケールで増減するインスタンスへの負荷をElastic Load Balancingで自動対応
- サーバーレスサービスはプロビジョニングや管理が不要で開発者はアプリに集中できる
    - 反面、細かな管理やユースケースによってはEC2が適していることも
- コンテナ(Docker, Kubernetes)も使える

### 個人的メモ

- EC2のインスタンスタイプで何がどれに適しているかを把握すること
    - General purpose 汎用
    - Memory-optimized メモリ最適
    - Compute-optimized コンピューティング最適
    - Storage-optimized ストレージ最適