大量の並行アクセス、大量のデータ処理、高信頼性の運用など、大規模 Web サイトが直面する重要な問題と課題となります。これらを解決するために、多くのインターネット企業は失敗しながら、様々なソリューションを考えて作り出しました。これらのソリューションはより多くの Web サイトで再利用され、徐々に大規模な Web サイトアーキテクチャの設計思想として広がれました。
階層化
階層化は、システム構築時の最も一般的なアーキテクチャパターンであり、システムを水平方向に複数の部分に分割し、各部分が比較的単一の役割を担い、上位層の依存性と呼び出しを通じて完全なシステムを形成します。
階層化はコンピュータの世界では広く普及しており、
・ネットワークの 7 階層通信プロトコル
・ハードウェア、オペレーティングシステム、およびアプリケーションソフトウェア
・ソフトフレームワークのMVCなど
も階層化の有名な例となります。階層構造は大規模な Web サイトのアーキテクチャでも使用されており、Webサイトのシステムは表に示すようにアプリケーション層、サービス層、データ層に分かれています。
アプリケーション層 | 業務の受付や画面の表をを担当する。 |
サービス層 | アプリケーション層に対して具体的なサービスを提供する。 |
データ層 | データアクセスを担当する。DB、キャッシュ、ファイル、検索エンジンなどを含む |
階層化するにより、システムをさまざまな部分に分割し、共同開発と保守を容易にすることができます。呼び出しインターフェイスが変更されない限り、各層はある程度独立しています。特定の問題に応じて各レイヤーに閉じ込めてカスタマイズでき、他のレイヤーをそれに応じて調整する必要がなくなります。
階層化の当初の目的は、ソフトウェアの論理構造を明確にし、開発とメンテナンスを容易にするためですが、Web サイトの高並行アクセスや、分散化するにも重要な意味があります。したがって、Web サイトがまだ小さいうちに階層型アーキテクチャを採用し、将来 Web サイトが大きくなった場合にもより迅速に対応できるようになるはずです。
分割
階層化がシステムを水平に分割することであることに対して、分割はシステムを垂直に業務を分けることです。 Web サイトが大規模になると、機能が複雑になり、サービスやデータ処理の種類も増加します。これらのさまざまな機能やサービスを分離し、結合度の低いモジュール単位にパッケージ化することによって、システムの開発と保守が容易になります。一方で、さまざまなモジュールの分散化ができ、Web サイトの並行処理と機能拡張能力が向上します。もちろん、これらのモジュールは論理的にも物理的にも関係なく、独立させることができます。
分散式
大規模な Web サイトの場合、階層化と分割の最終目的の 1 つは、別々になったモジュールの分散化を容易にすることです。つまり、異なるモジュールを異なるサーバーにデプロイし、リモート呼び出しを通じて連携することができます。
分散化のメリットは、より多くのコンピュータ(サーバ)を使用して、より多くの CPU、メモリ、およびストレージなどのリソースが使用できるようになり、処理できる並行アクセスとデータの量が増えるため、より多くのユーザーにサービスを提供できます。ただし、分散化のデメリットも目立ちます。まず、分散されたサービスの呼び出しがネットワークを経由する必要があるため、パフォーマンスに大きな影響を与える可能性があります。次は、サーバーの数が増えれば増えるほど、サーバーのダウンタイムが発生してサービスが利用できなくなる可能性が高くなります。さらに、分散環境ではデータの一貫性を維持することが非常に難しく、業務プロセスに大きな影響を与える可能性があります。
クラスター
分散化とクラスターの概念が紛らわしく、分からない方が多くいます。実は、分散化の異なるサーバは異なる業務を処理するに対して、クラスターは異なるサーバは同じ業務を処理することとなります。
分散化後のシステムは分離された各モジュールは独立となり、アクセス量もばらつきで、差異が大きいことが多いです。アクセス量などに合わせて、サーバのクラスター化は必要となります。ただ、どんなアクセス量が小さくても、可用性を高める観点で少なくとも2台のサーバで構成するクラスターが必要となります。
キャッシュ
キャッシュとは、処理を高速化するために、使用者に最も近い場所にデータを保存することです。キャッシュの利用は、ソフトウェアのパフォーマンスを向上させる最も優先的に考慮すべき手段の一つだと思われます。ハードウェアの世界では、CPU がますます高速になっている重要な要因は、より多くキャッシュの容量が使われることです。システム設計においても、ほぼあらゆる場所でキャッシュが使用されています。特に大規模な Web サイトのインフラ設計では、キャッシュが欠かせない存在になっています。
CDN: 複数拠点に分散配置されたサーバーネットワークを利用して、よりユーザーに近い場所からコンテンツを迅速に配信するシステムです。ユーザーのネットワーク リクエストは最初にCDNに到達し、ここで静的リソース (変更されるデータが少ない) がキャッシュされていて、その内容をすぐにユーザに返します。たとえば、ビデオ Web サイトやポータル Web サイトは、ユーザーが頻繁にアクセスする人気のコンテンツを CDN にキャッシュします。
リバースプロキシ: リバースプロキシは Web サイトのフロントエンドアーキテクチャの一部であり、システムのWebサーバ、アプリサーバの前に配置されます。ユーザーのリクエストが Web サイトのデータセンターに到達すると、最初にアクセスされるのは、静的データをキャッシュするリバースプロキシサーバーです。一部のリクエストは引き続きアプリサーバーに転送されることなくても、ユーザーにレスポンスを返されます。
ローカル キャッシュ: よく使うデータはアプリサーバー上でローカルにキャッシュされ、アプリケーションはデータベースにアクセスせずにローカルメモリ内のデータを直接に返します。
分散式キャッシュ: 大規模な Web サイトのデータ量は非常に多く、たとえ一部だけをキャッシュしても、必要なメモリ容量は 1 台のマシンでは賄えないため、ローカルキャッシュに加えて専用の分散式キャッシュサーバも必要になります。アプリケーションはネットワーク通信を通じて分散式キャッシュサーバにキャッシュされたデータにアクセスしますが、それでもロジック処理して、DBアクセスしてデータを取得するより速いです。
キャッシュを使用するには 2つの前提条件があります。1つ目は、データアクセスが分散されており、一部のデータはより頻繁にアクセスされることです。2つ目は、データが一定期間有効であり、期限切れにならないことです。そうしないと、キャッシュされたデータの有効期限が切れてダーティリードが発生し、結果の正確さに影響します。
キャッシュを使用することによってデータアクセスが高速化されるだけでなく、バックエンドアプリケーションやデータストレージの負荷軽減にもつながります。
非同期
よいシステム開発の重要な指標の一つは、ソフトウェアの疎結合を実現することです。前述の階層化、分割、分散化などはもちろん、非同期も疎結合を実現するための重要な手段となります。業務間の呼び出しは同期で実現するではなく、業務を複数のステージに分割され 、各ステージはデータ共有(メッセージキュー)を通して非同期的に連携します。
単一サーバー内であれば、マルチスレッドの間で共有メモリキューを利用して非同期を実現できます。前処理の出力をキューに書き込み、後続処理がキューからデータを読み取んで処理します。分散システムなら、前処理、メモリキューと後続処理は別々のサーバクラスターに配置することだけで、しくみは変わりません。
非同期アーキテクチャはプロデューサー/コンシューマーモデルであり、両者の間に直接の呼び出しはなく、相互に影響を与えることなく互いの関数の実装を変更できます。これは Web サイトの機能拡張にとって非常に便利です。また、非同期メッセージキューを使用すると次のような特長もあります。
システム可用性の向上:コンシューマサーバーに障害が発生した場合でも、データはメッセージ キューサーバーに保存され、蓄積されます。プロデューサーサーバーはビジネスリクエストの処理を続行できるため、システム全体のパフォーマンスへの影響は最小限に抑えられます。コンシューマサーバーは通常の状態に戻った後も、メッセージ キュー内のデータの処理を続けます。
応答高速化の実現:ビジネス処理のフロントエンドであるプロデューサーサーバーは、リクエストを処理した後にメッセージキューにデータを書き込むため、コンシューマーサーバーの処理を待たずにレスポンスを返すことができるため、レスポンスの遅延が軽減されます。
並行アクセスピークの緩和:イベント(ECサイトのキャンペンーンなど)によりWeb サイトのアクセスが突発的に谷ができています。十分にアクセスピークを予測して、それに合わせてWeb サイトを計画しても、不測な緊急事態が発生する可能性があります。アクセスが急激に増加すると、Web サイト全体が過負荷になり、応答が遅れ、ひどい場合にはサービスが停止する可能性があります。メッセージキューを利用すると、急に増えたアクセス要求データをメッセージキューに入れ、コンシューマーサーバーが順番に処理するのを待つことができるため、Webサイト全体の負荷を緩和できます。
ただし、非同期を使用すると、ユーザーエクスペリエンスとビジネスプロセスに影響を与える可能性があり、Web サイトのプロダクト設計に力を入れないといけません。
自動化
Web サイトの理想的な状態は、誰もいないときに Web サイトが正常に動作し、すべてが自動化できることです。現在、自動化といえば、主にリリースと運用保守に利用されています。
リリース作業はエンジニアに労力をかけ、ミスしやすい仕事です。特に昔のクラウドがまだ普及されていない時代に、リリース作業の失敗が多かったです。このような制限があるため、システムのリリースは頻繁的に実施できず、多くのビジネスチャンスを逃してしまうようになっています。
最近CI/CDがかなり普及となり、開発者はソースをリポジトリへコミットしたら、自動的にテスト、静的チェックが実行され、その結果をすぐに開発者へ連携します。さらに問題がなければ自動的にサーバへのデプロイまで自動的にできています。
Web サイトの運用中には、サーバーがダウンする、プログラムのバグ、ストレージ容量の不足、突然のアクセスのピークなど、さまざまな不測問題が発生しています。 サーバ/プロセスの死活、アプリケーションのさまざまなパフォーマンス指標など、システムの稼働状況を自動的に監視する必要があります。異常が発見されたら、自動的にアラートを発砲して、関係者に警報メッセージが送信されます。または、一部のサーバ(DBサーバなど)が障害を検出すると、システムは自動フェイルオーバーを実行し、障害が発生したサーバーをクラスターから分離し、システム内のアプリケーション要求を処理しなくなります。障害が解消されると、システムは自動障害回復を実行し、サービスを再起動し、データを同期してデータの整合性を確保します。
昔はリリースとシステム監視の自動化は非常に複雑で、いろいろ考えないといけないですが、クラウドサービスの普及や、パッケージ製品の進化することにより、リリースとシステム監視の自動化構築も簡単にできるようになりました。
コメント