最初の1億人のユーザーにスケーリングするシステム設計方法【前編】　ゼロから始める、スケーラビリティの技術

本記事は、[Anh Dang](https://dangtrunganh.medium.com/)氏による「[How to design a system to scale to your first 100 million users](https://levelup.gitconnected.com/how-to-design-a-system-to-scale-to-your-first-100-million-users-4450a2f9703d)」（2021年6月28日公開）の和訳を、著者の許可を得て掲載しているものです。

#最初の1億人のユーザーにスケーリングするシステム設計方法【前編】
>大きく考え、小さく行い、速く学ぶ

###

>新技術に対応するため、この記事は1年を通して更新したいと思います。
>最終更新日：2021年6月28日

![](https://miro.medium.com/max/700/0*z3gY0E6tUsDOue7Q)
>Photo by [Kirill Sh](https://unsplash.com/@kirill2020?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com/?utm_source=medium&utm_medium=referral)

##はじめに

何億人ものユーザーをサポートするシステムの設計は、容易なことではありません。ソフトウェアアーキテクトにとっては、常に大きな挑戦です（でも、私の記事を読めば、今日から簡単になります🤣）。

この記事で取り上げたトピックは次の通りです。

【前編】
-   最も単純なものから始める：オールインワン
-   スケーラビリティの技術：スケールアウトとスケールアップ

[【後編】](https://qiita.com/baby-degu/items/f729417946270010e269)
-   リレーショナルデータベースのスケーリング：Master-Slaveレプリケーション、Master-Masterレプリケーション、フェデレーション、シャーディング、非正規化、SQLチューニング
-   使うべきデータベース：NoSQLかSQLか
-   高度なコンセプト：キャッシング、CDN、geoDNSなど

>今日は、フォールトトレランス、信頼性、高可用性など、ハイパフォーマンスコンピューティングの一般的な用語については触れません。

落ち着いて、さあ始めましょう！

##ゼロから始める

下の図のように、数人のユーザーがいる基本的なアプリを設計するところから始めたいと思います。最も簡単な方法は、アプリ全体を1台のサーバーに配置することです。ほとんどの人がこの方法で始めると思います。

-   Webサイト（APIを含む）はApache¹（またはTomcat²）などのWebサーバー上で実行する
-   Oracle³（またはMySQL⁴）などのデータベース

![](https://miro.medium.com/max/700/1*VWHA2hOVtQ9uFnd6-CU78A.png)
>同じ物理マシン上にWebサーバーとデータベースサーバーを置く

しかし、現在のアーキテクチャには次の欠点があります。

-   データベースに障害が発生すると、システムに障害が発生する。
-   Webサーバーに障害が発生すると、システム全体に障害が発生する。

この場合、フェイルオーバーや冗長性はありません。サーバーがダウンすると、すべてがダウンします。

###DNSサーバーを使用して、ホスト名とIPアドレスを解決する

上の図では、ユーザー（またはクライアント）がDNS⁵システムに接続し、システムがホストされているサーバーのインターネットプロトコル（IP）アドレスを取得しています。IPアドレスが取得されると、リクエストはシステムに直接送信されます。

>###Webサイトにアクセスするたびに、コンピュータはDNSルックアップを実行します。

DNSサーバーは、通常、ホスティング会社が提供する有料サービスとして提供され、自分のサーバーでは実行されません。

##スケーラビリティの技術

データ量の増加、作業量の増加（トランザクション数など）、ユーザー数の増加など、さまざまな理由でシステムのスケーリングが必要になることがあります。

>スケーラビリティとは、通常、リソースを追加することで、ユーザーエクスペリエンスに影響を与えることなく、より多くのユーザー、クライアント、データ、トランザクション、リクエストを処理できる能力を意味します。

システムのスケーリング方法を決める必要があります。この場合、**スケールアップ**と**スケールアウト**という2種類のスケーリングがあります。

![](https://miro.medium.com/max/700/1*AH9piaOcg3Y-quM-HL0lbg.png)
>スケールアップとスケールアウト

###スケールアップ：既存サーバーにRAMとCPUを追加する

これは「**垂直スケーリング**」とも呼ばれ、増加する負荷を処理する能力を向上するために、システムのリソースを最大限に活用することを指します。例えば、RAMとCPUを追加することで、サーバーの性能を向上させます。

>8GBのメモリを搭載したサーバーを運用している場合、ハードウェアを交換または追加するだけで、32GBまたは128GBに簡単にアップグレードできます。

垂直スケーリングには、次のような方法があります。

-   RAIDアレイにハードディスクドライブを追加して、I/O容量を増やす。
-   ソリッドステートドライブ（SSD）に変更して、I/Oアクセス時間を短縮する。
-   プロセッサを追加搭載したサーバーに変更する。
-   ネットワークインターフェースをアップグレード、または追加インターフェースをインストールして、ネットワークスループットを向上させる。
-   RAMを増設して、I/O操作を減らす。

垂直スケーリングは、ハードウェアをアップグレードする余裕のある小規模システムには適した選択肢ですが、次のような重大な限界があります。

-   「1台のサーバーの性能を無限に向上させることは不可能」主に、OSとサーバーのメモリバス幅に依存する。
-   システムにRAMをアップグレードする時にサーバーをシャットダウンする必要があるため、システムにサーバーが1台しかない場合、ダウンタイムが回避できない。
-   強力なマシンは、通常、一般的なハードウェアよりはるかにコストがかかる。

スケールアップは、ハードウェア条件だけでなく、ソフトウェア条件にも適用し、例えば、クエリやアプリケーションコードの最適化も含みます。

###複数のサーバーは必要か

ユーザー数の増加に伴い、1台のサーバーでは足りなくなります。1台のサーバーを複数サーバーに分離することを検討する必要があります。

![](https://miro.medium.com/max/700/1*qOD0QEDwOC-hMcIC0YCxfA.png)
>ユーザー数の増加に伴い、1台のサーバーでは足りなくなる

このアーキテクチャには、次の利点があります。

-   Webサーバーとデータベースサーバーを異なる方法で調整できる。
-   Webサーバはより良いCPUで、データベースサーバーはより多くのRAMで、強力になる。
-   Web層とデータ層に別のサーバーを使用すると、独立してスケーリングできる。

###スケールアウト：ハードウェアとソフトウェアのエンティティを必要な数だけ追加する

「**水平スケーリング**」とも呼ばれ、リソースのプールにエンティティ（マシン、サービス）を追加します。システム構築前に検討する必要があるため、垂直スケーリングに比べて水平スケーリングを実現するのは難しいです。

水平スケーリングでは、最も基本的なものでもより多くのサーバーの数が必要なため、最初はコスト増になることが多いですが、後で効果が出て回収できます。初期費用とトレードオフの関係です。

-   サーバーの数が増えると、より多くのリソースの維持が必要になる。
-   複数のサーバー間で作業の並列処理や分散処理を可能にするため、システムのコード変更が必要になる。

###ロードバランサーを使用して、各ノード間でトラフィックの負荷分散をする

ロードバランサーは、サーバーのクラスター全体にトラフィックを分散して、システム（アプリケーション、Webサイト、データベースを含みますが、これらに限定されません）の応答性と可用性の向上に役立つ、ハードウェアまたはソフトウェアコンポーネントです。

![](https://miro.medium.com/max/700/1*UZ-IzTDvZQacr61IyFbV5g.png)
>ロードバランサーを使用して、各ノード間でトラフィックの負荷分散をする

ロードバランサーは、通常、**クライアント**と**サーバー**の間に設置し、受信ネットワークやアプリケーショントラフィックを受信して、さまざまなアルゴリズムを使用して複数のバックエンドサーバーにトラフィックを分散します。そのため、Webサーバーとデータベースサーバー間や、クライアントとWebサーバー間など、さまざまな場所で使用できます。

>HAProxyとNGINXは、有名なオープンソースのロードバランサーです。

ロードバランサーの技術は、耐障害性を確保する方法であり、次のように可用性を向上させます。

-   サーバー1がオフラインになると、すべてのトラフィックはサーバー2とサーバー3にルーティングされる。Webサイトはオフラインにならない。負荷分散のために、新しい正常なサーバーをサーバープールに追加する必要もある。
-   トラフィックが急激に増加している場合、Webサーバープールにサーバーを追加するだけで、ロードバランサーがトラフィックをルーティングする。

ロードバランサーは、さまざまなポリシーや作業分散アルゴリズムを使用して、次のように最適に負荷分散します。

-   **ラウンドロビン**：各サーバーは先入れ先出し（FIFO）と同じ考え方で、順番にリクエストを受信する。
-   **最小接続**：接続数が最も小さいサーバーにリクエストを転送する。
-   **最速応答**：（最近または通常の）応答時間が最速のサーバーにリクエストを転送する。
-   **重み付け**：より強力なサーバーは、より性能の低いサーバーより、より多くのリクエストを受信する。
-   **IPハッシュ**：クライアントのIPアドレスのハッシュを計算して、サーバーにリクエストを転送する。

複数のサーバー間でリクエストを負荷分散する最も簡単な方法は、ハードウェアアプライアンスを使用することです。

-   共有IPからの実サーバーの追加や削除は即座に行われる。
-   負荷分散は必要に応じて実行できる。

ソフトウェア負荷分散は、ハードウェア負荷分散に代わる安価な手段です。レイヤー4（**ネットワーク層**）とレイヤー7（**アプリケーション層**）で動作します。

-   **レイヤー4**：ロードバランサーは、ネットワーク層のTCPが提供する情報を使用する。このレイヤーでは、通常、リクエストの内容を確認せずにサーバーを選択する。
-   **レイヤー7**：送信元および送信先アドレスを含む通常のレイヤー情報だけでなく、クエリ文字列、Cookieなど選択したヘッダー情報に基づいて、リクエストの負荷分散ができる。

>今回は前編です。[後編はこちら。](https://qiita.com/baby-degu/items/f729417946270010e269)

##翻訳協力

この記事は以下の方々のご協力により公開する事ができました。改めて感謝致します。

Original Author: [Anh Dang](https://dangtrunganh.medium.com/) (<http://junryo.xyz>)
Original Article: [How to design a system to scale to your first 100 million users](https://levelup.gitconnected.com/how-to-design-a-system-to-scale-to-your-first-100-million-users-4450a2f9703d)
Thank you for letting us share your knowledge!

選定担当: @gracen
翻訳担当: @gracen
監査担当: -
公開担当: @gracen

##ご意見・ご感想をお待ちしております
今回の記事はいかがでしたか？
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
頂いたお声は、今後の記事の質向上に役立たせて頂きますので、お気軽に
コメント欄にてご投稿ください。[Twitter](https://twitter.com/BabyDegu?lang=ja)でもご意見を受け付けております。
皆様のメッセージをお待ちしております。