CloudFront の機能を洗い出す

モチベーション

CloudFrontを実務で使う機会があったのだが、全体的に何ができるか?なんの設定が必要なのか?何と組み合わせて使うと効果的なのか?がわからなかったためまとめる。

参照

20201028 AWS Black Belt Online Seminar Amazon CloudFront deep dive

Amazon CloudFront を活用したウェブサイトの可用性向上 | Amazon Web Services

CloudFrontの基本機能

AWS global networkを使用することで非キャッシュコンテンツの高速化

CloudFrontを使うとオリジンまでの通信は AWS global network を使用するためインターネット上でのルーティング回数削減などにより、高速な配信が可能になる。

フラッシュクラウドからのオリジンサーバーの保護

カスタムオリジンの場合のリクエストおよびレスポンスの動作 - Amazon CloudFront

リクエストを折りたたむという表現が使われることが多いが、大量の同時リクエストをオリジンに届かないようにしてくれる。

  • 同一オブジェクトの同時リクエストが大量に来た場合、最初のリクエストだけ即時オリジンに投げ、それ以外のリクエストは一時停止する。
  • この間にレスポンスがあれば、他のリクエストはレスポンスを使い回すため負荷軽減となる。
  • レスポンスが停止終了までに間に合わない場合は、停止後オリジンにリクエストを投げる。

