6

Redisトランザクションとパイプラインの違い、そして最終的にはBooksleeveでパイプラインを使用する方法について少し混乱しています。BooksleeveはRedisトランザクション機能(/ )をサポートしているようですが、パイプライン機能についてのAPI/テストには言及されていません。ただし、他の実装では、パイプラインとトランザクションの間に違いがあることは明らかです。つまり、以下のredis-rubyバージョンで証明されているように、アトミック性ですが、一部の場所では、これらの用語は同じ意味で使用されているようです。MULTIEXEC

redis-rubyの実装:

r.pipelined {
  # these commands will be pipelined
  r.get("insensitive_key")
}

r.multi {
  # these commands will be executed atomically
  r.set("sensitive_key")
}

MULTI代わりに/を使用EXECしますが、トランザクションが完了するまで他のすべてのユーザーをブロックしているように見えるので(私の場合は必要ありません)、パフォーマンスが心配です。Booksleeveでパイプラインを使用したり、それらを実装する方法についてアイデアを持っている人はいますか?

4

3 に答える 3

6

BookSleeveでは、すべてが常にパイプライン化されます。同期操作はありません。単一のものではありません。そのため、すべての操作は何らかの形式Task(バニラTaskの場合もあればTask<string>、、Task<long>などの場合もあります)を返します。これは、将来のある時点(つまり、redisが応答するとき)に値を持ちます。Wait呼び出し元のコードで同期待機を実行するために使用するか、 ContinueWith/ await(C#5言語機能)を使用して非同期コールバックを実行することができます。

トランザクションも同じです。それらはパイプライン化されています。トランザクションに関する唯一の微妙な変更は、完了するまで呼び出しサイトで追加でバッファリングされることです(マルチプレクサであるため、完全な作業単位が得られるまで、トランザクション関連のメッセージのパイプライン化を開始できません。同じマルチプレクサ上の他の発信者に悪影響を及ぼします)。

つまり、明示的なものがない理由.pipelinedは、すべてがパイプライン化されて非同期であるためです。

于 2012-10-11T06:51:58.347 に答える
4

パイプライン化はプロトコルレベルの通信戦略であり、アトミック性とは何の関係もありません。これは、「トランザクション」の概念と完全に直交しています。(たとえばMULTI .. EXEC、パイプライン接続で使用できます。)

パイプラインとは何ですか?

redisへの最も基本的なコネクタは、要求と応答の方法で対話する同期クライアントです。クライアントはリクエストを送信し、Redisからの応答を待ってから次のリクエストを送信します。

パイプライン処理では、クライアントは、各リクエストのRedis応答を確認するために一時停止することなく、リクエストを送信し続けることができます。もちろん、Redisはシングルスレッドサーバーであり、自然なシリアル化ポイントであるため、要求の順序は保持され、応答の順序に反映されます。つまり、クライアントは1つのスレッドでリクエストを送信でき(通常はリクエストキューからデキューすることで)、別のスレッドがRedisからの応答を常に処理しています。もちろん、シングルスレッドクライアントでパイプラインを使用することはできますが、効率の一部が失われることに注意してください。2スレッドモデルでは、ローカルCPUとネットワーク帯域幅(飽和など)を最大限に活用できます。

これまでこれをフォローしている場合は、自問する必要があります。クライアント側でリクエストとレスポンスはどのように一致していますか?良い質問!これにアプローチするにはさまざまな方法があります。JRedisではFuture、要求/応答処理の非同期性に対処するために、要求を(java)オブジェクトでラップします。リクエストが送信されるたびに、対応するFutureオブジェクトは保留中のレスポンスオブジェクトによってラップされ、キューに入れられます。応答リスナーは、このキューから一度に1つのアイテムをデキューし、応答(ストリーム)を解析して、将来のオブジェクトを更新するだけです。

これで、クライアントのエンドユーザーは、同期インターフェイスまたは非同期インターフェイスのいずれかに公開できます。インターフェイスが同期している場合、実装は当然、Futureの応答をブロックする必要があります。

これまでのところ、パイプラインを使用した同期セマンティクスを使用するシングルスレッドアプリは、パイプラインの目的全体を無効にすることは明らかです(アプリは応答をブロックしており、クライアントに追加のリクエストを送信するのに忙しくないため)。アプリはマルチスレッドであり、パイプラインへの同期インターフェイスにより、 N個のクライアントアプリスレッドを処理しながら単一の接続を使用できます。(したがって、ここでは、スレッドセーフな接続の構築を支援する実装戦略です。)

パイプラインへのインターフェースが非同期の場合、シングルスレッドのクライアントアプリでもメリットがあります。スループットは少なくとも1桁増加します。

(パイプラインに関する警告:フォールトトレラントなパイプラインクライアントを作成することは簡単ではありません。)

理想的には図を使用する必要がありますが、クリップの最後で何が起こるかに注意してください: http ://www.youtube.com/watch?v=NeK5ZjtpO-M

于 2011-12-07T18:16:49.063 に答える
1

これがRedisトランザクションドキュメントへのリンクです

BookSleeveについては、Marcのこの投稿を参照してください。

「CreateTransaction()は、(まったく同じAPIを使用して)コマンドを構築し、将来の結果をキャプチャするためのステージング領域を作成します。次に、Execute()が呼び出されると、バッファリングされたコマンドがMULTI / EXECユニットにアセンブルされ、連続したブロックに送信されます(マルチプレクサは、明らかにこれらすべてを一緒に送信します。」

トランザクション内でコマンドを作成すると、コマンドは自動的に「パイプライン化」されます。

于 2011-12-07T01:52:52.357 に答える