AWSアソシエイト試験に向けて11( ElastiCacheとCloudFront）

## はじめに

両方とも主にキャッシュを利用することで様々な恩恵をサービスに齎すために利用するサービス。

## ElastiCache

- ベストプラクティスではキャッシュの利用と最適なデータベース選択の分野に入る
- Well-Architected Frameworkではパフォーマンス効率の分野に入る
- S3と連携することが基本的な使い方になる
- インメモリ型DB、つまりメモリにキャッシュを保存する仕組みなのでディスク型DBに比べて処理は早くなる
- 分散型インメモリキャッシュサービスでフルマネージド型である
- キャッシュクラスタを手軽に起動できる
- フルマネージドで自動障害検出、復旧、拡張、パッチ適用、バックアップに対応と高可用性が期待できる
- DBエンジンとしてはmemocachedかredisが選択できる

ユースケースとしては以下のことが考えられる。

- セッション管理
- IoT処理とストリーム分析
- メタデータ蓄積
- ソーシャルメディアのデータ処理・分析
- Pub/Sub処理
- DBキャッシュ処理

また以下のようなデータを即時反映させる必要があるような処理にも有効である。

- ユーザーのマッチング処理
- レコメンデーションの結果処理
- 画像データの高速表示
- ゲームイベント終了時のランキング表示

キャッシュすべきデータを特定して、他のDBと連携して活用することでDBへのアクセス負荷を抑制し、可用性の低下を防ぐ。


### Redis

- 高速に値を読み書きできるインメモリキャッシュ型DB
- シングルスレッドで動作するインメモリキャッシュDBですべてのデータ操作が排他的である
- Snapshot可
- データの永続化が可能
- Luaスクリプト……移植性が高く、高速な実行速度などの特徴を持っているスクリプト言語が利用可能
- 位置情報クエリ……緯度経度などの位置情報をクエリ処理することが可能、検索距離や検索範囲の指定もできる
- pub/subモデル……イベントを起こす側(pub)、イベント処理を行う側(sub)を分離するという思想のモデルで、メッセージ処理・イベント処理で活用する

こちらを利用するケースとして考えられるのは以下の通り。

- 複雑なデータ型が必要である
- インメモリデータセットをソートまたはランク付けする必要がある
- 読み込み処理の負荷に応じて、リードレプリカにレプリケートをする必要がある
- pub/sub機能が必要
- 自動的なフェイルオーバーが必要である
- キーストアの永続性が必要である
- バックアップと復元の機能が必要である
- 複数のDBをサポートする必要性がある

### Memcached

- 高速に値を読み書きできるインメモリキャッシュ型DB
- マルチスレッドで動作するインメモリキャッシュDB
- Snapshot不可
- データ永続化も不可
- フェイルオーバーや復元も不可

こちらを利用するケースとして考えられるのは以下の通り。

- シンプルなデータ型が必要である
- 複数のコアまたはスレッドを持つ大きなノードを実行する必要がある
- システムでの需要増減に応じてノードを追加または削除するスケールアウト及びスケールイン機能が必要である
- DBなどのオブジェクトをキャッシュする必要がある
- キーストアの永続性は必要ない
- バックアップと復元の機能が必要でない
- 複数のDBを利用できない要件である

つまり、一時的な処理や簡便に利用したい場合の選択肢がこちらになる。

## CloudFront

AWS提供のCDN(Content Delivery Network)サービス。
CDNはWebコンテンツ配信処理を高速化するためのサービスであり、もう少し踏み込んで言うとサーバーでキャッシュを利用することで負荷を軽減させつつ処理を高速化させるという仕組みのものである。
どういうことかというと、`https://www.example.com`というWebページへアクセスした場合CDNの仕組みがあるとDNSサーバーは`https://www.example.com`のIPアドレスを返すのではなく、CDNサーバーのCNAMEを返す。
そうすると、アクセスはCDNサーバーへと迂回され、そちらにキャッシュがあればそこからWebページを送信し、キャッシュがなければそこではじめてオリジンサーバーへとアクセスをパスするということらしい。

[参考: ネットの大規模障害が起きた「CDN」って何？実際にアクセスして確かめてみた](https://pc.watch.impress.co.jp/docs/topic/feature/1330779.html)

で、CloudFrontの場合はIoTや末端デバイスに置かれることでリアルタイムでそれらの端末からデータの収集・処理・分析を行い、クラウドサーバーと連携するエッジサーバーとしての役割も持つことでその特性がより際立つ……ということになるのだと思う。

[参考: エッジコンピューティングとは？](https://www.sbcloud.co.jp/entry/what-is-edge-computing)

- 210以上のエッジロケーションによる高性能な分散配信を行う
- AWS WAF、AWS Certificate Managerとの連携やDDoS対策によるセキュリティ機能を持つ
- オリジンに対してHeader、Cookie、Query Stringsによるフォワード指定で、動的なページ配信が可能である
- エッジサーバー(エッジロケーション)とオリジンサーバの間にさらにリージョナルエッジキャッシュと呼ばれるものをかませることでより効率的に配信を行う
- AWSがAmazonの特性を生かしてグローバルにエッジロケーションを持っているので、配信ネットワークもまたグローバルに展開できる
- 独自ドメインを指定可能
- エッジ側でGzip処理をオリジンからの配信されたコンテンツに対して行うことでより高速に配信が可能

使い方としては

- 各配信先となるドメインにCloudFrontを個々に設定して割り当てる
- 作成はマネコンやAPIから
- Web Distributionのみ可能(RTMPは廃止)
- 使用量が最大40Gbps/10万RPS超になるときは上限緩和申請をする
- コンテンツ利用データ分析を実施し、結果から判断して静的・動的コンテンツへのキャッシュ対象URLを設定する
- 変更が反映されるまでの時間も考慮して、TTLを設定する(キャッシュ時間のこと)
- セキュリティ対応等の非機能要件の要否を検討する(SSL認証の有無、HTTPSの有無等)

具体的には

- コンテンツオリジン設定……CloudFrontの配信ファイルの取得先の設定をする
- アクセス設定……ファイルアクセスの許可設定
- セキュリティ設定……アクセスにHTTPSを利用するかの設定
- Cookieまたはクエリ文字列転送の設定……オリジンへのCookieまたはクエリ文字列転送の要否の設定をする
- 地域制限……特定の国のユーザーからのアクセス拒否設定
- アクセスログ設定……アクセスログを作成要否の設定をする

ということになる。

### WEB Distribution

CloudFrontで設定できるもの。
RTMPという主にAdobe Flashの配信を行うために利用されていたメディアファイルのストリーミングのための設定もあったが2021年に廃止。
WEBの方は以下のような仕様となる。

- 通常のHTTPプロトコルを利用したWEB配信をする際に利用する
- HTTP1.0、HTTP1.1、HTTP2に対応する
- オリジンはS3バケット、MediaPackageチャネル、HTTPサーバーを設定
- HTTPやHTTPSを使用した静的および動的なダウンロードコンテンツ配信を行う
- Apple HTTP Live StreamingやMicrosoft Smooth Streamingなど様々なビデオオンデマンドに対応

### キャッシュコントロール機能

キャッシュヒット率を上昇させて効果的にキャッシュ活用を行う。

- URLとフォワードオプション機能(header、Cookie、Query Strings)のパラメーター値の完全一致でキャッシュが指定される仕組み
- 単一ファイルのキャッシュは最大20GB
- GET、HEAD、OPTIONリクエストに対して利用できる
- キャッシュの期限切れを待たずに無効化することが可能
- 必要のないキャッシュを無効化することで効果的な利用を可能にする
- コンテンツごとに最大3000個まで無効化パスを指定できる
- ワイルドカードを利用して最大15個まで無効化パスリクエストが指定可能

### セキュリティ機能

様々なセキュリティ設定によるセキュアなコンテンツ配信を行う。

- SSL証明書を設定して、コンテンツ配信時のHTTPS対応を行うことでビューワーアクセスとオリジン配信の暗号化通信が可能
- オリジンカスタムヘッダーによる通信制御が可能
- AWS WAFによるファイアウォールと連携して、これらのDistributionに対するWebリクエスト許可やブロックが可能
- Referer制限によるリンク参照禁止も可能
- S3バケットからの配信の際にOAIとCloudFrontを指すカスタムドメインによってアクセス制限を行う
- AWS ShieldによるDDoSに対応
- 署名付きURL/Cookieによる有効期限指定
- GEOリストリクションによる地域情報でアクセス判定を行う

## ハンズオン

### ElasticCache

ウィザードに従って進めていく。
RedisとMemocachedとで設定する項目は大幅に変わる(Memのができないことが多い)。

![2021-06-15_23h35_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/764eb814-9423-a3a7-724d-cecee060cf9e.png)
![2021-06-15_23h35_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/90b6af94-cbe1-e6e8-b3be-1ab1dbc6ef5b.png)

できるとこんな感じで設定した通りシャードが3つできているのが確認できる。
![2021-06-15_23h49_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/b2efc6f2-5c4f-6ba6-ddad-a2a9770f0213.png)

作ったElastiCacheのプロパティ。
アクセスするには指定エンドポイントの値が必要になる。
最後の下4桁がポート番号になるのでウィザードで指定したセキュリティグループでトラフィックを許可するように設定しておく(もしくは許可してから設定する)
![2021-06-15_23h49_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/1cc3b64d-d7f7-ee6d-6977-5c3ffc73ab00.png)

各種設定画面。
![2021-06-15_23h49_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/a2bbab98-ab86-8476-e7fa-8e2654484df3.png)
![2021-06-15_23h50_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/97dc5d0f-cfaa-1538-acec-ce77f3ca9b9a.png)

### 実際にEC2インスタンスからアクセスして使ってみる。

予めEC2インスタンスにredisを入れておく(`sudo amazon-linux install redis4.0`)。
下記のようにデータのセットと取得ができていることが確認できる。
![2021-06-15_23h58_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/3945674e-5cca-5d31-79d7-b302bdd30c71.png)

### CloudFront

同じようにウィザードで設定していく。
ODNにはELBとかドメインなどを指定する、今回はELB。
![2021-06-16_00h58_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/5112e06a-c246-7621-3855-0b7778d3df73.png)
TTLでキャッシュの時間を設定する。
Use legacy cache settingsにチェックを入れないと出てこない。
![2021-06-16_00h59_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/cbf9ffef-ff0c-7095-ded4-c3a05d320f7a.png)
![2021-06-16_01h07_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/277abc36-fb80-eb67-2710-5ed8613db6ba.png)

作成すると以下のように出来上がる。
![2021-06-16_01h19_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/6520e335-5b25-cebc-daca-1f6044b03713.png)

プロパティは以下の通り。
Domain Nameの部分を後で使う。
![2021-06-16_01h19_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/6701eaa1-e1a3-646b-f662-189d9b491952.png)

各種設定部分。
オリジンを追加したり、オリジンのグループを設定したりできる。
![2021-06-16_01h19_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/24a87f84-e568-9ceb-6dd5-29853f6dca89.png)
パスを設定して、キャッシュの動作を設定できる。
![2021-06-16_01h19_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/904220cc-3b2e-d9fb-52a5-5266b2dde09b.png)
エラーページの設定
![2021-06-16_01h19_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/8cd15b23-ef5f-f46d-1ec9-de83ab64bfa5.png)
制限を設定できる。
![2021-06-16_01h20_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/523f55d6-97aa-c991-70d5-b9ca2d0fc9ab.png)
キャッシュの無効化に関する設定。
![2021-06-16_01h20_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/bd2ac45d-529f-70ef-1186-a0b0ed41c39f.png)
タグ。
![2021-06-16_01h20_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/04c620f4-b7ee-f81d-d997-636a1e5c0414.png)

各種メトリクス。
まず、統計的なレポートはこの項目。
![2021-06-16_01h23_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/1a523d4a-72de-c1d4-f4ac-fd0fe39e94d2.png)

次にMonitoring and Alarmsの部分。
ここはudemyの講座とは変更されて下記のように変更になっていた。
![2021-06-16_23h08_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/cf99dda1-d2e5-3e01-ff69-b16860458cb0.png)
![2021-06-16_23h08_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/f42a4e0a-b2ae-c7c6-4cab-e603f3b376fe.png)

Popular Objects Reportではどのコンテンツが配信でよく使われるのかを確認できる。
要はここでよく表示されるコンテンツに対してキャッシュを設定しようということ。
![2021-06-16_01h26_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/58158aae-3089-27dc-8ca6-d57c6db4a607.png)

今度はこちらから参照されやすいコンテンツを確認することができる。
![2021-06-16_01h27_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/01d83c93-f832-852f-b0f6-e1583d752210.png)

利用状況のレポートはこちらから。
![2021-06-16_01h27_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/84f6352f-6c7a-b3eb-9deb-fe18de3daab6.png)

どんなデバイスやブラウザ、及び場所からコンテンツが見られているのかを確認できる。
![2021-06-16_01h28_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/11f81d22-cab9-19f7-9939-3c7eb956dacf.png)

S3からのコンテンツ配信の際に、アクセスを設定するための設定を行える。
![2021-06-16_01h29_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/5a545d0e-d005-e93a-cd3c-381ece2cb28d.png)
こちらはフィールドレベルのEncryption(暗号化)を設定するためのPublic Keyを作る場所。
![2021-06-16_01h30_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/e13efb0c-b175-7fde-8434-f772672ecff6.png)
作ったキーはこちらで使う。
![2021-06-16_01h30_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/fc6c56c7-668f-2333-e557-9af44740a7c0.png)

### 実際の動作を確認してみる。
まずはこちらのドメイン名を直接URLに叩き込む。
![2021-06-16_01h31_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/196069ff-a2ac-e27e-cb29-beb12d50e5ca.png)
キャッシュがある場合は、とりあえずEC2Webサーバーからindex.htmlの内容が返ってくる。
ちなみに構成はマルチAZでELBで2つのAZのPインスタンス(Webサーバー)をロードバランシングしているというものになっていて、先程設定したようにCloudFrontはこの場合ELBに置かれている。
![2021-06-16_01h47_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/ee223686-c044-20ba-8d83-5a5d8332e7be.png)
では、index.htmlの内容を変えてみる。
![2021-06-16_01h48_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/3f59d371-40a0-2b6b-7395-9acc56d374ca.png)
TTL設定した時間を置いて確認してみるとキャッシュも変わっているのが確認できる。
![2021-06-16_01h49_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/cd40636a-27fa-6e97-1d39-535e299768a8.png)