[メモ] Scaling on AWS (Part 2): > 10K Users

###### https://medium.com/aws-activate-startup-blog/scaling-on-aws-part-2-10k-users-8ad391a56de6 の個人的な翻訳というかメモです。所属する企業や団体における公式見解ならびに公式発表ではございません。
----
あなたのStartupをAWS上でスケールさせる為の入門ブログの2つ目のポストへようこそ。1つ目のポストでは、AWSをクイックにはじめる基本的なアーキテクチャをご紹介しました。また、アーキテクチャを層に分けて水平にスケールさせる方法もご紹介しました。これにより増えていくトラフィックを簡単に捌くことができます。

このポストでは、引き続き成長するウェブサイトにおけるAWSでのスケーリングの例をご紹介していきます。ゴールとしては10,000以上のユーザーからのアクセスを捌けるようになることです。まずは独立したデータ層の構築におけるデータベースの選択肢からはじめたいと思います。また、その中でいくつかAWSのサービスもご紹介していきます。

# Database Options on AWS
データベースをAWS上にデプロイする上で、一般的に2つのやり方があります。
1. Amazon Relational Database Service(Amazon RDS)やAmazon DynamoDBといったマネージドなデータベースを使う
2. ご自身でデータベースソフトウエアをEC2上でホストする

以下のセクションでは、あなたのビジネスに最も適したサービスを選択できるように、それぞれのサービスの特徴を簡単にご紹介します。

## Amazon RDS
Amazon RDSは一般的なデータベース管理タスクをAWSにオフロードします。RDSは自動的に夜間バックアップを行い、データベースソフトウエアのアップデートやパッチ当てを行い、そして、異なるAZへシームレスなフェールオーバーを行うための冗長性確保用のデータベースインスタンスの構築を行います。スタートアップにおいてはリソースが限られているわけで、RDSによってデータベースエンジニアは管理タスクから開放され、value-creatingなタスクにフォーカスできるようになります。RDSは様々なエンジンの中から選択することができます: Microsoft SQL Server, Oracle, MySQL, PostgreSQL, MariaDB, Aurora。RDS(SQL ServerとOracle)ではフレキシブルなライセンスモデルもサポートしており、ご自身のライセンスを持ち込むこともできます(BYOL)。

## Amazon DynamoDB
DynamoDBのようなnon-relationalなデータベースからベネフィットを享受することもできます。DynamoDBは高速でフレキシブルなNoSQLデータベースサービスで、どのようなデータスケールにおいても、一貫性やミリ秒レベルのレイテンシを確保する必要がある、全てのアプリケーションに向いています。マネージドなCloudデータベースであり、documentおよびkey-valueストアの両方のモデルをサポートします。

## Amazon EC2
最後に、もしAWSが提供していないデータベースエンジンを利用する必要があったり、データベースサーバーに関する全ての権限が必要な場合はEC2インスタンス上に、あなたご自身のデータベースを構築することもできます。ただし、私達は、できるだけAWSマネージドなデータベースを利用することをオススメします。なぜかというと、それらはあなたをデータベース管理業務から開放し、high-valueなタスクへフォーカスする手助けになるものだからです。

# SQL vs. NoSQL
よくある議論として、SQLとNoSQLのどちらを選択すべきか？というものがあります。正しい答えとしては、あなたが何をしようとしているのか、というところによってしまいます。SQLはよく、良い出発点になりえます。以下はベーシックなガイドラインになります。

## Choose SQL if:
• 確立した(枯れた)テクノロジーを利用したい場合
• 既存の コード,コミュニティ,事例,そしてスケーラビリティの確立されたパターン の価値を活かしたい場合
• 大量のデータを扱うのでない場合。ここで言う大量のデータとは最初の1年でテラバイト級のデータが発生するようなものの事を示します。

## Choose NoSQL if:
• non-relationalなデータを大量に保持している場合
もし、データオブジェクトと抽出するデータにリレーションシップを持たせてストアする必要がなければ、NoSQLのkey-valueフォーマットを選択することでデータのinputとoutputをクイックに行うことができます。
• テラバイト級の大量のデータを扱う場合
NoSQLは水平にスケールする分散データベースです。key-valueフォーマットは簡単にシャーディングさせることができます。NoSQLデータアーキテクチャは大きなデータセットに対しても安定して高いスループットを出し続けます。
• 秒間数千といった高速なデータ登録を行う必要がある場合
シンプルなkey-value構造によって、NoSQLデータは登録や削除を素早く行うことができます。これは大量のデータを扱う上での良い良い候補となります。

