「AWS定番業務システム14パターン設計ガイド」を読んだ

AWSで用意されているサービスを学ぶために、この本を読んでみました。
様々な定番業務システムを例にどのようなサービスを組み合わせて構築するのか、わかりやすく書いてあったので ポイントをまとめました。

1章 Webシステム

1-1. パターン1: キャンペーンサイト

  • アクセス数は多くないと想定すると高いマシンスペックは要求されない。
    LAMP環境が動く最小構成でスタート(例: t3.medium)。運用しながら必要に応じてスケールアップを検討する。
  • 短期間限定での公開、かつコスト優先という前提。
    冗長化やバックアップは考えない。

1-2. パターン2: コーポレートサイト

  • マーケティングやコミュニケーションのツールとして重要度が高い。
    →複数のEC2インスタンスとELBを組み合わせてWebサーバーを冗長化
    →RDSのレプリケーションによるDBの冗長化
  • 静的コンテンツを中心に閲覧する。
    CDNとS3を使ったキャッシュした静的コンテンツの配信でEC2の負荷を下げる。
  • 安定的なレスポンスが求められる。
    →「EBS最適化利用」と「プロビジョンドIOPS」の利用により専用のネットワーク帯域を確保。
  • 数年単位の長期間の利用が想定される。
    →年単位でインスタンスの利用を予約する「リザーブインスタンス」を使い、利用料金を割引。

1-3. パターン3: 性能重視のイントラWeb

  • 時期によって負荷が変動する環境下でもレスポンスを確保したい。
    →CloudWatchでインスタンスを監視し、処理能力の低下をトリガーにAuto Scalingで自動スケールアウト。
  • ピーク時でも数秒以内のレスポンスを確保したい。
    Amazon ElastiCacheでインメモリーでキャッシュし、参照頻度の高いデータに高速にアクセスできるように。
  • 高速なRDSを利用。RDS for AuroraはRDS for MySQLの最大5倍の性能。

1-4. パターン4: 可用性重視のイントラWeb

  • 災害時にも業務継続できるようにしたい。
    →同リージョン内でもAZをまたいだ構成にする。
    →CloudWatchで障害を検知してEC2の自動復旧。
    →リージョン間の冗長化。(RDSやS3のレプリカ機能、Route53のDNSフェイルオーバー機能)
    →予算に応じたバックアップ方式を選定する。(Active/Active, Active/Stanby)

2章 ストレージシステム

2-1. パターン5: バックアップ

  • オンプレミスの複数社内システムのバックアップをAWSに取りたい。
    →Storage Gatewayが稼働するバックアップ用のストレージをオンプレミスに用意し、S3に自動バックアップ。
  • 容量の大きな画像ファイルやデータベースファイルのバックアップ。
    →SGの従量課金を抑えるためS3のAPIを使ったスクリプトでアップロードする。
  • ログファイルとデータベースファイルは長期間保存する。
    →S3の機能でバージョン管理しつつ、保持期間を超えたファイルはGlacierにアーカイブすることでコストを抑える。
  • 重要データをセキュアにバックアップしたい。
    専用線(Direct Connect)を使う。相互接続ポイントまでは通信事業者の専用線接続サービスを使う。

