高度にスケーラブルなWebサイトを設計する最良の方法は何ですか?


35

Facebookなどのソーシャルネットワークなど、高度にスケーラブルである必要があるWebサイトの場合、Webサイトを設計する最良の方法は何ですか?

  1. サイトが必要なデータを取得するためにクエリするWebサービスが必要ですか?

    または

  2. サイトはデータベースを直接照会する必要がありますか?(組み込みの言語構造を使用して、テーブルに自動的に入力するなどを行うことができます)。

ウェブサービスは一元化されたデータアクセスを提供し、キャッシングなどの制御がはるかに簡単になるため、より良いデザインだと思いますが、他の人はどう思いますか?


また、使用するアーキテクチャ(MVCなど)の問題もあります。
イヴァン

起動する内容を詳しく知ることなく、答えを出すことは非常に困難ですが、おそらくアプリケーションが一種のSaaSアプリに適合する「クラウドサービス」を覚えておいてください。(一元化されています)。
ディープセル

一般的に言って、特に何も考えていないでしょう
ダニエル

1
「クラウド」で構築し、HighScalability.comを読むのに多くの時間を費やしてください。
エヴァンプライス

回答:


37

うわー、これは単純な質問であり、可能な答えの膨大な配列です。質問のより明確な部分は、データベースと直接またはWebサービスを介して接続する方がスケーラブルであるかどうかを尋ねます。その答えは簡単です。データベースに直接クエリを実行します。Webサービスを通過すると、ファイアウォールの背後で動作するコード(全体的に)にはまったく不要な待ち時間が追加されます。たとえば、Webサービスでは、リクエストを受信し、それをデシリアライズし、DBにクエリし、レスポンスをシリアライズして返すためのコンポーネントが必要です。したがって、コードがすべてファイアウォールの背後で動作している場合は、トラブルを回避し、DBに直接クエリを実行してください。

ただし、Webサイトをスケーラブルにすることは、最初に提起した問題をはるかに超えています。ここで接していても許してくれますが、あなたが特にFacebookについて言及していることを考えると、それは役に立つと思いました。