キャッシュキーについて

  • CloudFrontはキャッシュキーを共有するリクエストを折りたたむ。

  • デフォルトのキャッシュキーは以下情報を含む。

    1. CloudFront ディストリビューションドメイン名 (d111111abcdef8.cloudfront.net など)
    2. リクエストされたオブジェクトの URL パス (例: /content/stories/example-story.html)

    つまり以下のようなリクエストの場合、キャッシュキーに含まれるのは赤文字部分となる。

    GET **/content/stories/example-story.html**?ref=0123abc&split-pages=false HTTP/1.1
    Host: **d111111abcdef8.cloudfront.net**
    User-Agent: Mozilla/5.0 Gecko/20100101 Firefox/68.0
    Accept: text/html,*/*
    Accept-Language: en-US,en
    Cookie: session_id=01234abcd
    Referer: <https://news.example.com/>
    

    キャッシュキーについて - Amazon CloudFront

キャッシュキーのカスタマイズ

すべてのリクエストの折りたたみを防ぐ

  • マネージドキャッシュポリシーの CachingDisabled を使用すると、リクエストの折りたたみとキャッシュをしなくなる。

DDoS 攻撃からの保護

CloudFrontでは、AWS Shield によるDDoS 保護が有効化されており、ネットワーク層/トランスポート層のDDoS 攻撃に対する緩和が自動的に行われる。

また、AWS WAF と連携することでアプリケーション層のDDoS保護も可能。

OSI参照モデル

アプリケーション層
プレゼンテーション層
セッション層
トランスポート層
ネットワーク層
データリンク層
物理層

 

DDoS耐性の高いアーキテクチャ

Behavior関連機能

配信コンテンツのGzip,Brotli圧縮機能

配信コンテンツファイルを圧縮してレスポンスすることができる。

署名付きURL/署名付きCookie

署名付きURL

  • S3の署名付きURLと仕組みとしては同じ
    • CloudFrontから発行する場合、CloudFrontのキーペアで署名されるためCloudFrontで署名検証されたものだけOACでS3に届くという形になる。
  • S3と比較したメリット
    • データ転送料の無料枠が大きい。
      • S3の外部へのデータ転送料の無料枠は100GBなのに対し、CloudFrontの無料枠は1TBであるためより大きいファイルのアップロード・ダウンロードなどがある場合に料金面で有利なことがある。
        • S3 ←→ CloudFront 間の通信料はS3リクエスト料のみかかるが非常に少額である。
    • キャッシュが使える
      • より大量のアクセスがS3にかかる場合、CloudFrontのキャッシュを使うことで高速な配信が可能になる。
    • リクエスト料金は常時1,000万リクエストまでの無料枠がある。
      • これをキャッシュと組み合わせれば、S3のリクエスト料金なしでコンテンツ配信ができたりする。

署名付きCookie

  • TODO: 後ほど記載予定

Distribution関連機能

  • 特定の国のユーザーに関するアクセス制限
  • カスタムエラーページの設定
  • キャッシュファイルの無効化

リクエストのログ記録

CloudFrontのアクセスログ保存方式は2種類ある。

  • 標準ログ (アクセスログ)
    • 選択したS3バケットに記録され、S3に保存する分の料金のみかかる。
  • リアルタイムログ
    • ログの出力は、ディストリビューションにリクエストされてから数秒以内。
    • 送信されるのは、Kinesis Data Streams で選択したストリーム。
    • 料金は、リアルタイムログ自体 と Kinesis Data Streams の使用料。

CloudFront とエッジ関数のログ記録 - Amazon CloudFront

 

 

Aurora Serverless v2 の損益分岐点の調べ方

参考記事

この記事では、Aurora Serverless v2 とオンデマンドのコストを比較し、その損益分岐点を調べます。ここでは、以下の3つの概念を使用します:

  • buffer: ピーク時に備えるための余剰キャパシティ
  • loadgap: ワークロードが低い時間帯のギャップ
  • offpeak: 非ピーク時間帯の割合

参照 logmi.jp

db.t3.medium の場合

個人的にこのくらいのスペックでプロジェクトをスタートさせることが多い。 そのため db.t3.medium の場合にどういったワークロードであれば Serverless v2 でもとが取れそうかを実際に計算してみた。

db.t3.medium

  • メモリ: 4GiB
  • vCPU: 2
  • Serverlessにする場合のACUは 2GiB/ACU なので2ACUとなる。
    • それぞれの料金はリソースをフルで使用した際のものを比較すると約3.2倍差 となる。
      # serverless
      2ACU/h×月間730時間×0.20USD=292.00USD
    
      # ondemand
      1インスタンス x 0.125ドル/時間 x (100%/月) x 730時間/月 = 91.2500ドル
    

計算式

91.25USD × loadgap × (1 - offpeak) = X
91.25USD × (1 - loadgap - buffer) = Y
(X + Y) × 3.2 = Serverless v2 Cost

buffer=0.2, loadgap=0.7, offpeak=0.9(144min/24h) の時

  • Serverless=46.53USD < ondemand=91.25USD
    • コストメリットあり。およそ1/2。

buffer=0.7, loadgap=0.2, offpeak=0.9

  • Serverless=35.04USD < ondemand=91.25USD
    • コストメリットあり。およそ1/3。

buffer=0.5, loadgap=0.2, offpeak=0.9

  • Serverless=93.44USD > ondemand=91.25USD
    • コストメリットなし

buffer=0.2, loadgap=0.3, offpeak=0.9

  • Serverless=154.76USD > ondemand=91.25USD
    • コストメリットなし

offpeakは大体0.9前後から変わらないと仮定すると、ベースラインワークロードが高くなるような場合はコストメリットがなくなる。

これほど綺麗にワークロードを計算・区分できないとは思うが、およそどの程度のワークロードであれば元が取れるかを概算するのにとても参考になった。

結論

特定の条件下ではAurora Serverless v2の方がコストメリットがある。 しかし、ワークロードが高い場合やバッファが多い場合は、オンデマンドの方が有利になることがあるのでプロジェクトの性質に応じて、最適なオプションを選択することが重要です。

jawsdays2024 Session まとめ

jawsdays2024 に参加してきました。

5年ぶりのオフライン開催だったらしく、初参加がこの会でよかったです。 以降 Session のメモまとめです。

タイムテーブル

C-1 ぼくのかんがえたさいきょうのAWSへのリソースデプロイ

CI/CDを何で実現してますか?を雑談形式で話すというものだった。

AWS CDK

  • TypeScriptなどを使えば型で縛れる。
  • プログラムの品質はCFnのYamlなどに比べるとエンジニアのレベルに左右される。

CFn

  • Yaml で書く場合、実装者によってコード品質のばらつきが少ない。
  • 最近でた GitSync を使えば、GitHub 上で CFn Template の管理ができる。

Code Catalyst

  • Gihub Actionなどのようにワークフロー形式で CI/CD を作成できる。
  • blueprint というテンプレがある。

PipeCD

  • gitopsを実現するためのツール
  • 他のものとは違いPull型のデプロイを行う。(よくわからん)

Github Action

  • OIDC機能を重宝している。
  • VPC内でなければできないテストは self-hosted runners をVPC内にたてるなどしないといけない。

Codepipeline・CodeDeploy

  • VPC内でないとできないテストがあるなら、これらを使う方が楽。

A-3 サービスクォータ、ちゃんと監視してますか?

してないです、すいません。と思って聞くことにした。

なぜしないといけないか?

  • クォータは申請してから反映されるまでにラグがあるため。

どうやる?

  • クォータモニタというテンプレートが用意されており、最低約12ドルから利用できる。
  • 様々なケースに合わせたテンプレートが用意されているので用途に合ったものを探す。
  • クォータ上限何% という設定で80%以上になったらアラートを飛ばすなどの設定をする。

クォータモニタの監視対象外ものについて

  • Lambdaの同時実行数などは監視対象とすることができない。
  • その場合、CloudWatchを使って自分で監視するようにする。

B-4 国内東西リージョンでウォームスタンバイのDR設計をした話

実際の要件として「首都直下型地震にも対応できるように大阪リージョンにフェイルオーバーされるようにしたい」というものがありそれに対応した話。

どのようにしたか?

  • Route53 にフェイルオーバールーティングを設定
  • ウォームスタンバイ戦略で待機
    • パイロットライトではRTOを満たせそうになかった。
    • ホットスタンバイではお金がかかりすぎる

課題1

  • リージョンごとのCognite間で認証情報が統一できない。
    • Cogniteで発行される認証情報はリージョンごとに異なるIDを払い出される仕様になっていた。
    • Cogniteの前段にAPI GatewayとLambdaで、東京リージョンへのアクセスは大阪リージョンのCogniteの認証情報に置き換える処理を追加

課題2

  • IaC の管理どうするか?
    • ディレクトリ構成
      • 共通リソースとリージョンごとのリソースのディレクトリに分けた。
    • どうやって同期するか?
      • 東京リージョンへ IaC デプロイ時、大阪リージョンのCodeCommitにもPushするようPipelineを構築。

DR戦略で想定していないところに注意点があることを知ることができたのでよかった。

A-6 AWS認定 Specialityレベルで満点取った時の勉強法

どうやって勉強したかについてだが、情報が常に入ってくる環境を作ったという点が学びポイント。

どうやったか

B-11 恒例!ソリューションアーキテクト怒涛のLT

Chaos Kittyの紹介

  • Chaos Engineering を体験できる
  • Chaos Kitty の紹介とともに推奨したいこととして「修正の自動化」があり、これができるところまで持っていってほしい。

QuickSight について

  • 様々なデータの可視化ができる。
  • 個人的にもっと使いこなしたい機能なので以下用途などで調べて使ってみる。
    • コスト詳細可視化
    • データ分析

CodeWhisperer について

  • AWS はテストについて Shift Left なアプローチを推奨している。
  • CodeWhisperer をIDEに組み込むことで脆弱性テストの Shift Left アプローチに繋がる。
  • これも積極的に使ってみたい。

AWS Outposts について

  • 自社データセンターにAWS Cloudを設置できるというもの
  • こちら にあるようなサーバラックごと送られてくる。
  • オンプレを設置してくれるサービスではなく、クラウドを自社におけるというイメージ。

閉域網の接続について

  • Direct Connect, VPNなどを使って閉域網は構築する。
  • Direct Connect についても冗長構成を取る必要がある。が Direct Connect×2 はコストが... そのためVPNで代替して冗長化したりする。
  • その際、Direct Connect > VPN という優先順位でトラフィックが勝手にルーティングされる。これは仕様となっている。 ただし、Transait Gatewayによるルーティングはその限りではないことに注意する。

短縮URLの作り方

  • CloudFront Functions を使うと超簡単にリダイレクト設定ができるのでこれでやる。(参照

Amazon Q について

  • Github Copilot などのような生成AIサービス。
  • CodeCatalyst のワークフロー改善を Amazon Q に任せるなどの連携ができる(参照

2023年 SQS 怒涛の変化

  • FIFOクォータ制限が3倍に。
  • DLQ からのリドライブが FIFO でも可能に。
  • リドライブがコンソールのみでなくAPIから可能に。
  • CloudTrail で SQS を流れるイベントのログ取得が可能に。

Amazon Bedrock でできること

  • 生成AIサービス
  • 自然言語からLambda関数を見つけたりできる。

Next Action

  • Amazon QuickSight 試してみる。
  • CodeWhisperer 試してみる。

サメ

DOMと仮想DOM

DOMと仮想DOMについて再入門したくなったので、Reactが仮想DOMをどう扱っているかを深堀りしてみることにした。

仮想DOMとは

仮想DOMはメモリ上で実際のDOMとは異なるDOMを持ち、検出した差分だけ実際のDOMに反映させるという仕組みを持つ。

www.commte.co.jp

Reactの差分検出アルゴリズムはどのような動きをするか?

Reactでは差分検出は React Fiber という差分検出エンジンによって行われる。

 legacy.reactjs.org

React Fiberとは

重要用語: Reconciliation

Reconciliationとは、Current Tree(現在の仮想DOM)とWorkInProgress Tree(新しい仮想DOM)2つのTreeを再起的に比較して差分を計算し、実際のDOMに必要な更新を行うプロセスのことを指します。

要は仮想DOMを木構造の差分アルゴリズムによって検出している。

React Fiberとは

図で分かるReact18のしくみ

木構造の差分検出は主にどのようにやるのか?

React15 以前は Stack reconciler というアルゴリズム(あまり一般的ではない?)で実装されており、16以降は Stack reconciler を書き直した reconciler アルゴリズム(Fiber reconcilerと呼ばれる)で実装されている。

完全な Fiber reconciler のアルゴリズムは以下のサイトが参考になりそうだ。

調べてみると意外に試してみている人もいる。

An Introduction to React Fiber - The Algorithm Behind React

15以前の Stack reconciler の実装であれば以下記事で公式がフルスクラッチでの作成手順を公開している。

 ja.legacy.reactjs.org

  1. reconciler 関数に渡された変数の型によって以下のどちらかを実行してDOMをrenderする
    • 再帰的に <App/> のようなユーザ定義コンポーネントをrenderする関数
    • div,p のようなhost要素をrenderするための関数
  2. ompositeComponent と DOMComponent という上記関数を含むクラスにそれぞれリファクタ。
  3. ライフサイクルメソッド用の関数をクラスメソッド内で実行されるようにする。

差分処理については 更新 という章で説明されている。

※ 詳細まで理解、整理できたら追記する。

 ja.legacy.reactjs.org

Reactのライフサイクルメソッドと生DOMを更新するタイミング

実際のDOMが更新されるタイミングは Mount → Update → UnMount と3つある。

DOMが更新されると以下のライフサイクルメソッドが呼ばれる。

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

上記メソッドは、現在では Hook を使って上記ライフサイクルメソッドを以下のように useEffect 代替することができる。(上記仮想DOMとDOM更新の関係性を理解するとHookという名前はジャストネーミングな気がする)

componentDidMount

useEffect( () => {
    // 初回のみ実行する処理
}, []);

componentDidUpdate

useEffect( () => {
    // 毎回実行する処理
});

componentWillUnmount

componentDidUpdate を実行する useEffect の中で定義しているため、以下コードの場合 componentDidUpdate も行われることになる。

あくまでも return(); の中が componentWillUnmount に対応する。

useEffect( () => {
    // 毎回行う処理
    return (
        // クリーンアップ処理
    );
});

projects.wojtekmaj.pl

冪等性リフレッシュトークンについて

冪等性リフレッシュトークンとは

アプリ側で使用しているアクセストークンの有効期限が切れた際、リフレッシュトークンを使ってアクセストークンを再度取得することがある。

このときトークンリフレッシュAPIを叩くが、ネットワーク遅延でリトライ処理されたり、ユーザーがボタンを複数クリックしたり、さまざまな理由から何度も同じAPIが叩かれることがある。

この時に、一定時間内のリクエストには同じ結果が返されるようにしたリフレッシュトークを冪等性リフレッシュトークンという。

やるべき理由

もし、短期間で複数回のリクエストで違う値が返されてしまう場合、適切なアクセストークンが返されず認証がいつまでも完了しないといったことが考えられる。

 

こういった冪等性はモノリスでないアプリケーションが通信する場合にどんなAPIであっても注意する必要があるため、冪等性のあるAPIを実装するための考え方という点で参考になるなと思う。

「検索範囲ではなく値範囲を使うチューニング手法がB-Treeインデックスを採用しているDBにおいてなんら無効である」について

元ネタは以下のtwitterの投稿である。

https://twitter.com/kenta_feels_ayu/status/1721553272220373238

どういうことなのか理解しておきたいと思ったので記事にします。

 

「範囲検索ではなく値検索を使うチューニング手法がB-Treeインデックスを採用しているDBにおいて何ら無効である」について

結論から言うと、B+Treeインデックスは範囲検索にも優れており、値検索を使う場合と比べてどちらも同じくらい効率的であるため意味がない。と言うことを言っている。

範囲検索に優れているとは?

B+Treeインデックスはリーフノードからリーフノードへアクセスできる連結リストを持っており、これを利用して範囲検索を高速に行える。

図解

ChatGPTにB+treeインデックスの仕組みを質問しながら図解したら以下のようになった。

B-tree インデックス


ガッツリSQLチューニングする機会がほしい。

全銀ネットのシステム構成を図解・障害の原因についても解説

モチベーション

全銀システムで障害が2023/10/10~12にかけて発生している。

この機会に全銀システムの全体像を図解して理解してみようと思う。

全銀システムの全体図

現在

・処理能力 3,000万件/1日

・現在代7世代

・中継コンピュータは中央のデータセンターにあるらしい

・中継コンピュータは全銀システムに合わせたデータの変換や計算処理などを行う

将来的な全銀システム

将来的には中継コンピュータ(RC)の廃止を検討しており、次世代ではRCとAPI Gatewayが併用され、さらに次のアップデートにて完全廃止される予定。(※3)

 

全銀システムの物理的な配置と構成

大阪と東京で冗長化されており、各RC(中継コンピュータ)は両方に接続されている。

どのシステムも待機系と正系の2つから構成されている。

日銀ネットとの違い

日銀ネットは日銀のシステムであり、全銀システムから1日の終わりに最終結果を受け取り処理する。

こちらは24/365運用ではない。

2023/10/10~12まで続いた障害ポイント

中継コンピュータのアップデートのタイミングで不具合が起こった。

内国為替制度運営費の計算プログラムで不具合が発生したとのこと(※3)

内国為替制度運営費とは、全銀システム加盟店からシステムベンダーに支払われる運用費用(参照

なぜ中継コンピュータのアップデートのタイミングで不具合が起こったのか?(2023/12/03追記)

① 金融機関名生成テーブルプログラムを32bit環境のプログラムのままコンパイル後実行

② ①で生成されたインデックステーブルがメモリ不足により破損

③ RCに展開された破損したインデックステーブルが参照されたタイミングで異常終了

※5 ※6

インデックステーブル生成プログラムで必要なバイト数の計算を誤っていた可能性が高く、その計算は手動で行われていた。

おそらくアラインメントの考慮漏れであることが考えられる。※7

 

参考サイト

※1 全国銀行データ通信システムのシステム障害についてまとめてみた - piyolog

※2 金融システムの礎 全銀システム - YouTube

※3 次期全銀システムは富士通メインフレームとCOBOLから脱却へ、何が変わるのか | 日経クロステック(xTECH)

※4 【全銀ネット障害】その時システムでは何が起きたのか? 暫定版PGで12日午前8時半に復旧(更新) | Business Insider Japan

※5 全銀システム障害の詳細を報告、64ビット化でテーブルサイズが増えて作業領域が不足 | IT Leaders

※6 全銀システム障害の原因はテーブル生成プログラムの不具合、新旧稼働環境の違いを吸収できず─NTTデータ | IT Leaders

※7 https://twitter.com/ockeghem/status/1730754578570985646?s=46&t=i61zzLbodagfIcHQLkRYtw