2-2. パターン6: ファイルサーバー

  • AWS環境のシステムのファイル管理にファイルサーバーを使う。
    →アプリケーションからEFSをファイルサーバーとして利用。
  • オンプレのイントラネットで使うファイルサーバーは容量が大きく、頻繁に利用する少数のファイル、長期間保存する大量のファイルがある。
    →S3にバックアップを作成し、高頻度にアクセスされるファイルはオンプレにキャッシュする。(階層型ストレージ)
  • 営業担当者がモバイル端末からファイルへアクセスする。
    →権限管理、アクセスログの取得などができるWorkDocsを利用する。WorkDocsへのログイン認証はSimple ADを利用する。

    3章 データ分析システム

    3-1. パターン7: 構造化データの分析

  • 構造化データ(今回はRDBに格納されたデータ)を分析するシステムを素早くスモールスタートさせたい。
    →Redshiftを利用した分析を行う。既存システムのDBからのデータ取得はAWSパートナー製品のFlydata syncを使う。必要なテーブルのみ選択してRedshiftへデータ連携できるのでコストが抑えられる。
    →Redshiftへの接続はTableau Desktopを使うことで接続のための開発が不要になる。
    →まずは最小サイズのクラスターで構築し、必要に応じてスケールアウトさせる。
  • 経済統計や国勢調査など外部データも分析対象として取り込みたい。
    AWSがオープンデータを提供するEBSパブリックデータセットというサービスを利用。EC2にアタッチしてS3に一旦格納してからRedshiftへ格納する。

    3-2. パターン8: 非構造化データの分析

  • アクセスログやアプリケーションログなどの非構造化データを分析するシステムを構築したい。そのためにログの集約、分析できる形式に変換する必要がある。
    →FluentdでログをS3に集約、Amzon EMRとHiveでログをクレンジングし分析に必要な情報のみを抽出、変換する。
  • マーケティング担当がアドホックな分析を、他部門が定型的な分析をする。
    →Tableau Desktopでアドホックな分析を実施。定型的な分析結果はTableau Serverで公開する。

    3-3. パターン9: AIとIoT

  • 部品の検査工程のうち目視でチェックしている一部の工程をAIで代替したい。検査装置が撮影した画像をAI処理して良品、不良品の判定を行う。
    →検査の判定をエッジ側で行うことでネットワーク遅延による判定が間に合わないことを避ける。
    AWS Greengrassで機械学習のインフラ管理を効率化。エッジとクラウドで強調処理をするアーキテクチャーを実現する。
  • 機械学習の開発、実行環境の管理を効率的に実現したい。(フレームワークを柔軟的に変えながら最適なアルゴリズムを探していきたい)
    →SageMakerを使うことで事前にセットアップされたフレームワークごとの実行環境を自動構成。

4章 アプリケーションの高速開発

4-1. パターン10. サーバーアプリの高速開発

  • テスト、デプロイの自動化、省力化することで、ユーザーの反応を見ながら頻繁に修正版のリリースを行いたい。
    →CIのマネージドサービスCodePipelineを使ってビルド、テストを自動化、AWS CodeDeployを使ってビルドされたアプリケーションファイルを自動的にEC2インスタンスにデプロイ。
  • リリース時にサービスを停止したくない。
    →実行環境をコンテナ化し、ECSにデプロイすることで無停止リリースを可能にする。(Blue-Green Deployという手法: 新バージョンをデプロイしポート番号を変更、ELBからの転送ポートを切り替える)

    4-2. パターン11. モバイルアプリの高速開発

  • 開発効率を上げるためにアプリケーションの開発者だけで更新作業を進められるようにしたい。
    AWS Mobile SDKを使うことでモバイルアプリからS3に直接アクセス可能に、サーバーアプリケーションの開発を不要に。
  • 物理デバイスを使ったテストを効率化したい。
    AWS Device Farmを使い、AWSのセンターにある物理デバイスを使ってテスト。物理デバイス保有せずにテストを実行。
  • 海外拠点に短期間で、開発・検証・本番環境を展開したい。
    Amazon CloudFormationを使ってテンプレートからインフラを構築、短期で環境構築を行う。

    5章 クラウドネイティブ

    5-1. パターン12. サーバーレスのインフラ

  • 新規事業への参入はタイミングが重要、他社に先駆けて顧客開拓を行うため短期間でのシステムが必要。
    →動的コンテンツ: AWS Lamda、AWS API Gatewayを利用してEC2を使わずに迅速にWebサイトを構築する。
    →静的コンテンツ: AWS CloudFront、Amazon S3を利用してEC2を使わずにコンテンツを配信。
    →マネージドサービスのため運用管理やオートスケールはAWSが管理。(EC2とELBの組み合わせの場合、WebサーバーやELBのセットアップが別途必要)

    5-2. パターン13. マイクロサービスの運用基盤

  • アプリケーションの高速開発・リリースを行うためにマイクロサービス化したい。
    →EKS(オーケストレーションサービス)でマイクロサービスのコンテナへのリソース割当や実行スケジュールの管理を自動化。EKSを使うことでKubernatesのインフラ構成を意識することなく構成済みの環境を利用できる。
    →Fargateで実行環境のプロビジョニングを行う。クラスター内のEC2を自動的に管理。

    6章 ハイブリッドクラウド

  • 既存システムはオンプレで構築しているが、事業継続のために災害対策サイトを用意したい。ただし別のオンプレ環境を用意するのはコストが掛かりすぎる。
    VM Importを使ってオンプレの仮想マシンと同じ構成をEC2上に作成する。DBMSが動作するEC2インスタンスを起動してレプリケーション機能でオンプレと同期する。
  • 年に数回、リクエストが集中しCPU不足になることに対処したい。
    →ピーク時にオンプレのロードバランサーAWSのにリクエストを振り分ける。更にCloudWatchでEC2のCPU使用量がしきい値を超えた場合はEC2インスタンスを追加起動しスケールアウト。

