多くの小さなリクエストと少数の大きなリクエスト(APIデザイン)


49

現在、次のような組織でプロジェクトに取り組んでいます。

  • クライアント -REST APIを介してメインサーバーからデータを取得します。
  • サーバー -サードパーティAPIを介して他のさまざまなサーバーからデータを要求します
  • サードパーティ API-サーバーにデータを提供する私の制御できないサービス(Reddit、Hackernews、Quoraなど)

議論のために、クライアントが最初に各サードパーティAPIからのアイテムのリストを必要とするとしましょう。このリストからアイテムが選択されます。この時点で、クライアントはアイテムの完全なコンテンツとアイテムへの応答(コメント)を表示する必要があります。私は3つのオプションの間で決定しようとしています:

アラカルト

このアプローチでは、サーバーに3つのエンドポイントがあります。1つはアイテムのリストを取得し、1つはアイテムのメインコンテンツを取得し、もう1つはアイテムの応答を取得します。

  • 長所:必要以上にリクエストを送信することはありません。リクエストは小さくなければならないので、一般的には高速になります。
  • 短所:私は多くの要求をしなければなりません。リストから項目を選択した後、ユーザーはメインコンテンツを見る前に待たなければならない場合があり、それから応答を見るためにさらに長く待たなければならない場合があります

サーバー側キャッシュ

このリクエストでは、サーバーを1回呼び出して、すべてのソースのすべてのデータを「フェッチ」します。その後、データはサーバーにキャッシュされます。クライアントは以前と同じRESTエンドポイントを持つことになりますが、サーバーには既にデータがあり、それをクライアントにフィードするだけなので、呼び出しと呼び出しの間にあまり待つ必要はありません。

  • 長所:クライアント側での実装は依然として簡単ですが、遅延の問題はありません
  • 短所:サーバー側が少し複雑で、最初の呼び出しには本当に長い時間がかかる可能性があります。

クライアント側キャッシュ

このシナリオは前のシナリオと似ていますが、クライアントがサーバーに対して1回だけ要求を行うという点が異なります。つまり、すべてのデータを提供します。ここから、データを保存して適切に使用するのはクライアントの責任です。

  • 長所:簡単なサーバー実装、最初の呼び出し後は非常に高速
  • 短所:最初の呼び出しは非常に遅く、より複雑なクライアント側の実装になります

どちらが最善のアプローチであるのか、あるいは明らかな解決策が欠けているのかもしれません。どんなアドバイスも大歓迎です!


これは新鮮さとスピードの選択のように思えます。利害関係者とエンドユーザーは何を好みますか?
Erk

回答:


27

心に留めておくべきことの1つは、クライアントとサーバー間の予想されるネットワーク遅延(ping時間)です。それ以外の場合は帯域幅が良好な高遅延の状況では、小さなリクエストの多くは、大きなリクエストよりもパフォーマンスが著しく低下します。

私は最近、チームの1つがインド(残りは米国)である、マルチチームのデータベース支援Webアプリケーションプロジェクトで共同作業を行っています。米国のオフィスでホストされている単一のデータベースインスタンスがあり、そこに開発者がローカルのウェブサーバーインスタンスを接続しています。私のデスクは、データベースインスタンスから50フィート、LANから2ホップ離れたところにあり、パフォーマンスは良好です。

インドの開発者と最初に物事を始めたとき、彼らはアプリケーションを起動してページ間を移動するのに膨大な待ち時間を経験していました。ここでは、10分間の待機時間について話します。これは、デスクから開発用データベースサーバーまでの200ミリ秒のping時間に、データベースに対する多数の短いクエリが乗算されていたことが原因であることがわかりました。私のローカルの0.5msのpingはささいなものだったので、ウェブサーバーとデータベースサーバー間のチャットは問題になりませんでした。Webサーバーとデータベースサーバーを地理的に分離したのはこれが初めてでした。

私たちの場合の解決策は、データベースサーバーのクローンを作成し、インドでコピーを立ち上げることでしたが、ここでのポイントは、クライアントとサーバーが離れている場合、ネットワーク遅延がネットワーク全体の通信数で乗算されることに留意することですワイヤー。通常、接続が確立された後の帯域幅は、それほど心配ではありません。


2

これら3つのオプションは相互に排他的ではありません。クライアント側とサーバー側の両方のキャッシュを組み合わせて使用​​できます。ただし、コメントなどの一部のデータは、キャッシュに長時間保存されていると古くなる場合があります。それが当てはまるかどうかを確認できないことを考慮すると、おそらくそれをまったく保存しないでください。一方、コンテンツは通常、大幅に変更されることはないため、サーバー側でキャッシュし、クライアント側でその一部をプリフェッチして待ち時間を短縮しても害はありません。


1

あなたが提供した情報だけに基づいて、オプション1

  • 単一のクライアントリクエストで、リンゴとオレンジを混ぜると、フルーツバスケットが非常に大きくなる可能性があります。

  • キャッシュは、パフォーマンスは向上しますが、一貫性が失われる可能性のあるトレードオフです(古いデータ)。パフォーマンスの問題が特定されていない場合、通常、同期の問題はリスクを負う価値はありません。


0

私はいつも、いくつかの大きなリクエストがより良いパフォーマンスとよりスケーラブルであることを発見しました。ただし、すべてのアプローチにはトレードオフがあるため、サーバーとクライアントのニーズに依存します。別のオプションを使用することもできます。これは、クライアントに取得するデータ全体または一連のデータを指定することです。必ずしもすべてのデータではなく、利用可能な帯域幅に合わせて時間をかけて調整される一部の範囲です。


0

オプション3を(ほぼ)割引します。1と2のどちらを選択するかは、次の2つのことに依存します。

  • (A)単一の合計フェッチの結果の大きさ
  • (B)クライアント/ユーザーがそのセッションで通常使用する結果の詳細の量。

AとBが極端な場合、決定を下すのは簡単です。

  • Aが大きく、Bが小さい場合は、オプション1(アラカルト)を選択してください。
  • Aが小さく、Bが大きい場合は、2(サーバー側キャッシュ)または3(クライアント側キャッシュ)に進みます。

他のA / B(大/小)バリエーションについては、裁量を適用する必要があります。さまざまなクライアントのさまざまなユースケースに対応するために粗いエンドポイントと細かいエンドポイントの両方を提供することがよくあります。


0

プログラミングでいつものように、それは依存します。

ですから、本当の質問は次のとおりです。A/ B / Cまたは3つの組み合わせを決めるとき、あなたは何を考慮すべきですか?

本当の差別要因は、消費しているサードパーティAPIの実装の詳細だと思います。例として、次のことを考慮する必要があります。高速か低速か。データは頻繁に予期せず変更されますか?彼らは「おしゃべり」ですか、それとも休みですか?

高速で呼び出しが簡単なサービスの場合、データが頻繁に変更されるため、サーバー側のキャッシュで古いキャッシュの問題が発生するため、必ずオプション1に進みます。

外部データが予測可能な方法で変更される場合、または使用が制限されている場合、または単にサーバーでデータをキャッシュするユーザーエクスペリエンスを向上させることができる場合は、2に進みます。ただし、キャッシュは無料ではありません。デバッグの面でコストがかかり、ユーザーは更新プログラムが表示されないという苦情を訴えます。

オプション3は、データがそれほど多くない場合にのみ検討しますが、その場合はオプション1または2でも機能し、サーバーでより多くのロジックを保持するため、1または2に固執します。

ちょうど私の2c。

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