Webアプリケーションの負荷スケーリング

Webアプリケーションの人気が高まるにつれて、そのサポートには必然的にますます多くのリソースが必要になり始めます。 最初は、アプリケーション自体のアルゴリズムやアーキテクチャを最適化することで、負荷に対処することができます(そして確かに必要です)。 ただし、最適化できるものがすべて最適化されていて、アプリケーションが負荷に対応できない場合はどうすればよいでしょうか?



最適化



最初のステップは、座って、すべてを最適化することができたかどうかを考えることです。



これらの各ポイントについて個別の記事を書くことができるため、この記事のフレームワークでそれらを詳細に検討することは明らかに冗長です。 アプリケーションのスケーリングを開始する前に、作業を可能な限り最適化することが非常に望ましいことを理解することが重要です。結局、スケーリングが不要になる可能性があります。



スケーリング



そのため、最適化はすでに行われていますが、アプリケーションはまだ負荷に対処できないとしましょう。 この場合、問題の解決策は、明らかに、利用可能なリソースを増やすことによってアプリケーションの全体的なパフォーマンスを向上させるために、複数のホストに分散させることです。 このアプローチの正式名は、アプリケーションの「スケール」(スケール)です。 より正確には、「 スケーラビリティ 」とは、システムに割り当てられたリソースの量を増やしながらパフォーマンスを向上させる能力のことです。 スケーリングには、垂直と水平の2つの方法があります。 垂直スケーリングは、単一のノード(ホスト)内にリソース(プロセッサ、メモリ、ディスク)を追加するときのアプリケーションパフォーマンスの向上を意味します。 水平スケーリングは、分散アプリケーションでは一般的であり、別のノード(ホスト)を追加するときのアプリケーションパフォーマンスの向上を意味します。



最も簡単な方法は、ハードウェア(プロセッサ、メモリ、ディスク)を単純にアップグレードすること、つまり垂直スケーリングであることは明らかです。 また、このアプローチでは、アプリケーションを変更する必要はありません。 ただし、垂直スケーリングはすぐにその限界に達するため、開発者と管理者はアプリケーションの水平スケーリングに切り替えるしかありません。



アプリケーションアーキテクチャ



ほとんどのWebアプリケーションは、Webサーバー、ビジネスロジック(アプリケーション)、データ(データベース、静的)の少なくとも3つのレイヤーにアーキテクチャを分割できるため、アプリオリに分散されています。







これらの各レイヤーはスケーリングできます。 したがって、アプリケーションとデータベースがシステム上の同じホストに存在する場合、最初のステップは間違いなく異なるホストに配布することです。



ボトルネック



システムのスケーリングを開始する場合、最初のステップは、どのレイヤーがボトルネックであるかを判断することです。つまり、システムの他の部分よりも動作が遅くなります。 手始めに、top(htop)などの一般的なユーティリティを使用して、プロセッサ/メモリの消費を推定し、df、iostatを使用してディスクの消費を推定できます。 ただし、( ABまたはJMeterを使用して)戦闘負荷をエミュレートする別のホストを割り当てることをお勧めします。このホストでは、 xdebugoprofileなどのユーティリティを使用してアプリケーションをプロファイルできます。 狭いデータベースクエリを識別するには、 pgFouineなどのユーティリティを使用できます(戦闘サーバーからのログに基づいてこれを行う方が良いことは明らかです)。



通常、すべてはアプリケーションのアーキテクチャに依存しますが、一般的な場合のボトルネックの最も可能性の高い候補はデータベースとコードです。 アプリケーションが大量のユーザーデータで動作する場合、「ボトルネック」はそれぞれ静的ストレージである可能性が最も高くなります。



DBスケーリング



前述のように、データベースは多くの場合、最新のアプリケーションのボトルネックです。 それに関する問題は、通常、パフォーマンスと大量のデータを保存する必要性の2つのクラスに分けられます。



データベースを複数のホストに分散することにより、データベースの負荷を軽減できます。 同時に、それらの間の同期の深刻な問題があります。これは、同期または非同期レプリケーションでマスター/スレーブスキームを実装することで解決できます。 PostgreSQLの場合、同期レプリケーションはSlony-I 、非同期レプリケーション-PgPool-IIまたはWAL(9.0)を使用して実装できます。 特別なデータベースアクセスレイヤー (PgPool-II)を設定することにより、既存のスレーブ間の負荷を分散するだけでなく、読み取り要求と書き込み要求の分離の問題を解決できます



