[メモ] Scaling on AWS (Part 4) : > One Million Users

###### https://medium.com/aws-activate-startup-blog/scaling-on-aws-part-4-one-million-users-82ae773a55cc#.cn2c6cxtt の個人的な翻訳というかメモです。所属する企業や団体における公式見解ならびに公式発表ではございません。
****

4つ目で、そして、このシリーズ最後は、何百万ユーザーに対応するようにアーキテクチャをどのようにスケールさせるかをご紹介しましょう。もし、まだ1〜3のブログを読んでいないようでしたら、是非ご覧になってみてください。どのようにベーシックなAmazon Web Services(AWS)上で構築したアーキテクチャをユーザー数の増加とともに段階的にスケールさせたかをみていくことができます。更に、前の3つのパートでは以下のファンダメンタルなAWSのコンセプトについてもご紹介しています: 

- 水平にスケールさせるためアプリケーションを層に分ける
- AWSプラットフォーム上で動かすことができるデータベースを選択する
- より良いパフォーマンスで且つ効率的に処理をさせるためコンポーネントのワークロードをAWSのマネージドサービスに移行させる
- Auto Scalingを使って負荷をハンドリングしながら適切なEC2インスタンス数を維持する
- AWSのサービスを活用してソフトウエアデプロイメントのライフサイクルを自動化させる

このスケーリングシリーズブログを締めくくるにあたって、Service-Oriented Architecture(SOA)とAWSアプリケーションサービスの効能や効果をよく考えてみてください。

# Service-Oriented Architecture

これまで、アプリケーションを疎結合に層分けして、その中のコンポーネントの一部を最もフィットするAWSサービスに移すようにご紹介してきました。どのようにこれを更に進めることができるでしょうか？その答えはservice-oriented architecture(SOA)の原則をあなたのアーキテクチャに持ち込むことです。単純にアプリケーションをサーバーのロールで分割する(web vs. application)のではなく、サービスを一纏めにすることで更にリソース毎に分割してく、という方法です。この利点はそれぞれのサービスを独立した形でそれぞれスケールさせることができるということです。あなたのWebとApplication層はそれぞれ異なるリソースが必要となりますし、すなわち、あなたのサービス層でも異なるリソースが必要となるということです。

SOAの採用はとても良い事に聞こえますが、スタートアップにおいては、限られた時間および人的リソースをエンタープライズレベルなキューイングやメッセージングシステムの開発に対して使いたくないかもしれません。しかし、"恐れるな、Developers"。AWSプラットフォームはplug and playで汎用的なサービスを提供することで、とても簡単に疎結合なアーキテクチャを実践することを可能にします。以下のセクションでは一般的に使われるサービスについてご紹介します。

# Don’t Reinvent the Wheel (車輪の再発明をするな)

メールを送る、キューイングする、トランコーディング、モニタリング、そしてロギングは、ほとんどのソフトウエアで必要とされる機能ですが、これといった差別化の価値には繋がりません。もし、差別化に繋がらないのであればin-houseでそういったサービスを作ることに時間を使う必要はあるでしょうか？AWSはそういった一般的なサービスを提供し、あなたがインプラストラクチャをクイックに構築することを手助けします。以下のイラストはAWSが提供するアプリケーションサービスになります。