「ハイパフォーマンス ブラウザネットワーキング」を読んだ。の続き

前回は「14章 ブラウザネットワーキング入門」、「15章 XMLHTTPRequest」を扱いました。 www.developers-helix.info

今回は「9章 HTTPの歴史」から「13章 アプリケーション配信最適化」をまとめます。

9章 HTTPの歴史、11章 HTTP 1.x、12章 HTTP2.0

HTTP 0.9

  • HTMLのみ転送可能
  • リクエストはメソッドとパスのみ
  • ドキュメントの転送が完了すると接続は終了する
  • ApacheやNginxなどのWebサーバーは現在もHTTP0.9をサポートしている。
GET /about/

HTTP 1.0

  • HTML、プレーンテキスト、画像、その他形式の転送が可能(Hypertext TransferというよりはHypermedia Transportと呼べる存在に)
  • リクエストはメソッド、パスのほか、複数の改行されたヘッダーフィールドを持てる
  • サーバーとクライアントのそれぞれのリクエスト後に終了する
  • ほとんどのWebサーバーでHTTP 1.0をサポートしている。ただしリクエストごとに新規TCP接続を必要とするので、パフォーマンスの低下を引き起こす。
GET /about/ HTTP/1.0

HTTP 1.1

  • パフォーマンスの最適化を取り入れた
    • キープアライブ接続: 同じTCP接続を使い回せる
    • チャンク転送コーディング: データをぶつ切りにして、部分的に送信開始できる。
    • バイトレンジリクエスト: 取得したいコンテンツの範囲を取得できる(データのうち200-400byteまでなど)

HTTP 2.0

  • Googleによって開発された実験的なプロトコルであるSPDYがベース
  • 追加された機能
    • ストリームの多重化: 単一のTCP接続内で多数のストリームが並列にリクエストを送信できる。(HTTP1.1までは1つのリクエストが完了するまで、原則次のリクエストを送ることができなかった)
    • フロー制御: ストリームごとに受信可能なバイト数の通知を行うことで帯域幅への競合を防ぐ。(TCPのフロー制御とほぼ同じ仕組み)
    • サーバープッシュ: クライアントからの1つのリクエストに対して複数のレスポンスを返すことができる。ドキュメントに関連するCSSJavaScript、画像などのリソースをサーバー側から送りつけてしまうことでリクエストの数を減らすことで発生するはずだったレイテンシを排除できる。
    • ヘッダ圧縮: ヘッダテーブルをクライアントとサーバーに用意することでヘッダの差分のみを送る。(通常HTTP1.xのヘッダは1リクエストあたり500-800バイトほどオーバーヘッドが発生していた。)

10章 Webパフォーマンス入門

