概要
ドキュメント指向型 NoSQL である Couchbase を初めて触ってみました。目的としては、Couchbaseに格納したドキュメントがどのData Service ノードに格納されているのかを確認することです。CLI でやっていますが、特に理由は無いので作業はコンソールから行うほうが簡単です。couchbase-cli や cbq などをごちゃまぜで使ってしまっているので、もっとスマートな方法があるかと思います。
vBuckets とは
Couchbase にドキュメントを格納するためには、バケットを作成する必要があります。このバケットですが、実際には 1024(macOSだと64)の vBuckets に分割されており、それらが Data Service の稼働するノードに分散格納されています。
ドキュメントがどの vBucket/どのノードに格納されるかは「①ドキュメントのキー値をハッシュ化し vBucket 番号を算出」「②Cluster Manager が vBucket とノードをマッピング」というような流れで決まるようです。
やったこと
概要
以下のような流れでやってみました。
- バケットを作成
- 適当なドキュメントを格納
- ドキュメントのキー値を取得
- キー値から格納先 vBucket/ノード情報を確認
環境
CentOS 上に Docker をインストールし、3ノードの Couchbase クラスタを構成して作業を行いました。コンテナ名はcb1~3とし、すべてで Data Service を有効化しています。
$ cat /etc/centos-release
CentOS Linux release 8.3.2011
$ docker -v
Docker version 20.10.6, build 370c289
$ docker exec cb1 couchbase-server -v
Couchbase Server 6.6.2-9588 (EE)
後続の作業は、コンテナcb1に接続して実施しています。コンテナとIPアドレスとの対応は以下の通りです。また、Couchbaseの操作は管理ユーザとして作成した Administrator(パスワード:password)で実行しています。
| コンテナ名 | IPアドレス |
|---|---|
| cb1 | 172.17.0.2 |
| cb2 | 172.17.0.3 |
| cb3 | 172.17.0.4 |
バケットの作成
作業用バケットとして test-bucket を作成します。作成と確認は、couchbase-cli を使用して行いました。引数についてはマニュアルに記載があるので、詳細はそちらが参考になります。
# バケットの作成
$ couchbase-cli bucket-create \
-c couchbase://172.17.0.2 \
--bucket test-bucket \
--bucket-type couchbase \
--bucket-ramsize 256 \
--bucket-replica 1 \
--durability-min-level none \
--wait
# 確認
$ couchbase-cli bucket-list -c couchbase://172.17.0.2
test-bucket
bucketType: membase
numReplicas: 1
ramQuota: 805306368
ramUsed: 61442848
ドキュメントの格納
ここでは cbq を使用してデータを格納します。雑ですが、管理ユーザでやってしまっています。
# cbqで接続
$ cbq -e http://172.17.0.2:8091 -u Administrator -p password
# Insertを実行
cbq> insert into `test-bucket` (KEY, VALUE) values ("testKey", {"name": "Taro", "status": "working"});
ドキュメントと vBucket の対応付け
格納したドキュメントがどの vBucket に格納されているかを確認するために、まずドキュメントのキー値を取得します。今回は Insert 実行時に "testKey" として明示指定していますが、例えば cbimport を使用すると #UUID# を指定してキー値を生成することができるため、別途確認を行う必要があります。その場合、以下のようにしてバケットの meta() から取得することができます。
# 存在しない場合、索引を作成(N1QLでは検索のために索引が必要)
# ここではPrimary Indexを作成
cbq> create primary index test_prim_idx on `test-bucket`;
# バケットのメタ情報からidを取得
cbq> select meta(t).id from `test-bucket` t;
:
"results": [
{
"id": "testKey"
}
:
キー値がわかったら cbc hash コマンド を使用することで、ドキュメントがどの vBucket /ノードに格納されているのかを確認することができます。
$ cbc hash testKey -U couchbase://localhost/test-bucket -u Administrator -P password
testKey: [vBucket=705, Index=2] Server: 172.17.0.4:11210, CouchAPI: http://172.17.0.4:8092/test-bucket
Replica #0: Index=0, Host=172.17.0.2:11210
これより、以下ということがわかります。
| 項目 | 値 |
|---|---|
| 格納先の vBucket 番号 | 705 |
| アクティブ・データ | cb3(172.17.0.4) |
| レプリカ・データ | cb1(172.17.0.2) |
以上から、ドキュメントとその格納先である vBucket を対応付けることができました。
なお、cbc hash コマンドは実行時に指定したキー値からハッシュ値を算出し、それに基づいてデータの格納先を返却します。そのため、現時点で存在しない(例えば今後格納予定の)キー値を指定し、確認することもできます。
最後に、念のためcbc hash コマンドで取得した vBucket 番号 705 の格納ドキュメント数などの情報を参照してみます。確認には cbstats を用いました。
# アクティブ・データのあるcb3に対して実行
$ cbstats -u Administrator -p password -b test-bucket 172.17.0.4:11210 vbucket-details 705 | \
grep -E "num_items|topology|vb_705:\s"
vb_705: active
vb_705:num_items: 1
vb_705:topology: [["ns_1@172.17.0.4","ns_1@172.17.0.2"]]
# レプリカ・データのあるcb1に対して確認
$ cbstats -u Administrator -p password -b test-bucket 172.17.0.2:11210 vbucket-details 705 | \
grep -E "num_items|topology|vb_705:\s"
vb_705: replica
vb_705:num_items: 1
vb_705:topology: null
実行結果は 3 つの値のみにフィルタしています。num_items が 1 となっており、active/replica の値も cbc hash の実行結果と一致しているので、上の確認方法で正しそうです。topology (active, replica のノード情報?)はアクティブ・データのあるノードのみから参照できるようです。
以上です。