パイプライン化はプロトコルレベルの通信戦略であり、アトミック性とは何の関係もありません。これは、「トランザクション」の概念と完全に直交しています。(たとえば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