ハイパーテキスト、Webページ、Webアプリケーション

  • ハイパーテキスト: ハイパーリンクを付与したプレーンテキスト
  • Webページ: 画像や動画を含めたリッチなレイアウトが可能となったコンテンツ
  • Webアプリケーション: Javascript、DHTMLやajaxによるインタラクティブなコンテンツ
  • Web関連技術の進化とともにWebサイトを構成するリソースのサイズ、それらを取得するリクエスト数が増加している。
  • 数百のリソース、数MBのリクエストを複数のホストから取得するという処理を数百ミリ秒以内に行うことが必要。

スピード、パフォーマンス、人間の知覚

  • 時間とユーザーの知覚
    • 0-100ms: 瞬時
    • 100-300ms: わずかな知覚可能な遅延
    • 300-1,000ms: マシンが動作している
    • 1,000+ms: メンタルコンテクストスイッチが発生する(他のことが頭をよぎる)
    • 10,000+ms: タスクを破棄
  • アプリケーションが瞬時に反応したと感じさせるためには数百ミリ以内にレスポンスを行わなければならない。ただしDNS解決、TCPハンドシェイクなどのネットワークのオーバーヘッドだけでその大半を使ってしまう。
  • 例えばhttp://www.yahoo.jpの表示には683msかかり、そのうち30%の200msがネットワークのオーバーヘッド。

ブラウザ最適化

  • ブラウザ自体にもパフォーマンスを向上させるための仕組みが実装されている。
    • ドキュメント認識最適化: リソースの優先度付け、先読み解析によって初回のレンダリングに必要なリソースを始めに取得してユーザーが操作可能な状態にする。
    • 投機的最適化: ユーザーのナビゲーションパターンを認識してDNS事前解決やTCP事前接続を行うことで、ユーザーが実際にアクセスした際にかかる時間を短縮する。
  • Webアプリケーションの開発者は以下の手法でブラウザによる最適化を補助できる。
    • レンダリングに重要なリソース(CSSJavaScriptなど)は先に読み込まれるよう上の方に記載する。
    • ドキュメントはサーバー上で生成され次第、部分的にでも送信する。(Google検索では検索クエリの解析の前に検索ページのヘッダー部分のドキュメントを送信している)
    • ヒントをドキュメントに埋め込み、最適化を施す
<link rel="dns-prefetch" href="//hostname_to_resolve.com">(DNS事前解決)
<link rel="prefetch" href="/images/big.jpg">(リソースのプリフェッチ)
<link rel="prerender" href="//example.org/next_page.html">(指定ページのプリレンダリング)

13章 アプリケーション配信最適化

定番のパフォーマンスベストプラクティス

  • 不要なネットワークレイテンシを排除
    • DNSルックアップを減らす
    • TCP接続内接続の再利用
    • HTTPリダイレクトを減らす
    • 必要ないリソースを排除する
    • リクエストやレスポンス処理の並列化
    • プロトコル特有の最適化を適用(HTTP1.xのドメインシャーディングなど)
  • 通信データ量を最小化
    • リソースをクライアントにキャッシュ
    • 転送中リソースの圧縮
    • リクエストから不要なデータを排除

「ハイパフォーマンス ブラウザネットワーキング」を読む

なおひさです。今回取り上げるテーマは「Browsers and how they work?」です。
ブラウザの仕組みと一口に言ってもブラウザは色々なことをやってくれていますが、ざっくり分けると次の2つに分類できます。

  1. 「ネットワーキング」 接続の確立やリソースの取得など
  2. レンダリング」 取得したHTMLドキュメントをもとにDOMの構築やスタイリングなど

今回はメンバーから推薦してもらった「ハイパフォーマンス ブラウザネットワーキング」を読んで、「ネットワーキング」について内容をまとめていきたいと思います。 割とボリュームのある本なので「14章 ブラウザネットワーキング入門」「15章 XMLHTTPRequestのみを扱っていきます。

レンダリングについては素晴らしい記事があるのでこちらを参考にしてください! qiita.com

14章 ブラウザネットワーク入門