Brad Fitzpatrick(LiveJournalの創設者であり、現在Googleにいる)によって構築された作品とツールを読むことをお勧めします。Six Apartで彼と仕事をしたとき、彼から学んだことと、LiveJournalのアーキテクチャが非常にスケーラブルであることをここにいくつか紹介します。

  1. 広いデータベーステーブルではなく、狭いデータベーステーブルを使用します。これが魅力的だったのは、このアーキテクチャの動機を知ることでした。これは、簡単かつ迅速にシステムを作成することでした。アップグレードされました。幅の広いテーブル、または各フィールドまたはプロパティがテーブル内の列であるテーブルを使用する場合、データベーススキーマをアップグレードするとき、たとえば新しい列を追加するとき、システムはスキーマの実行中にテーブルをロックする必要があります変更が実装されます。大規模に運用する場合、これはデータベーススキーマを単純に変更するだけで大​​規模なデータベースが停止する可能性があることを意味します。それは明らかに悪い。一方、狭いテーブルは、オブジェクトに関連付けられた個々のプロパティをデータベース内の単一の行として単純に格納します。したがって、データベースに新しい列を追加する場合に必要なことは、ロックされていない操作であるレコードをテーブルに挿入することだけです。OK、それは少しの背景です。このモデルがLiveJournalのような作業システムで実際にどのように変換されるかを見てみましょう。

    ユーザーのブログに最新の10個のジャーナルエントリをロードし、各ジャーナルエントリに10個のプロパティがあるとします。従来の幅の広いテーブルレイアウトでは、各プロパティはテーブルの列に関連付けられていました。その後、ユーザーは必要なすべてのデータを取得するためにテーブルを1回クエリします。クエリは10行を返し、各行には必要なすべてのデータが含まれます(SELECT * FROMエントリORDER BY date LIMIT 10など)。ただし、狭いテーブルレイアウトでは、状況は少し異なります。この例では、実際には2つのテーブルがあります。最初のテーブル(テーブルA)は、エントリのID、作成者のID、エントリの日付などで検索する単純な基準を格納します。 (テーブルB)は、エントリに関連付けられたすべてのプロパティを保存します。この2番目のテーブルには、entry_id、key、およびvalueの3つの列があります。テーブルAのすべての行に対して、テーブルBには10行(各プロパティに1行)があります。したがって、最新の10個のエントリを取得して表示するには、11個のクエリが必要です。最初のクエリはエントリIDのリストを提供し、次の10個のクエリは最初のクエリで返された各エントリに関連付けられたプロパティを取得します。

    「聖なるモリー!」「地球上でどのようにスケーラブルにできるのですか?!」まったく直感に反する権利ですか?最初のシナリオではデータベースクエリが1つだけでしたが、2番目の「よりスケーラブルな」ソリューションでは11のデータベースクエリがあります。それは意味がありません。その質問に対する答えは、次の箇条書きに完全に依存しています。

  2. memcacheを自由に使用します。気づいていない場合、memcacheは分散型のステートレスで低レイテンシのネットワークベースのキャッシュシステムです。Facebook、Google、Yahoo、そして地球上のあらゆる人気のあるスケーラブルなWebサイトで使用されています。狭いテーブルデータベース設計に固有のデータベースオーバーヘッドを相殺するために、Brad Fitzpatrickによって部分的に発明されました。上記の#1で説明したのと同じ例を見てみましょうが、今回はmemcacheを紹介しましょう。

    ユーザーが最初にページにアクセスし、キャッシュに何もないときに始めましょう。まず、ページに表示する10エントリのIDを返すテーブルAをクエリすることから始めます。これらの各エントリについて、データベースにクエリを実行して、そのエントリに関連付けられているプロパティを取得し、それらのプロパティを使用して、コードがインターフェイスできるオブジェクト(オブジェクトなど)を構成します。次に、memcacheにそのオブジェクト(またはそのオブジェクトのシリアル化された形式)を隠します。

    誰かが同じページを2回目にロードするとき、同じ方法で開始します。表示するエントリIDのリストをテーブルAに照会します。エントリごとに、最初にmemcacheにアクセスして、「キャッシュにエントリ#Xがありますか?」と言います。はいの場合、memcacheはエントリオブジェクトを返します。そうでない場合は、データベースを再度クエリしてそのプロパティを取得し、オブジェクトを構成して、memcacheに格納する必要があります。ほとんどの場合、誰かが同じページに2回目にアクセスすると、データベースクエリは1つだけで、他のすべてのデータはmemcacheから直接取得されます。

    実際には、LiveJournalのほとんどで起こったのは、システムのデータのほとんど、特に揮発性の低いデータがmemcacheにキャッシュされ、ナローテーブルスキーマをサポートするために必要なデータベースへの余分なクエリがほとんど完全に相殺されたことです。

    この設計により、すべての友達に関連付けられた投稿のリストをストリームまたは「壁」にまとめることに関連する問題をはるかに簡単に解決できました。

  3. 次に、データベースのパーティション分割を検討します。上記のモデルは、さらに別の問題を浮上させます。つまり、狭いテーブルは非常に大きく/長くなる傾向があります。また、これらのテーブルの行が多いほど、他の管理タスクが難しくなります。これを相殺するには、何らかの方法でテーブルをパーティション分割してテーブルのサイズを管理し、ユーザーのクラスターが1つのデータベースで処理され、別のユーザーのクラスターが別のデータベースで処理されるようにすることをお勧めします。これにより、データベースの負荷が分散され、クエリの効率が維持されます。

  4. 最後に、素晴らしいインデックスが必要です。クエリの速度は、データベースのテーブルのインデックス作成の程度に大きく依存します。インデックスが何であるかを議論するのにあまり時間を費やしませんが、それは干し草の山から針を見つけるのをより効率的にする巨大なカードカタログシステムによく似ていると言うことを除いて。mysqlを使用する場合は、スロークエリログをオンにして、実行に長い時間がかかるクエリを監視することをお勧めします。クエリがレーダー上に表示されたら(遅いなどの理由で)、高速化するためにテーブルに追加する必要があるインデックスを見つけます。

「この素晴らしい背景のすべてに感謝しますが、聖なる悪徳、それは私が書かなければならない多くのコードです。」

必ずしも。memcacheとのインターフェイスを非常に簡単にする多くのライブラリが作成されています。さらに他のライブラリは、上記のプロセス全体を体系化しています。PerlのData :: ObjectDriverはまさにそのようなライブラリです。他の言語については、独自の調査を行う必要があります。