例えば、以下のセクションでは私はRDSを使います。よく検索されている商品トップ5や、火曜日に訪れたユーザーの数や、特定のプロダクトカテゴリを見た人、といった関連性をもったデータを抽出する必要があると仮定しています。

以下の図はアップデートされたアーキテクチャを示しています。緑の線はデータベースのマスターからスタンバイへの同期レプリケーションをしめしています。ここではMulti-AZがenabledになっています。
![MAZ](https://cdn-images-1.medium.com/max/800/1*5ZNYMmpcy0qbhssZNn2e1A.gif)

# Users > 10K
アプリケーションを層分けした後、水平スケールする準備ができました。前回ポストでは私のオリジナルアーキテクチャにはいくつか問題点がありました。1つ目は、冗長性が不足していました。二つ目は、アプリケーションはsingle AZにホストされていました。AWSではこれらの問題点を複数のAZを利用することで解決できます。私のアプリケーション層においては、サーバーを複数のAZに配置し、入ってくるトラフィックをElastic Load Balancing(ELB)を使って負荷分散します。ELBは冗長性を持った水平スケールするサービスで、管理作業は不要で、SSLのターミネーションをサポートし、Sticky Sessionの機能も持っています。ELBはまたhealthyなインスタンスにのみトラフィックを流すようにヘルスチェックを行う機能も持っています。これにより、それぞれのAZにサーバーを追加することで沢山のトラフィックを捌くことができます。

データベース層では、RDSのMulti-AZ機能を使うことで冗長性を確保しています。この機能を有効にするにはRDSのコンソールで起動する再に、シンプルにチェックボックスにチェックを入れるだけです。

RDSのMulti-AZを使うと、RDSは異なるAZにスタンバイ用のデータベースインスタンスを構築し、同期でデータをコピーします。この同期レプリケーションはフェールオーバーのプロセスをシームレスにします。データベースのDNS名を変えずにフェールオーバーさせることができるため、(アプリケーションから見た)接続先を変更する必要はありません。アプリケーション側ではデータベースのコネクションに対してリトライをするロジックを含める必要がありますが、RDSが自らが行うには面倒な仕事をしてくれていることが見て取れるかと思います。フェールオーバーイベントの他にも、スタンバイ用データベースインスタンスは可用性を高めています。例えば、計画されたメンテナンスの際にダウンタイムを最小にします。RDSは最初にスタンバイをアップデートして自動的にフェールオーバーさせるように振る舞います。

あなたのアプリケーションがポピュラーになって、沢山の読み込みリクエストを受け付ける必要があるようになった際は、Amazon RDSのRead Replicaを使ってデータベースをスケールさせることができます。Read ReplicaはMySQL, PostgreSQL, Amazon Auroraを使っている場合に利用することができます。RDS MySQLとPostgreSQLは最大5つのリードレプリカを構築することができます。但し、MySQLおよびPostgreSQLに元々備わっているレプリケーションを機構を使ったレプリケーションであるためレプリケーションのラグは発生してしまいます。Amazon Auroraは最大で15個のレプリカを作成することができます。Auroraにおいては共通のunderlyingなストレージを使っていることもあり、レプリケーションのラグは非常に小さいものとなっています。以下の図はAmazon RDSのリードレプリカを使うようにアップデートしたものになります。
The following illustration shows an updated architecture with Amazon RDS Read Replicas.
![RDS](https://cdn-images-1.medium.com/max/800/1*_OQmff_EB6QzYdh-AYdjsQ.gif)
水平スケーリングを、アプリケーションのレイヤ、RDS Multi-AZ, そしてRDSリードレプリカに導入したことで、このシステムは非常にスケーラブルなものになりました。しかし数万以上のユーザー数になってきたら、さらにアーキテクチャを疎結合にしていくことをオススメします。

# Shifting Loads to Increase Performance and Efficiency
AWSプラットフォームには様々なサービスがあり、それらは、十分なパフォーマンス、可用性、信頼性を備えています。AWSの様々なサービスを導入することで、あなたのアプリケーションにスケーラビリティをもたらします。

## Amazon Simple Storage Service (Amazon S3)
アセットをWebサーバー(EC2インスタンス)にストアすることは可能ですが、長い目で見た場合、スケーラブルであるとは言いがたく、また、あまりコスト効率が良くありません。例えば、トラフィックが伸びてきた時に静的なアセットへのリクエストもそれにあわせて伸びていきます。ネットワーク帯域の利用量をモニタリングしていくと、いずれ帯域のためにEC2インスタンスのタイプを変えなければならないかもしれません。また、それぞれのWebサーバーに対してアセットをWebサーバーにコピーすることもチャレンジングになってくるかもしれません。もし、全てのアセットを1つのサーバーにストアする場合、大きなインスタンスをその為に立てなければなりませんし、いくつかのWebサーバーに分散してコピーする場合、その為のインテリジェントなロジックを自分で実装しなければなりません。

これらの課題をAmazon Simple Storage Service(Amazon S3)を使って解決することができます。S3は非常に堅牢性および可用性が高いオブジェクトストレージで、ビデオやログファイル、そして画像を保存するのに適したソリューションです。S3はイレブン9の耐久性を備えています。データはリージョン内の複数の場所にコピーされます。オブジェクトへのアクセスはRestfulなAPIを通して行うことが可能です。S3はまた静的なアセットのセントラルリポジトリとして利用することができます。自動的にストレージをパーティショニングし、増加しつづけるリクエスト数への対応を行います。S3のオブジェクトはURLを通してグローバルにアクセスすることもでき、ネットワーク帯域のために高いEC2インスタンスを使う必要がなくなります。

## Amazon CloudFront
S3をアセットのセントラルリポジトリにして、更にcontent distribution network(CDN)を活用して、世界中の50以上のエッヂロケーションでキャッシングおよび配信を行うことで、よりスケーラブルにすることができます。Amazon CloudFrontは静的、動的両方のコンテンツを配信することができます。SSL証明書の導入もサポートしていて、オリジン(EC2もしくはS3)からCloudFrontまでのデータ転送量は無料です。

## Amazon DynamoDB
DynamoDBは、スケーラブルな、セッションもしくは状態のデータを保持するデータベースとしても有効です。リレーショナルなデータはRDSに保持し、セッションデータをDynamoDBにオフロードするといった構成を組むことができます。DynamoDBはマネージドなNoSQLデータベースであり、provisioned throughputをfine-tuneすることができます。高速で予測可能で非常にセキュアです。key-valueフォーマットなセッションデータを扱うのであれば、DynamoDBを使うことで、プライマリなデータベースからオフロードすることができ、システム全体のパフォーマンスを向上させることができるでしょう。

## Amazon ElastiCache
最後に、データへの高頻度なアクセスおよびプライマリなデータベースの負荷を下げるためにAmazon ElastiCacheをオススメします。ElastiCacheはRedisとMemcachedのプロトコルに準拠しています。もし、あなたがRedisやMemcachedを使っているのであれば、ElastiCacheを使うことにおいて何のコードの書き換えも必要もないということです。ElastiCacheを使う上での利点はマネージドサービスである、ということに尽きるでしょう。AWSはunhealthyなノードを検知してリプレースします。ElastiCache Redisを使用した場合、可用性を高めるため異なるAZにレプリカを立てることもできます。以下の図はS3、CloudFront、DynamoDB、そしてElastiCacheを導入したものになります。
![Arch](https://cdn-images-1.medium.com/max/800/1*DTICuVID8WhStu0kRuc9Jw.gif)
次のポストでは、引き続きこのアーキテクチャを、50万人のユーザー数にも耐えられるものにしていきたいと思います。Auto Scalingが図の中に登場することでしょう。また自動化やモニタリングについてもご紹介します。それによってあなたはAWSインフラストラクチャをより最適化することができるようになります。

# Summary
• SQLとNoSQLは異なるツールだということを理解しました; それぞれの用途に適した選択をしましょう
• 極力マネージドサービスを利用しましょう。マネージドサービスはあなたを重労働から開放し、あなた組織における、より価値のあることにフォーカスすることを可能にします。
• アプリケーションの可用性を向上させるため、Availability Zoneをまたいだ水平スケーリングするアーキテクチャデザインをしましょう。AWSはElastic Load Balancing(ELB)を提供することで各EC2インスタンスへトラフィックを分散します。
• RDSの機能を活用して冗長性および可用性の向上を簡単に実現しましょう。Multi-AZはスタンバイデータベースを構築し可用性を向上させます。リードレプリカはリードヘビーなワークロードに対してスケールおよびパフォーマンスの向上をもたらします。
• スケール、パフォーマンス向上、そして効率的に、増え続けるワークロードに対応するため適切にAWSのサービスを利用しましょう。S3は静的アセットのストアに適していますし、CloudFrontは低いレイテンシでコンテンツを配信しますし、DynamoDBとElastiCacheはセッションやキャッシュデータをメインのデータベースからオフロードすることを可能にします。