ソケット管理やネットワークセキュリティ、キャッシュ機能について書かれています。
これらはブラウザが自動的に行なってくれているので私達が普段Webアプリケーションを作る際にあまり意識しません。
しかし理解しておくことでトラブルシューティングやパフォーマンスの向上に繋げることができます。

  • ソケット管理*1
    • ソケット管理はWebアプリケーションではなくブラウザが行う。これによりブラウザはソケットの再利用やリクエストの発生を予測してソケット接続をしたり、パフォーマンスの最適化をしてくれる。
  • ネットワークセキュリティとサンドボックス
    • ブラウザがソケット管理を行う利点は他にも、ブラウザをサンドボックス化できることにある。
    • Webアプリケーションがソケット管理をする場合、悪意のあるアプリケーションがメールサーバーに接続して意図しないメッセージを送るなどセキュリティを担保できない。
    • 同一生成元ポリシーを適用して他のオリジンのリソースにアクセスできないように制限しているのもブラウザの仕事。同一オリジンポリシー - ウェブセキュリティ | MDN
  • リソースとクライアント状態キャッシュ
    • 最速のリクエストはリクエストがまったく行われないこと、つまりローカルのキャッシュを利用すること。
    • キャッシュの管理自体はブラウザが行ってくれる、Webアプリの開発者の仕事は適切なキャッシュ制御ディレクティブを返すように実装すること。
    • 認証、セッション、クッキーの管理もブラウザが行っている。複数タブやウインドウで認証セッションを共有できるので、そのうちのどれかでログアウトしたら他のセッションも無効になる。

15章 XMLHttpRequest

Webアプリケーションで非同期処理を実装した方は使ったことあるかもしれません。現在はFetch APIやaxios、jQuery$.ajaxなどがありますが、その元祖ですね。

  • XHRの歴史
    • XMLHttpRequest(XHR)とはJavaScriptを使ってデータ転送ができるブラウザレベルのAPI
    • XHRが登場する前にはサーバー・クライアント間で情報を送受信するためにはページ全体を更新する必要があったが、XHRにより非同期に送受信できるようになった。
    • ブラウザAPIということは接続管理などの低レイヤの処理をブラウザに任せて、開発者はリクエストの発行やサーバーから受信したデータの処理などに集中できる。
  • リアルタイム通知と配信
    • XHRを使うことでクライアントからサーバへの通信は簡単に実装できるが、逆にサーバからクライアントへの通信は難しい。
    • サーバ上の状態変化をトリガーにクライアントにリアルタイム通知をしたい場合など。HTTPはサーバからクライアントへの新規接続の開始はできない。
  • XHRポーリング
    • リアルタイム通知を実現するためにはクライアントからサーバへ定期的にXHRリクエストを送りアップデートの確認する方法がある(XHRポーリング)。定期的に送られるリクエストに対して新しいデータがあれば返し、なければ空のレスポンスを返す。
    • ただしポーリングのインターバル設定の決定が難しい。長すぎる場合はリアルタイム性が失われ、短すぎる場合には不要なトラフィックやオーバーヘッドが発生する。モバイルにとってはバッテリーを消費させてしまうアンチパターン
    • インターバルが長い場合や配信のインターバルが予測できる場合などにはポーリングが適している。
  • XHRを使ったロングポーリング
    • 新しいデータがない場合はアップデートが行われるまでレスポンスを返さない(接続をアイドルにする)というロジックにすることで不要なトラフィックを発生させないようにすることをロングポーリングという。
    • アップデートのタイミングが不明な場合はロングポーリングが有効。ただし頻繁にアップデートが行われる場合、アップデートされるごとにレスポンスが返るので定期的なポーリングよりトラフィックが増えてしまう。
  • XHRのユースケース
    • HTTPリクエストやレスポンスに関わる転送を簡単に実装したい場合や認証が必要なリソースの取得や、転送データを圧縮する際などに使える。
    • リアルタイム通知については現在はServer-Sent EventsやWebSocketなどより効率的に同様の機能を実現できる方法があるため、XHRのロングポーリングはこれらのフォールバックに使われている。
    • XHRはストリーミングには向いていない。

14-15章とまとめて来ましたがかなりボリューミーで、理解できていない箇所が多いです、、、 他の章も含めて読み直して理解を深めていきたいと思います。