この回答がお役に立てば幸いです。私が頻繁に見つけたのは、システムのスケーラビリティがコードにますます低下し、健全なデータストレージと管理戦略/技術設計にますます低下することです。


3
+1私はこのすごい
Pankaj Upadhyay

1
「データベースに直接クエリを送信する」ことにはまったく同意しません。APIインターフェースを使用してシングルマスターマルチスレーブアーキテクチャを実装する方が簡単な場合に、パフォーマンスのためにデータベースをパーティション分割することに言及します。DBをアプリケーションから切り離すことの利点は、APIレイヤーが必要に応じてリクエストを分散できることです。APIは、アプリケーションを中断することなく、基盤となる実装を変更したり、データを再利用したりできるようにする抽象化です。
エヴァンプライス

1
(続き)シリアル化は常にオーバーヘッドを追加しますが、同時に実行される複数のインスタンスで構成される可能性が高いAPIレイヤーでのみです。有線での転送速度が心配な場合は、JSONに変換すると、とにかくgzipで圧縮される可能性が高くなります。最も簡単なパフォーマンスの向上は、サーバーからクライアントに作業がプッシュされるときに見られます。尋ねるべき重要な質問は、アプリケーション内でリクエストを配信するのか、それともサーバーレベルで配信するのかということです。複製する方が簡単ですか?
エヴァンプライス

1
@EvanPlaice-再利用性と、サービスを使用する際のサービスロジック実装の変更に関する優れた点。また、直接のデータベース呼び出しの代わりに、サービスでキャッシュインフラストラクチャを使用することもできます。
アシッシュグプタ

1
@AshishGupta正確に言うと、データを個別のサービスに分割することの唯一の違いは、ユーザーが受け取るものです。代わりに、サーバー上でhtml +コンテンツを組み立てます。ユーザーはデータとHTMLを別々に受け取り、クライアントブラウザーが再アセンブリを処理します。データを別のサービスとして使用すると、モバイルアプリケーションやその他の非Webベースのクライアント(スマートテレビアプリなど)で利用できるようになります。
エヴァンプレイス

13

Facebookなどのソーシャルネットワークなど、高度にスケーラブルである必要があるWebサイトの場合、Webサイトを設計する最良の方法は何ですか?

測定します。

私は思うだろう...

悪いポリシー。

実際の測定が必要です。


定量メトリックFTW。
バギア

1
OK ...では、測定後はどうなりますか?
Pacerier 14年

9

Scalablilityは特定の実装戦略の機能ではなく、アプリケーションアーキテクチャを設計することにより、大規模なリファクタリングと書き換えを行わずにデータアクセスレイヤーを進化させることができます。

拡張性のあるシステムを構築するための重要なテクニックは、高レベルのデータアクセス要件を理解し、それらに関連するインターフェイスコントラクトを構築することです。たとえば、1人のユーザー取得したり、任意のユーザーが最近投稿した50枚の写真一覧表示したりする必要がある場合があります

アプリケーションのビジネスロジックとデータアクセスロジックの間に必ずしもネットワークチャネルが必要なわけではありません。論理演算ごとに1つのメソッドを使用したメソッド呼び出しの間接化は、開始するのに十分です。

これらのデータアクセス方法は、できるだけ簡単に始めてください。アプリケーションが実際の使用パターンを提供し、ボトルネックのある場所に関するデータを収集するまで、パフォーマンスの問題がどこにあるかを予測することは非常に困難です。

明確に定義されたデータアクセスインターフェイスを持つことにより、アプリケーション全体に大きな変更を加えることなく、データアクセスの実装を進化させることができます。また、ビジネスロジックに透過的にWebサービスアーキテクチャに切り替えることもできます。

上記の回答の多くは、パフォーマンスのボトルネックを発見した後の進め方についていくつかの素晴らしいアドバイスを提供しますが、これらをあまりにも早く適用すると、コードの複雑さが必要かどうかを知る前にコードの複雑さに戸惑うことになります。


4

シンプルなWebサイトを開発し、トラフィックレベルに到達させます。ラインに沿って、スケーラブルなWebサイトを作成する方法を学習します。

問題に直面するまで、解決策を考えることはできません

サイトをローリングし、スケーリングの要件に直面したら、私を信頼してください。:-)