リレーショナルDBMSを使用する場合に大量のデータを保存する問題は、PostgreSQLのパーティションメカニズムを使用するか、 Hadoop DFSなどの分散FSにデータベースを展開することで解決できます。



両方のソリューションは、 優れたPostgreSQLチューニングブックに記載されています。



ただし、大量のデータを保存する場合の最適なソリューションは、データを「 シャーディング 」することです。これは、ほとんどのNoSQLデータベース( MongoDBなど )の組み込みの利点です。



また、クエリの解析/最適化、データ構造の整合性チェックなどのオーバーヘッドがないため、NoSQLデータベースは一般にSQL兄弟よりも高速です。 リレーショナルデータベースとNoSQLデータベースを比較するトピックも非常に広範囲であり、 別の記事に値します



それとは別に、JOIN選択なしでMySQLを使用するFacebookの経験に注目する価値があります。 このような戦略により、データベースを非常に簡単にスケーリングし、データベースからコードに負荷を移すことができます。これは、以下で説明するように、データベースよりも簡単にスケーリングできます。



コードスケーリング



コードのスケーリングの難しさは、ホストがアプリケーションを実行するために必要な共有リソースの数に依存します。 セッションのみですか、それとも共通のキャッシュとファイルが必要ですか? いずれの場合でも、最初に行う必要があるのは、同じ環境の複数のホストでアプリケーションのコピーを実行することです。



次に、これらのホスト間でロード/リクエストのバランスを設定する必要があります。 これは、TCP( haproxy )レベルとHTTP( nginx )またはDNSの両方で実行できます



次の手順では、各ホストで静的ファイル、キャッシュ、およびWebアプリケーションセッションにアクセスできるようにします。 セッションの場合、ネットワーク上で機能するサーバー( memcachedなど )を使用できます。 キャッシュサーバーと同じmemcachedを使用することは非常に合理的ですが、もちろん、別のホストで使用することもできます。



静的ファイルは、 NFS / CIFSを介して共有ファイルストレージからマウントするか、分散ファイルシステム( HDFSGlusterFSCeph )を使用できます。



また、データベース( Mongo GridFSなど )にファイルを保存して、アクセシビリティとスケーラビリティの問題を解決できます(NoSQLデータベースの場合、スケーラビリティの問題はシャーディングによって解決されたという事実を考慮して)。



それとは別に、複数のホストにデプロイする問題に注意する価値があります。 「更新」をクリックして、ユーザーにアプリケーションの異なるバージョンが表示されないようにする方法は? 私の意見では、最も簡単な解決策は、更新されていないホストをロードバランサー設定(Webサーバー)から除外し、更新されたホストを有効にすることです。 また、CookieまたはIPによってユーザーを特定のホストにバインドすることもできます。 更新にデータベースの大幅な変更が必要な場合、最も簡単な方法は、プロジェクトを完全に一時的に閉じることです。



FSスケーリング



大量の静的データを保存する必要がある場合は、スペースの不足とデータアクセスの速度という2つの問題を区別できます。 前述のように、スペース不足の問題は少なくとも3つの方法で解決できます。分散FS、シャーディングをサポートするデータベースへのデータの保存、およびコードレベルでのシャーディングの「手動」の編成です。



また、高負荷の場合は、静電荷の分布も最も簡単なタスクではないことを理解しておく必要があります。 したがって、多くのサーバーが静的を配布するように設計されていることは非常に合理的です。 同時に、共通のデータストア(分散FSまたはDB)がある場合、ファイルを保存するときに、ホストを考慮せずにその名前を保存し、ページを形成するときにホスト名をランダムに置き換えることができます(静的を分散するWebサーバー間でランダムに負荷を分散します) 。 シャーディングが手動で実装されている場合(つまり、コード内のロジックがデータのアップロード先ホストを選択する責任がある場合)、フィルホストに関する情報は、ファイル自体に基づいて計算されるか、3番目のデータ(ユーザー情報、 (ストレージディスクの容量)およびファイル名とともにデータベースに保存されます。



モニタリング



大規模で複雑なシステムでは、常時監視が必要であることは明らかです。 私の意見では、ソリューションはここでは標準です-zabbixは、システムノードの負荷/作業を監視し、セキュリティのためにデーモンを監視します。



おわりに



上記では、Webアプリケーションのスケーリングの問題に対する多くのソリューションを簡単に検討しました。 それぞれに長所と短所があります。 すぐにすべてを実行する方法についてのレシピはありません。各タスクには、長所と短所を備えた多くのソリューションがあります。 どちらを選ぶかはあなた次第です。



All Articles