2

問題は次のとおりです。

多くの異なるサーバーにインストールされた「エージェント」は、「ハートビート」信号を 5 秒ごとに中央サーバーに送信します。10 秒以上ハートビートを逃したものをアクティブに見つけてアラートを出すにはどうすればよいですか?

スケーラビリティについて考えなければ、問題は単純です。最も単純な形式では、各エージェントから受信した最新のハートビートのタイムスタンプをデータベース テーブルに記録し、通常のクエリを実行して、しきい値よりも古いものを見つけることができます。

ただし、このソリューションは、数百万のエージェントに拡張することはできません。

これを可能にするアルゴリズムや技術を探しています。

4

3 に答える 3

2
  1. マップを使用します: AgentId --> LastHearbeatTime
  2. 11 セットを使用します (1 秒の分解能で十分であると仮定)。それぞれが 1 秒のウィンドウで報告されたエージェントの ID を保持します。

エージェントがハートビートを報告するたびに: 1. マップで見つけます 2. 関連するセットから削除します 3. マップで更新します 4. 関連するセットに追加します

スレッドの定義: 1 秒に 1 回、最も古いセットが期限切れになります。空である必要があります。そうでない場合は、報告しなかったエージェントの ID が含まれます。セットの有効期限が切れると、それを再利用できます (セットの循環配列)。

ロックなしで実装できると思います (おそらく 12 セットが必要になるでしょう)。

于 2011-08-16T20:40:01.337 に答える
1

言語とプラットフォームを知らなければ、詳細な実装についてアドバイスするのは少し難しいですが、私のアドバイスはLiorKoganのアドバイスと多少似ています。ただし、私の意見では、必要なセットは2つだけで、マップは含まれていません。

セットを表す2つの変数、AとBがあるとします。

ハートビートごとにセットAからエージェントIDが削除されます。5秒ごとに、異なるスレッドがB内のすべてのエージェントIDに対してアラートを生成し、次にB = Aに設定します。最後に、すべてのエージェントIDとセットAを含むセットを作成します。これに等しい(エージェントIDの数が非常に多い場合は、1つのチェックと別のチェックの間に新しいセットを準備し、残りの時間だけスリープすることができます)。ロックフリーのセットコレクションを使用する場合、ロックは各セットを指す変数を変更するときにのみ必要になります。パフォーマンスは、前述の実装のアルゴリズムの複雑さに大きく依存します。このように下げる場合は、パフォーマンスが最高の1つ(たとえば、最悪の場合の遅延が重要な場合など、必ずしも最高のbig-Oである必要はありません)を削除する特権を与える必要があります。

ちなみに、メモリが問題ではない場合、または障害が比較的少ない場合は、アラートを発生させる必要があるかどうかを確認するときに、独自のスレッドでそれを実行して、おそらく興味深いパフォーマンスのスピードアップを得ることができます(ここでも、プラットフォームとランタイムの問題。erlangでは簡単ですが、Windowsでは、古いBセットをメモリに保持するという犠牲を払って、本格的な新しいスレッドを作成するコストがパフォーマンス上の利点を超える可能性があります。

于 2011-08-16T21:53:24.023 に答える
-1

MongoDB は、このような用途に最適です。正確にはアルゴリズムではありませんが、このサービスを作成するために必要な基本的なテクノロジの法案に適合します。ここCopperEggでは、RevealCloud製品があなたの言うことを正確に実行するために使用しています-システムがしばらく離れたときにアラートを送信します-5秒ごとにサンプリングします. 皆さんの考えや使用例についてもっと知りたいです。詳細を教えていただけますか?

于 2011-08-16T20:17:22.830 に答える