*1:ソケットとはプログラムの世界とTCP/IPの世界を結ぶ特別な出入り口のようなものhttp://research.nii.ac.jp/~ichiro/syspro98/socket.html

『Real World HTTP』を読む

Real World HTTP

ある時、こちらのロードマップを見つけました。 github.com

バックエンドエンジニアとして仕事をしている上でとても参考になったと同時に必須とされている内容のものでも自分はその知識を持っていないものが多くあることに改めて気づかされました。

このロードマップに則り自分と相方のなおひさと共に記載されてある項目をそれに対応する良書を見つけアウトプットしていきます。

今回僕の担当は「What is HTTP?」
HTTPって何?って聞かれたらこの本を読むまではwebのブラウザとサーバーの間の決まりごとだよ!くらいしか答えることが出来ませんでした。

HTTPの理解の深めるため今回は「Real World HTTP」という本を読み章ごとにまとめていきます。 今回は1章のみをまとめます。

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

  • 作者:渋川 よしき
  • 発売日: 2017/06/14
  • メディア: 単行本(ソフトカバー)

第 1 章 HTTP/1.0 のシンタックス:基本となる4つの要素

HTTP/0.9から1.0までの歴史

HTTP/0.9

1章のタイトルにある基本となる4つの要素とは
1. メソッドとパス
2. ヘッダー
3. ボディ
4. ステータスコード

HTTP/0.9で実現できていることは、ボディの受信とパスのみ。 HTTP/0.9はテキスト情報が書かれたページのパスをサーバーに指定して、それを取得してくるだけのプロトコルです。
リクエストにはホスト名、IPアドレス、ポート番号を指定するだけであり

$ curl --http1.0 http://localhost:18888/hoge

上記の場合はサーバーが受け取るのは/hogeというパス部分のみ。

HTTTP/1.0

1.0から基本となる4つの要素が機能として使えるようになる。

  • リクエスト時にメソッドを追加
  • リクエスト時にHTTPバージョンを追加
  • ヘッダーの追加

HTTPの先祖について①(電子メール)

HTTP/1.0は電子メールのヘッダー+本文という構造を参考にして取り入れた。

クライアントがサーバーに対して送るヘッダーの一部

  • User-Agnet: クライアントが自分のアプリケーション名を入れるところ
  • Referer: サーバー側で参考にするための追加情報
  • Authorization: 特別なクライアントにだけ通信を許可する際、認証情報をサーバーに伝えるためのもの

サーバーからクライアントに返す時に付与するヘッダーの一部

  • Content-Type: ファイルの種類を指定する。MIMEタイプと呼ばれる識別子を記述。
  • Contetn-Length: ボディのサイズ
  • Content-Encodind: 圧縮形式の説明
  • Date: ドキュメントの日時

X-から始まるヘッダーは各アプリケーションが独自に設定できる

HTTPの先祖について②(ニュースグループ)

ニュースグループとは記事を読んだり投稿したりするプラットフォームのこと。USENETととも呼ばれている。
この分散アーキテクチャからHTTPはメソッドとステータスコードを参考にして取り入れ、 HTTP/1.0からGET, POST, HEADなどが利用できるようになった。

ステータスコード

主に5つのカテゴリに分類される

  • 1xx系: 処理中の情報の伝達
  • 2xx系: 成功時のレスポンス
  • 3xx系: サーバからクライアントへの命令(リダイレクト、キャッシュの利用など)
  • 4xx系 :クライアントからのリクエストのエラー
  • 5xx系: サーバー内部のエラー

URLとボディについて

URL

URLはRFC1738で定義され、場所からドキュメントなどのリソースを特定する手段を提供する。

ボディ

HTTP/0.9ではリクエストにデータは含められず、レスポンスはファイルコンテンツそのものだったがHTTP/1.0ではリクエストにコンテンツを含められ、レスポンスはボディとヘッダーを含むようになった。

本章の中はRFCにまつわる記載が多く、W3Cも含めて学び直そうという気持ちになった。
次回は2章と3章で提供されているソースを自分で動かしてみます。