受信したデータをバーストで分散させようとしています。これは、他のアプリケーションが大量に受信したデータがあることを意味します。データエントリごとに、トラフィックを制限する必要があるサーバーで追加のリクエストを実行する必要があります。したがって、次のデータバーストが到着するまでの時間内にリクエストを分散させようとします。
現在、データを分散させるためにトークンバケットを使用しています。ただし、受信したデータの整形がすでに悪いため、保留中のリクエストのキューがいっぱいになるか、バーストが発生するたびにスパイクが発生します。したがって、このアルゴリズムは、必要な種類の整形を実行していないようです。
リクエストを制限するために利用できる他のアルゴリズムは何ですか?高負荷時と低負荷時があることはわかっているので、どちらもアプリケーションで適切に処理する必要があります。
私が現在抱えている問題を本当に説明できたかどうかはわかりません。説明が必要な場合は、お知らせください。
編集:
問題をもう少し明確にして、単純なレートリミッターが機能しない理由を説明します。
問題は、トラフィックのバースト性と、バーストのサイズが異なる時間に異なるという事実にあります。ほとんど一定であるのは、各バースト間の遅延です。divide time by number of records
したがって、処理するデータレコードの束を取得し、次の束が入る前にそれらを可能な限り均等に分散する必要があります。ただし、次の束がいつ入るかは100%確実ではないため、単純に正常に動作しません。
この方法ではデータの拡散が十分でないため、レート制限は機能しません。レートの飽和に近づくと、すべてが正常になり、均等に広がります(ただし、これは頻繁には発生しないはずです)。ただし、しきい値を下回ると、拡散はさらに悪化します。
この問題をより明確にするための例を示します。
トラフィックを1秒あたり10リクエストに制限し、新しいデータが約10秒ごとに届くとしましょう。
時間枠の開始時に100レコードを取得すると、毎秒10レコードをクエリし、完全に均等に分散します。ただし、15レコードしかない場合は、10レコードをクエリする場合は1秒、5レコードをクエリする場合は1秒、0レコードをクエリする場合は8秒になるため、時間の経過とともにトラフィックのレベルは非常に等しくなりません。代わりに、毎秒1.5レコードを照会した方がよいでしょう。ただし、このレートを設定すると、新しいデータが早く到着する可能性があるため、問題が発生します。そのため、完全な10秒がなく、1.5クエリでは不十分です。トークンバケットを使用する場合、トークンバケットは時間枠の開始時にバーストを通過できるため、問題は実際にはさらに悪化します。
ただし、この例では単純化しすぎています。これは、実際には、特定の時点で保留中のリクエストの数を完全に把握することはできず、上限にすぎないためです。したがって、この数値に基づいて毎回スロットルする必要があります。