2012-04-06 11 views
3

redisが過負荷になる場合は、設定要求を削除するように設定できますか?私はデータがリアルタイムで更新されるアプリケーションを持っています(アイテムごとに10〜15回/秒)、多数のアイテムがあります。値はすぐに古くなり、一貫性は必要ありません。redisに過負荷がかかるとどうなりますか?

リアルタイムで書かれた値の並列和も計算したいと思います。ここで最高のオプションは何ですか? LUAは赤十字で実行されましたか? UNIXソケットを使用して赤いボックスと同じボックスにある小さなアプリですか?

答えて

1

Redisが過負荷になると、クライアントの速度が低下します。ほとんどのコマンドでは、プロトコル自体は同期しています。

Redisはパイプライニングをサポートしていますが、クライアントがパイプラインに残っているトラフィックを取り消すことはできませんが、サーバーによってまだ確認されていません。 Redis自体は実際に着信トラフィックをキューに入れるわけではなく、TCPスタックはそれを行います。

したがって、設定要求を削除するようにRedisサーバーを構成することはできません。しかし、クライアント側での最後の値のキューを実装することが可能である:

  • キューは実際にあなたの項目でインデックス化2つのマップで表現(項目ごとに保存された唯一の値)です。プライマリマップはアプリケーションによって使用されます。セカンダリマップは、特定のスレッドによって使用されます。 2つのマップコンテンツは、原子的な方法でスワップすることができます。

  • プライマリマップが空の場合、特定のスレッドがブロックされています。そうでない場合は、2つのマップの内容を交換し、アグレッシブなパイプライニングとvariadic parametersコマンドを使用して、セカンダリマップの内容をRedisに非同期に送信します。それはまたレディスからの肯定を受けます。

  • スレッドがセカンダリマップを使用している間、アプリケーションはまだプライマリマップを埋めることができます。 Redisが遅すぎる場合、アプリケーションはプライマリマップの最後の値のみを蓄積します。

この戦略は、hiredisと任意のイベントループを使用してCで実装できます。

しかし、実装するのは簡単ではないので、私は最初に、Redisのパフォーマンスがであるかどうかを確認します。すべてトラフィックは私の目的にとって十分ではありません。レディスのベンチマークは、最近では500K以上の単価で(シングルコアを使用して)行われることは珍しくありません。必要に応じて、複数のRedisインスタンスでデータを破棄することはできません。

RedisサーバーのCPUの前にネットワークリンクが飽和している可能性があります。そのため、最後の値キュー(必要に応じて)をサーバー側ではなくクライアント側に実装する方が良い理由があります。

合計計算に関しては、リアルタイムで計算して維持しようとします。たとえば、GETSETコマンドを使用して新しい値を設定し、前の値を戻すことができます。

代わりに自分の値を設定するので、あなたができる:

[old value] = GETSET item <new value> 
INCRBY mysum [new value] - [old value] 

mysumキーは任意の時点で、すべての項目について、あなたの値の合計が含まれます。 Redis 2.6では、Luaを使用してこの計算を包み込み、ラウンドトリップを節約できます。

既存のデータの統計を計算するために大きなバッチを実行しています(これがあなたの「並列」合計を理解する方法です)は、Redisにはあまり適していません。計算のようにmap/reduceのために設計されていません。

+0

私は心配しているCPUではありませんが、ネットワークのリンクです。私はクラウドホスティング環境でこのアプリケーションを実行するつもりです。営業担当者は、自分のクラウドインスタンスが100MB/sしか得られないと言いました。 – jz87

+0

同期プロトコルでは、クライアント側の最後の値キューがあなたが提案したように最善のオプションだと思います。私はプロトコルが非同期になることが恐れていました。その場合、これはもっと難しくなります。 – jz87

関連する問題