1

問題:
50〜100台のTomcatサーバーで使用される複数の共有シーケンスジェネレーターを実装する必要があります。各シーケンスジェネレーターは1から始まり、要求ごとに1ずつ増加する必要があります。シーケンスジェネレータの実装には、アトミックインクリメントコマンドが必要です。Javaクライアントが利用可能である必要があります。

スケール:
最大50000のシーケンスジェネレーターがアクティブに使用されます。それぞれについて、5〜10秒で1つの増分リクエストが必要です。1秒あたり最大20000リクエスト
50-100Javaクライアント(Tomcatサーバー)。シーケンスジェネレーターへのアクセスは、これらのサーバー間で共有されます。重要:2つのクライアントのみが同じシーケンスジェネレーターを使用します。
50〜100回-各シーケンスジェネレーターが使用される平均回数。
24時間TTL-ジェネレーターは作成後24時間以内にクリーニングする必要があります-したがって、実際には50000を超えるシーケンスジェネレーターが存在する可能性がありますが、同時にアクティブにリクエストを受信するのは最大50000までと予想されます。

パフォーマンス:
1ms未満の望ましい平均応答時間。2ms以上の平均は間違いなく十分ではありません。

OracleのSequenceオブジェクトを除外しました。
現在、RedisとMemcachedを検討しています。
どちらも高速です。

どのような実装が推奨/十分に良いですか?
この目的のために他にもっと良い技術はありますか?

もう1つの重要な質問:
incr、Redis、Memcachedのどちらのパフォーマンスが優れていますか?

ありがとう

4

2 に答える 2

6

Redis では、これを簡単に行うことができます。

  1. シーケンス ジェネレーターごとにキーを作成する
  2. 次のシーケンス番号を取得するには、 INCRコマンドを使用します。
  3. 返された数値が 1 の場合、キーが以前に存在しなかったことを意味します。この場合、PEXPIREコマンドを発行して、24 時間後にキーを期限切れにする必要もあります。

待ち時間をさらに短縮するために、いくつかのことを行うことができます -

  1. シーケンス ジェネレーター専用の Redis サーバーを維持します。つまり、このサーバーに他のデータを保存しないでください。
  2. AOF を使用しないでください。代わりに RDB 永続性を使用してください。AOF はすべての INCR コマンドをログ ファイルに追加しますが、RDB は各シーケンスの現在の値を単純に保存します。

待ち時間の問題の診断とredis の永続化に関するページをよく読む必要があります。

また、expire コマンドは 24 時間に 1 回発行する必要があり、redis への往復が 2 回必要になります。それを避けたい場合は、lua スクリプトを作成できます。レート制限 lua スクリプトは良い出発点です。

于 2012-08-20T11:42:43.247 に答える
3

次の提案があります。

単純なアプローチは、現在のシーケンス値を保持するレコードに非常に細かいロックが含まれるため、問題があります。非常に多くのクライアントがいると、耐え難い競合が発生します。

私の提案は、クライアントが一連のシーケンスで予約を実行できるようにすることです。したがって、クライアントは初めて、たとえば 1 から 1000 までの範囲を注文します。この注文の処理は同期されます。したがって、別の人が同時に範囲を要求した場合、ブロックして後で範囲 1001 から 2000 を受け取る必要があります。

各クライアントは、互いに素なシーケンスのプールを取得し、そこから値を取得します。プールが使い果たされるとすぐに、データベースに別の範囲を要求します。前述のように、これにはロックが含まれます。

問題は、範囲のサイズを微調整して、ロックの競合とリソースの使用率をトレードオフできることです (予約された範囲が完全に使用されることは保証されていません。クライアントは、シーケンスが不要になったか、完全にクラッシュする可能性があります)。

于 2012-08-19T18:10:45.240 に答える