web-dev-qa-db-ja.com

サブスクリプションを処理する最適な方法

データベースにデータを挿入するシステムがあります。データが挿入されるたびに、サブスクライバーに通知されます(挿入直後に発生する必要はありませんが、時間制限があるため、10秒ほど待ってから、挿入されたデータのX数について通知できます)。

問題は、各サブスクライバーにフィルターがある可能性があることです。新しいレコードがデータベースに挿入され、それがタイプの製品であるとしましょう:靴。私はそれに興味のある1 kのサブスクライバーを持っているので、その情報を含む電子メールを受信する必要がありますが、サイズが10の場合にのみフィルターをかける人もいます。

それをスケーラブルにするのに最適なデザインは何ですか?

現在、データベースで新しいレコードを探し続けるプロセスがあり、各ユーザーに対して、このユーザーに通知する必要があるかどうかを確認しようとするすべてのサブスクライバーを反復処理します。別のコンポーネントがそれを受信し、そのユーザーに送信します。

このようにして、X個のコンポーネントが新しいデータを探し、Y個のコンポーネントがキューからイベントを受信して​​ユーザーに通知を送信できるため、コールアウトすることができますが、それを行うための最適な方法ではないと思います。

手伝ってくれてありがとう

1
Witos

NFSA

非決定性有限状態マシン。

それが現在のアルゴリズムです。あなたは1つのノード(挿入されたばかりのアイテム)にいて、そのノードにはアクティベーションルール(フィルター)を持つ非常に多数のエッジがあり、サブスクリプションごとに1つです。

これで、そのノードにいるたびに各エッジでフィルターを実行できますが、これは低速です。

あなたが指摘したように、任意のノードに関心があるサブスクライバーのセットと、サイズ10のノードにのみ関心があるセットがあります。要点は、これらのセットの両方が変更されないことです。すべてに関心のあるセットは依然としてすべてに関心があり、サイズ10のセットはサイズ10のみに関心があります。

質問を裏返してみましょう。どのようなサブスクライバーのグループがありますか?

DFSAにコンパイル

私たちがやりたいのは、各ノードが1つの質問(またはフィルターの一部)を表し、その質問に一連の回答があるデータ構造です。あなたの靴の類推から、ノードが必要ですSize of Shoeと靴のサイズの配列[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]。各サブスクライバーを回答に対応するバケットに配置します。このように靴を見ると、サイズが10の場合、サイズ10のバケットは、すべてのサブスクライバーがサイズ10の靴に関心を持つことになります。

これは少し繰り返すことができます。質問ごとに個別のインデックスを設定して、それらに参加できます。これは、リレーショナルデータベースを使用している場合に最適です。

または、この設定をツリーとして行うこともできます。各回答には、次のブランチへのポインタ、またはサブスクライバのバケットのいずれかが含まれます(おそらく、常に関心のあるサブスクライバのバケットと、関心のある可能性のあるサブスクライバのポインタの両方が与えられます...)。これは、データベースなしで実行する必要がある状況に適しています。

あなたがしたいと思うかもしれない最適化はフィルター好みがない人々が特別な回答バケットに入れられることです。このバケットを検索し、サブスクライバーを回答に対応するバケットに追加する必要があります。技術的には、これによりNFSAアプローチに戻ることができます。

このアプローチの欠点は、フィルターを変更するたびにこのデータ構造の保守が必要になるため、フィルターの修正が遅くなることです。利点は、実行が桁違いに速くなることです。

1
Kain0_0