良い引用!!!!!!!!!!
-AmirHossein

2

Webアプリケーションは、デフォルトで3つの層(Web(プレゼンテーション)、アプリケーション、およびデータベース層)で設計されるべきであるという知恵を受け入れています。この区分は、各層の異なる要件によるものです。通常、データベースの品質の高いディスクアクセス/ストレージ、アプリ層の高いCPU /メモリ、およびWeb層の高い外部帯域幅/メモリ/地理的分散です。データベースマシンは、アプリケーションの初期の負荷を処理するために構築できる大規模なサーバーであることが多いため、アプリケーション/データベース層はしばしばアプリケーションのライフサイクルの後期まで1つに統合されます。

ただし、アプリケーションの特定の層数と適切なアーキテクチャは、このモデルや他のモデルと一致する必要はありません。

システム内のすべてのアクティビティを測定および監視する必要があることを計画します。2層または3層の設計から始めて、構築中に最も多くのリソースを必要とするように見える部分に注目します。このレベルで、実行中のアプリケーションが設計をガイドします。収集する情報が多く、それがより正確で詳細であるほど、成長するアプリケーションの設計に関してより適切な決定を下すことができます。

必要な変更をできる限り迅速かつ簡単にピボット/変更できるフレームワークとアーキテクチャを選択します。データアクセス/ストレージ/処理とアプリケーション処理が同じ実行可能ファイルで実行されている場合でも、適切にファクタリングされていれば、たとえば後でそれらを2つのレイヤーに分割することは難しくありません。


2

データベースに接続するための追加手順は、単なるオーバーヘッドです。たとえば、との間UI -> Business Facade -> Business -> Data Access -> DatabaseUI -> Databaseは、2番目のアプローチの方が高速です。ただし、削除するステップが多いほど、システムの保守性が低下し、重複が多くなります。プロフィール、ホームページ、悪魔の管理ページなどで友人のリストを取得するために必要なコードを書くことを想像してください。

したがって、ここでは、パフォーマンスの向上(もちろん、スケーラビリティの向上に直接影響する)と保守性の向上のバランスをとる必要があります。

ただし、高度にスケーラブルなWebサイトの作成を考えるときは、データベース接続のトピックに限定されないでください。これらの項目も考慮してください。

  1. 適切なプラットフォームの選択(PHPはスクリプトの性質により高速ですが、ASP.NETは要求されたファイルをオンザフライでコンパイルして処理し、何かを提供する必要があります。また、node.jsコールバックのため、ベースのアーキテクチャ
  2. Webサービスモデル(SOA)の代わりにRESTfulアーキテクチャを使用する
  3. データ転送にXMLではなくJSONを使用する(転送されるバイト数が少なくなる)
  4. Yahooのパフォーマンスガイドラインに従う
  5. 負荷分散層アーキテクチャなどのネットワークおよびハードウェアのトピック

2
PHPの方が速いとは言えません。適切に記述されたASP.NETアプリケーションは、多くの場合、PHPよりも優れています。naspinski.net/post/AspNet-vs-php--speed-comparison.aspx
アンドリュールイス

+1実際には、「単純な」ソリューションは、UI->データアクセス->データベースです。2 RESTはほとんどのブラウザーに既に組み込まれているため、「簡単」です。コマンド応答APIホイールを再作成する必要はありません。3 JSONが小さいだけでなく、HTMLエンティティを確認する必要がないため、シリアル化と逆シリアル化の手順が少なくて済みます。いい物。
エヴァンプライス

1

スケールアップとアウトアウトには、主に2つの方法があります。

スケールアップとは、マシンをより強力なマシンに置き換えることです。スケールアウトとは、別のマシンを追加して、既存のマシンが行っている作業を実行することを意味します。

トラフィックの多いWebサイトには、スケールアウトする機能が必要です。行う必要があるソフトウェアアーキテクチャは、サイトが忙しくなったときにより多くのマシンを簡単に追加できるようにする方法です。

通常、これは、各層でより多くのサーバーをプラグアンドプレイできるように、アプリケーションを層に分割することを意味します。

私はオプション1を実行します。直接実行する代わりにサービスがあります。これまでのところ、モノリシックアプリケーションのみをスケーリングできます。


0

クラウドのサポートを完全に統合したテクノロジープラットフォームを使用してサイトを開発します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.