Couchbaseサーバのクラスタにおける主要な操作として、リバランスがあります。Couchbaseのシステム管理者は新しいサーバの追加、古いサーバの撤去などにともない、リバランスを実行する必要があります。リバランスの中身はあるCouchbaseサーバから他のCouchbaseサーバへのvBucket(そしてvBucket内のアイテム)の移行です。
Couchbaseクラスタとクライアントという分散環境の性質上、vBucketの所有者情報が変化し、あるサーバからあるサーバへ移行しても、クライアントライブラリがそのことを知らない期間があります。そこで、クライアントライブラリは、あるアイテムに対して間違った(古い)サーバと接続しようとします。なぜなら、クライアントサーバは古いvBucketサーバマップで動作しているからです。
以下はこの状況のより詳細なウォークスルーとその対処法です。
リバランスが開始する前には、既存の、接続済みクライアントは、リバランス前のクラスタのvBucketサーバマップで動作していなければなりません。
Couchbaseはリバランスを開始すると即座に、更新されたvBucketサーバマップのメッセージを(ストリーミングREST/JSONのチャネルを介して)、"ブロードキャスト"します。サーバに対するvBucketsの割り当ては、実際にリバランス開始のこの時点では変更されませんが、Couchbaseクラスタ内のすべてのサーバのserverListは、変更されます。つまり、vBucketsはまだ動かさずに(あるいはちょうど動き始めている)、クライアントライブラリがクラスタに参加した新しいCouchbaseサーバのアドレスを知っている状態です。クラスタ内のすべてのサーバ(新しく追加されたサーバを含む)を知ることは、重要です。
この時点で、Couchbaseクラスタは、あるサーバから別サーバにvBucketsを移行するのに忙しくなります。
同時に、クライアントライブラリは、リバランス前のvBucketサーバマップを使用してアイテムデータの操作(取得/設定/削除など)を実行しようとします。しかし、いくつかのvBucketsは、既に新しいサーバに移行されている可能性があります。このケースでは、クライアントライブラリが使用しようとしたサーバは、NOT_MY_VBUCKETのエラー応答(サーバは、クライアントライブラリが要求時にエンコードしたvBucketIdを知っています)を返します。
クライアントライブラリは、NOT_MY_VBUCKETのエラー応答を受けると、クラスタ内の別のサーバーに対して要求を再試行する必要があります。もちろん、再試行でもNOT_MY_VBUCKETのエラー応答を受け失敗する場合がありますが、クライアントライブラリはクラスタ内の別のサーバーに対して探索し続ける必要があります。
最終的に、一つのサーバーが正しく応答し、クライアントライブラリはそのvBucketIdの新しい、正しい所有者を自己解決します。クライアントライブラリは、今後のアクセスに使用するために、新しいマッピングをvBucketサーバマップに記録するべきです。
この実装は、libvBucket APIの
vbucket_found_incorrect_master()
を参照してください。
以下は、NOT_MY_VBUCKETエラーの間、moxiがどのようにlibvBucketとやり取りするかを示したスイムレーン図です。libvbucket_notmyvbucket.pdf
リバランスの最後に、Couchbaseクラスタは、最終的に新しいvBucketサーバマップを、REST/JSONクライアントにストリーミング通知します。これは、他のvBucketサーバマップの更新のメッセージと同様に、クライアントライブラリで処理することができます。リバランス中の一時的な状態はクライアントに通知されないため、クライアントは自力で正しいvBucketを探します。