![managed](https://cdn-images-1.medium.com/max/800/1*J_Owl0KEIb3DLDge1bwnwg.png)

## Amazon Simple Queue Service (SQS)

SQSは分散した高いスケーラブルな特徴を持つシステムの、のりのような役目をする(acs as glue)サービスです。システムが非同期メッセージングによって繋がっている場合、それぞれは独立してスケールおよび(メンテナンス等含めて)ダウンさせることができます。もし、独立したフリートがあって、それぞれのジョブのステップを担当していたとして、ステップ2が失敗したとしたら、ジョブとしてはステップ2がリカバリーされるのを待てばよく、ジョブ全体をキャンセルする必要はありません。

SQSはまたスタートアップにとって価値があるはずで、それは、あなたのソフトウエアディベロッパーがキューイングのサーバーをメンテナンスする必要がなくなることです。マネージドサービスとして、SQSは可用性を担保します。スケーラブルなサービスとして、SQSは制限なくキューを作成することが可能ですし、あなたをキャパシティプランニングから開放します。SQSをはじめるためにディベロッパーが覚える必要があることはシンプルでRESTfulなAPIだけです。

## Amazon Simple Notification Service (SNS)

SNSはpub-subサービスで、メッセージを他のAWSサービスに送ります。SubscriberはTopicにpublishされたメッセージを受取ります。例えば、CloudWatchがメッセージをSNS topicに向かって発火した場合、そのtopicをサブスクライブしているAWS Lambda functionがトリガーされます。SNSとSQSは両方AWS上のメッセージングサービスですが、SNSは複数のSubscriberに対してメッセージをpushすることができ、更新情報を取得するための定期的なチェックや、いわゆるポーリングをする必要がありません。

SNSはまたmobile push機能を持っていて、Apple, Google, Fire OS, そしてWindowsデバイスに、中国国内のAndroidデバイスに関してはBaidu Cloud Push経由で、push notificationを行うことができます。push notificationでは、インストールされたモバイルアプリケーションは直ちにイベントの通知を、アプリケーションをオープンすることなく、ユーザーに伝えることができます。例えば、あなたがスポーツアプリをインストールして、push notificationをenableにした場合、アプリはあなたの応援しているチームの最新のスコアを、アプリを開くことなく受取ることができる、というものです。このnotificationはあなたのデバイス上に表示され、あなたがそれに気づいてアプリを開けば、より詳細の情報を表示させることができます。このユーザー体験はSMSを受け取った時と似ていますが、それと比べてコストは安くより機能的です。

## AWS Lambda

AWS LambdaはJava, Node.js, そしてPythonで書かれたコードをご自身でプロビジョニングやサーバーの管理を行うことなく実行できるサービスです。Lambdaはスケーラブルにあなたのコードを可用性高く実行され、100ミリ秒ごとのコンピュート時間にのみ課金が行われます。アップロードされたコードはLambda functionとして、AWS上でおこる様々なイベントによってトリガーされることを可能にします。Lambda functionはあなたのAWSアーキテクチャに追加可能なfirst-classなコンピュートリソースと考えても良いかもしれません。一般的なLambda functionのユースケースとしては、S3イベントをlisteningして、オブジェクトがS3にアップロードされる際にカスタムロジックを走らせるというものです。AWS Lambdaは新しいサービスですが、AWSプラットフォーム上の非常に強力なサービスです。

# Users > One Million

アプリケーションが爆発的に人気が出たと仮定しましょう、そして100万ビジターに近づいた、と。100万を超えるようなユーザーを捌くには、以下のようなアプローチ全てを持ち込む必要があるでしょう: 

- 複数のAvailability Zoneへのデプロイ
- Elastic Load Balancing(ELB)の活用
- Auto Scalingの導入
- Service-Orientedなアーキテクチャ
- コンテンツ配信に最適なAWSサービスの利用(例えば、local vs. Elastic BlockStore vs. S3)
- ElastiCacheを使ったデータベースの負荷のオフロード
- 水平スケールのために、その層に状態を持たないようにする

以下は上記のアプローチの利用を図解したものです。

![diagram](https://cdn-images-1.medium.com/max/800/1*gONUdrBv_I11Luz_h8OyXQ.png)

# Users @ Five to Ten Million

500万から1000万ユーザーになると、マスターデータベースに対する書き込みの競合といった問題に遭遇するかもしれません。いくつかそれを低減するための方法はありますが、基本的にはデータベースレイヤーにおいて更なる切り離しを必要とすると思います。これらの方法としては、データベースのフェデレーション、シャーディング、そしてNoSQLの活用といったところが挙げられると思います。

# Database Federation

データベースフェデレーションはデータベースを機能によって分割することを指します。例えば、フォーラムデータ、ユーザーデータ、プロダクトデータをそれぞれ異なる3つのデータベースにストアするといったものです。これによって個々のコンポーネントはそれぞれスケールさせることができます。このデータベース戦略はSOA戦略を補うものと言うことができるかもしれません。例えば、データの保存先を異なるサービスの異なるデータベースにしたい、と思うようになるかもしれません。一方で、このアーキテクチャは複雑さが増し、データをデータベースから取得するのにより洗練されたクエリを書く必要性が出てきます。

# Sharding

もし、上記のフェデレーションを行ってもなおデータのサイズが大きすぎる場合は、シャーディングを検討すべきかもしれません。これはデータベースの層で水平なスケーリングを行うというものです。シャーディングを行うことで、データを複数のデータベースにまたいで均等に保存することができます。ユーザーテーブルを、ラストネームがA〜Mのレンジを保存するデータベースと、それ移行のアルファベットのデータを保存するデータベースを分けるといったものです。シャーディングはフェデレーションよりもスケールしますが、データ量によって動的にデータベースの構成を変えるにはアプリケーションにそういったロジックを保持する必要があります。

# NoSql

最後に、もしあなたが独立したテーブルをリレーショナル・データベースに持っているのであれば、そのデータをAmazon DynamoDBのようなNoSQLデータベースに移してもよいかもしれません。リレーショナル・データベースはデータ間の整合性をとることにオーバーヘッドがありますが、もし、あなたのデータにその必要があないのであれば、なぜそのオーバーヘッドを取る必要があるでしょうか？DynamoDBはマネージドで、スケーラブルで、且つ、ハイパフォーマンスなkey-valueストアです。RDSのように、DynamoDBは管理系のタスクを担い、あなたをより価値のあるタスクにフォーカスすることを可能にします。データは高い可用性を達成するためにリージョン内の複数のファシリティに格納されます。DynamoDBはまたデータサイズによって自動的にスケールします。

# Next Steps

このブログシリーズがあなたにとってAWSプラットフォーム上でのスケールに関して思考の糧になることを望みます。更に、よく使われるアーキテクチャを集めた[リファレンスアーキテクチャセクション](https://aws.amazon.com/architecture/)も是非ご覧ください。私たちの[ドキュメント](https://aws.amazon.com/documentation/)を読んで情報を得て、そして、[スタートアップブログ](https://medium.com/aws-activate-startup-blog)を通じてあなた達の知り合いがどのようにAWSのサービスを使っているかご覧ください。

AWSに飛び込む準備ができたら、AWSには[無料枠](https://aws.amazon.com/free/)もございます。

Happy coding!

# Summary

1. 独立したサービスに層を分けましょう(SOA)
2. 車輪の再発明はやめてAWSのアプリケーションサービスを極力活用しましょう
3. 大量のデータを管理するのに、データベースのフェデレーションおよびシャーディングを検討しましょう
4. もし理にかなうのであればNoSQLへ移行しましょう

By David Kuo, Solutions Architect, AWS

# Reference
[Scaling Up to Your First 10 Million Users](https://www.youtube.com/watch?v=ccojvcQq858)