CLOVER🍀

That was when it all began.

CockroachDBクラスターで、ノードを増減・廃止させてみる

これは、なにをしたくて書いたもの?

CockroachDBクラスターでノードの増減を行って、その挙動を見てみようかなと。

ノードの追加と削除

ノードの追加は、cockroach startコマンドで既存のクラスターに参加すれば良さそうですね。

cockroach start | CockroachDB Docs

セキュアなクラスターの場合は、SANを使ってあらかじめノード名を列挙しておくか、ワイルドカードでノード名を
登録しておくと良い気がしますね。

cockroach cert / Node key and certificates

ノードをクラスターから切り離したり(廃止)、ドレインする時にはcockroach nodeコマンドを使います。

cockroach node | CockroachDB Docs

Decommission Node

Decommission Nodeという言葉が、ドキュメントに出てきました。

廃止されたノードのことをDecommission Nodeといい、廃止ノードになるシーケンス中に再稼働させることを
Recommissionというみたいです。

Decommission Nodeについては、こちらに説明があります。

Decommission Nodes | CockroachDB Docs

説明を読んでいると、クラスターから安全にノードを切り離す時に使いそうな感じがします。

ノードは、以下の2つの条件を満たすと廃止された(Decommision Nodeになった)とみなされるようです。

  • The node has completed the decommissioning process.
  • The node has been stopped and has not updated its liveness record for the duration configured via server.time_until_store_dead, which defaults to 5 minutes.

  • 廃止プロセスが完了した

  • ノードが停止していて、server.time_until_store_deadで設定した時間(デフォルト5分)、liveness recordを更新していない場合

廃止プロセス中は、ノード内のすべてのレンジレプリカが他のノードに転送されます。この最中、もしくは完了後、
ノードは「廃止」とみなされ、新しいSQL接続を受け付けます。

データは持っていなくても、Decommission Nodeは接続を目的のデータにルーティングするゲートウェイとして
機能できるようです。

この最中に、復帰(Recommission)させることもできるようです。

すべてのレンジレプリカが転送された後であれば、SIGTERMシグナルを送信することによってGraceful Shutdownを
行うことができます。Graceful Shutdownが始まると、ノードはクライアント、SQL、リースをドレインされ、
ヘルスチェックは503を返すようになります。ドレイン完了後、liveness recordの更新を停止し、
server.time_until_store_dead時間が経過後、廃止された(decommissioned)と見なされます。

Decommission Nodeの注意点

以下に、Decommission Nodenの注意点が書かれています。

Decommission Nodes / Considerations

Decommision Nodeにするためには、他のノードがレプリカを引き継げる必要があります。

例はこちらに書かれていますが

Decommission Nodes / Examples

3ノードで構成するクラスターでレプリケーション係数が3の時に、ノードをひとつ廃止しようとすると、レンジレプリカを
他のノードに移動できないため廃止プロセスはハングします。
※ひとつのレンジレプリカに、複数同じデータを持てないため

レプリケーションの詳細については、こちら。

Replication Layer | CockroachDB Docs

では、ドキュメントからの情報はこれくらいにして、試していってみましょう。

なお、Decommision Nodeのことは「廃止したノード」といった感じで書くことにします…。

環境

今回の環境は、こちら。

$ cockroach --version
cockroach version details:
Build Tag:        v21.2.3
Build Time:       2021/12/14 15:23:22
Distribution:     CCL
Platform:         linux amd64 (x86_64-unknown-linux-gnu)
Go Version:       go1.16.6
C Compiler:       gcc 6.5.0
Build Commit ID:  cb0222a1980b96ad59c181c96fab8340aa252571
Build Type:       release
(use 'cockroach version --build-tag' to display only the build tag)

CockroachDBのノードは、全部で5つ用意することにします。ノード名は、node1.cockroach〜node5.cockroachまでの
5つとします。

準備

まずは、セキュアなクラスターを構築しておきます。

CA証明書の作成。

$ cockroach cert create-ca \
   --certs-dir=/var/lib/cockroach/security/certs \
   --ca-key=/var/lib/cockroach/security/ca/ca.key

ノードの証明書は、DNSワイルドカードを使って登録しておくことにします。

cockroach cert / Node key and certificates

$ cockroach cert create-node \
   localhost \
   *.cockroach \
   --certs-dir=/var/lib/cockroach/security/certs \
   --ca-key=/var/lib/cockroach/security/ca/ca.key

rootユーザーと、自前で作成するユーザーの証明書を作成。

$ cockroach cert create-client \
   root \
   --certs-dir=/var/lib/cockroach/security/certs \
   --ca-key=/var/lib/cockroach/security/ca/ca.key

$ cockroach cert create-client \
   myuser \
   --certs-dir=/var/lib/cockroach/security/certs \
   --ca-key=/var/lib/cockroach/security/ca/ca.key

この/var/lib/cockroach/securityディレクトリは、全CockroachDBノードで共有しているものとします。

とりあえず、3ノードでクラスターを構成しましょう。

## node1.cockroach
$ cockroach start \
   --certs-dir=/var/lib/cockroach/security/certs \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node1.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach


## node2.cockroach
$ cockroach start \
   --certs-dir=/var/lib/cockroach/security/certs \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node2.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach


## node3.cockroach
$ cockroach start \
   --certs-dir=/var/lib/cockroach/security/certs \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node3.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach

残り2つのノードは、まだ使いません。

以降、/var/lib/cockroach/security/certsディレクトリを$CERTS_DIRと表記します。

$ CERTS_DIR=/var/lib/cockroach/security/certs

node1.cockroachで、クラスターを初期化。

$ cockroach init --certs-dir=$CERTS_DIR
Cluster successfully initialized

クラスターが構成されました。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
(3 rows)

ユーザーも作成して

$ cockroach sql --certs-dir=$CERTS_DIR -e 'create user myuser password "password"; grant admin to myuser;'

サンプルデータとして、movrワークロードを登録します。

$ cockroach workload init movr "postgresql://myuser@localhost:26257?sslcert=$CERTS_DIR/client.myuser.crt&sslkey=$CERTS_DIR/client.myuser.key&sslmode=verify-full&sslrootcert=$CERTS_DIR/ca.crt"

データとしては、これだけ入るようです。

I211219 10:36:24.783400 1 workload/workloadsql/dataload.go:146  [-] 1  imported users (0s, 50 rows)
I211219 10:36:24.843771 1 workload/workloadsql/dataload.go:146  [-] 2  imported vehicles (0s, 15 rows)
I211219 10:36:24.947685 1 workload/workloadsql/dataload.go:146  [-] 3  imported rides (0s, 500 rows)
I211219 10:36:25.047812 1 workload/workloadsql/dataload.go:146  [-] 4  imported vehicle_location_histories (0s, 1000 rows)
I211219 10:36:25.211770 1 workload/workloadsql/dataload.go:146  [-] 5  imported promo_codes (0s, 1000 rows)

cockroach node statusコマンドで、各ノードの状態を確認。

cockroach node | CockroachDB Docs

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.258227 | 2021-12-19 10:37:00.427624 |          |         true |    true |               30 |                    30 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.646529 | 2021-12-19 10:37:00.755195 |          |         true |    true |               23 |                    23 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:07.746837 | 2021-12-19 10:36:57.4232   |          |         true |    true |               20 |                    20 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
(3 rows)

データの分布状態の確認。

$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 3 | {1,2,3}
rides | 46 | 3 | {1,2,3}
rides | 95 | 3 | {1,2,3}
rides | 94 | 1 | {1,2,3}
rides | 92 | 3 | {1,2,3}
rides | 93 | 2 | {1,2,3}
rides | 90 | 3 | {1,2,3}
rides | 96 | 1 | {1,2,3}
rides | 91 | 2 | {1,2,3}
rides | 70 | 2 | {1,2,3}
user_promo_codes | 49 | 2 | {1,2,3}
users | 44 | 2 | {1,2,3}
users | 53 | 3 | {1,2,3}
users | 52 | 2 | {1,2,3}
users | 51 | 2 | {1,2,3}
users | 67 | 3 | {1,2,3}
users | 50 | 2 | {1,2,3}
users | 66 | 2 | {1,2,3}
users | 64 | 2 | {1,2,3}
users | 65 | 1 | {1,2,3}
vehicle_location_histories | 47 | 2 | {1,2,3}
vehicles | 45 | 3 | {1,2,3}
vehicles | 88 | 2 | {1,2,3}
vehicles | 87 | 2 | {1,2,3}
vehicles | 86 | 2 | {1,2,3}
vehicles | 68 | 1 | {1,2,3}
vehicles | 84 | 3 | {1,2,3}
vehicles | 89 | 2 | {1,2,3}
vehicles | 85 | 2 | {1,2,3}
vehicles | 69 | 2 | {1,2,3}

こちらは、以下のSQL文を使っています。

SHOW RANGES | CockroachDB Docs

これで、準備完了です。

これ以降、cockroach start 以外の cockroachコマンドは、すべてnode1.cockroachノードで実行しているものとします。

ノードを追加する

ではここで、ノードを追加してみましょう。

このクラスターに、node4.cockroachを追加してみます。node4.cockroachノードで、以下のコマンドを実行。

$ cockroach start \
   --certs-dir=$CERTS_DIR \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node4.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach

4ノードになりました。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
   4
(4 rows)

cockroach node statusを見ると、リバランスしていっているのが確認できます。

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.258227 | 2021-12-19 10:38:52.871152 |          |         true |    true |               23 |                    23 |     66 |                  0 |           0            |                63 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.646529 | 2021-12-19 10:38:48.748094 |          |         true |    true |               19 |                    19 |     64 |                  0 |           0            |                63 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:07.746837 | 2021-12-19 10:38:49.810784 |          |         true |    true |               17 |                    17 |     65 |                  0 |           0            |                64 |       false        |   active   |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 10:38:12.50393  | 2021-12-19 10:38:48.61277  |          |         true |    true |               14 |                    14 |     29 |                  0 |           0            |                29 |       false        |   active   |    false
(4 rows)

ノードが追加、停止した時のリバランスについては、こちらに記載があります。

Overview / Membership changes: rebalance/repair

追加時は、こうですね。新しいスペースに対してリバランスを行う、としか書かれていませんが。

Nodes added: The new node communicates information about itself to other nodes, indicating that it has space available. The cluster then rebalances some replicas onto the new node.

最終的には、ここで落ち着きました。

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.258227 | 2021-12-19 10:40:09.346323 |          |         true |    true |               21 |                    21 |     56 |                  0 |           0            |                56 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.646529 | 2021-12-19 10:40:09.765978 |          |         true |    true |               21 |                    21 |     57 |                  0 |           0            |                57 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:07.746837 | 2021-12-19 10:40:10.808903 |          |         true |    true |               17 |                    17 |     56 |                  0 |           0            |                56 |       false        |   active   |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 10:38:12.50393  | 2021-12-19 10:40:09.584081 |          |         true |    true |               14 |                    14 |     50 |                  0 |           0            |                50 |       false        |   active   |    false
(4 rows)

データの分布の確認。

$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 4 | {1,3,4}
rides | 46 | 1 | {1,2,3}
rides | 95 | 2 | {1,2,3}
rides | 94 | 4 | {1,2,4}
rides | 92 | 3 | {1,2,3}
rides | 93 | 2 | {1,2,4}
rides | 90 | 3 | {2,3,4}
rides | 96 | 1 | {1,2,4}
rides | 91 | 3 | {1,2,3}
rides | 70 | 2 | {1,2,3}
user_promo_codes | 49 | 2 | {2,3,4}
users | 44 | 2 | {1,2,3}
users | 53 | 3 | {2,3,4}
users | 52 | 2 | {1,2,3}
users | 51 | 4 | {2,3,4}
users | 67 | 3 | {1,2,3}
users | 50 | 2 | {2,3,4}
users | 66 | 2 | {2,3,4}
users | 64 | 4 | {1,3,4}
users | 65 | 1 | {1,3,4}
vehicle_location_histories | 47 | 2 | {1,2,3}
vehicles | 45 | 3 | {1,2,3}
vehicles | 88 | 4 | {2,3,4}
vehicles | 87 | 3 | {1,3,4}
vehicles | 86 | 3 | {1,3,4}
vehicles | 68 | 1 | {1,3,4}
vehicles | 84 | 1 | {1,2,3}
vehicles | 89 | 2 | {1,2,4}
vehicles | 85 | 4 | {1,2,4}
vehicles | 69 | 2 | {1,2,4}

ノード証明書にDNSワイルドカードを使っておくと、ノード追加が楽にできますね。

ノードを停止する

次に、クラスターからノードを強制停止して削除してみます。

このテーマについては、1度こちらで少し扱っているのですが。

CockroachDBで、データがどのノードに割り当てられているか確認する - CLOVER🍀

改めて、もう1度。

node4.cockroachで、cockroachプロセスをkillしてみます。

$ kill `pgrep cockroach`

ちなみに、これだとGraceful Shutdownになるようですが…。

initiating graceful shutdown of server
server drained and shutdown completed

cockroach node statusで見ると、membershipとis_drainingがfalseになっています。離脱中、ですね。

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.258227 | 2021-12-19 10:44:52.822427 |          |         true |    true |               27 |                    27 |     56 |                  0 |           18           |                56 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.646529 | 2021-12-19 10:44:53.214879 |          |         true |    true |               25 |                    25 |     57 |                  0 |           17           |                57 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:07.746837 | 2021-12-19 10:44:49.81032  |          |         true |    true |               21 |                    21 |     56 |                  0 |           15           |                56 |       false        |   active   |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 10:38:12.50393  | 2021-12-19 10:44:15.548517 |          |        false |   false |               14 |                    14 |     50 |                  0 |           0            |                50 |       false        |   active   |    true
(4 rows)

他のノードは、ranges_underreplicatedという項目の数字が増えています。これは、レプリカが使用できないレンジの数を
表しています。

この数字が0以外の場合は、クラスターがまだ安定していないことを表しているようです。

この時、Web UIで見るとSUSPECTという状態になっています。

f:id:Kazuhira:20211219194825p:plain

さらにしばらく待っていると、DEADになります。

f:id:Kazuhira:20211219194959p:plain

ステータスの遷移に時間がかかるのは、データのリバランスを開始するまでに5分かけるから、みたいですね。

Nodes going offline: If a member of a Raft group ceases to respond, after 5 minutes, the cluster begins to rebalance by replicating the data the downed node held onto other nodes.

Overview / Membership changes: rebalance/repair

DEADになっても、クラスターのメンバー一覧にはまだ残ったままです。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
   4
(4 rows)

cockroach node statusではこのようになります。ranges_underreplicatedが0になりました。

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.258227 | 2021-12-19 10:50:48.310116 |          |         true |    true |               27 |                    27 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.646529 | 2021-12-19 10:50:48.727116 |          |         true |    true |               25 |                    25 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:07.746837 | 2021-12-19 10:50:45.332459 |          |         true |    true |               21 |                    21 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 10:38:12.50393  | 2021-12-19 10:44:15.548517 |          |        false |   false |               14 |                    14 |     50 |                  0 |           0            |                 0 |       false        |   active   |    true
(4 rows)

データとしても、リバランスが終わりましたね。

$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 3 | {1,2,3}
rides | 46 | 1 | {1,2,3}
rides | 95 | 2 | {1,2,3}
rides | 94 | 1 | {1,2,3}
rides | 92 | 3 | {1,2,3}
rides | 93 | 2 | {1,2,3}
rides | 90 | 3 | {1,2,3}
rides | 96 | 1 | {1,2,3}
rides | 91 | 3 | {1,2,3}
rides | 70 | 2 | {1,2,3}
user_promo_codes | 49 | 2 | {1,2,3}
users | 44 | 2 | {1,2,3}
users | 53 | 3 | {1,2,3}
users | 52 | 2 | {1,2,3}
users | 51 | 2 | {1,2,3}
users | 67 | 3 | {1,2,3}
users | 50 | 2 | {1,2,3}
users | 66 | 2 | {1,2,3}
users | 64 | 1 | {1,2,3}
users | 65 | 1 | {1,2,3}
vehicle_location_histories | 47 | 2 | {1,2,3}
vehicles | 45 | 3 | {1,2,3}
vehicles | 88 | 2 | {1,2,3}
vehicles | 87 | 3 | {1,2,3}
vehicles | 86 | 3 | {1,2,3}
vehicles | 68 | 1 | {1,2,3}
vehicles | 84 | 1 | {1,2,3}
vehicles | 89 | 2 | {1,2,3}
vehicles | 85 | 2 | {1,2,3}
vehicles | 69 | 2 | {1,2,3}

ところで、停止したノードは一覧から削除できないのでしょうか?

ここでcockroach node decommissionを使います。

$ cockroach node decommission --certs-dir=$CERTS_DIR 4

ドキュメントとしては、こちらに記載があります。

Decommission Nodes / Remove a single node (dead)

このコマンドのレスポンスは、このようになります。

  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  false  |        0 |        true        | decommissioning |    true
(1 row)

No more data reported on target nodes. Please verify cluster health before removing the nodes.

cockroach node statusの方では依然として表示されますが、こちらは過去にいたノードの情報も含めて
表示するからのようです。
※--decommissionまたは--allを使った場合

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning |   membership   | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+----------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.258227 | 2021-12-19 11:06:06.296492 |          |         true |    true |               27 |                    27 |     73 |                  0 |           0            |                73 |       false        |     active     |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:06.646529 | 2021-12-19 11:06:06.706032 |          |         true |    true |               25 |                    25 |     73 |                  0 |           0            |                73 |       false        |     active     |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 10:36:07.746837 | 2021-12-19 11:06:07.817467 |          |         true |    true |               21 |                    21 |     73 |                  0 |           0            |                73 |       false        |     active     |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 10:38:12.50393  | 2021-12-19 11:05:10.77051  |          |        false |   false |             NULL |                  NULL |   NULL |               NULL |          NULL          |                 0 |        true        | decommissioned |    true
(4 rows)

これがノードの廃止、ですね。

ノードを廃止する

先ほどは、すでに停止したノードに対してcockroach node decommissionを実行しました。
今度は、起動しているノードに対して実行するケースを考えてみましょう。

クラスターは再作成しました。クラスターおよびデータの状態。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
(3 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:14.070428 | 2021-12-19 11:16:36.655673 |          |         true |    true |               26 |                    26 |     62 |                  0 |           29           |                67 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:15.943274 | 2021-12-19 11:16:34.035422 |          |         true |    true |               10 |                    10 |     37 |                  0 |           0            |                43 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:16.096537 | 2021-12-19 11:16:34.245839 |          |         true |    true |               15 |                    15 |     37 |                  0 |           0            |                43 |       false        |   active   |    false
(3 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 2 | {1,2,3}
rides | 46 | 2 | {1,2,3}
rides | 71 | 1 | {1,2,3}
rides | 70 | 2 | {1,2,3}
rides | 68 | 2 | {1,2,3}
rides | 69 | 1 | {1,2,3}
rides | 67 | 1 | {1,2,3}
rides | 60 | 1 | {1,2,3}
rides | 59 | 3 | {1,2,3}
rides | 81 | 2 | {1,2,3}
user_promo_codes | 49 | 2 | {1,2,3}
users | 44 | 1 | {1,2,3}
users | 53 | 3 | {1,2,3}
users | 52 | 3 | {1,2,3}
users | 51 | 2 | {1,2,3}
users | 66 | 2 | {1,2,3}
users | 50 | 2 | {1,2,3}
users | 65 | 3 | {1,2,3}
users | 64 | 3 | {1,2,3}
users | 74 | 3 | {1,2,3}
vehicle_location_histories | 47 | 2 | {1,2,3}
vehicles | 45 | 3 | {1,2,3}
vehicles | 80 | 1 | {1,2,3}
vehicles | 79 | 2 | {1,2,3}
vehicles | 55 | 3 | {1,2,3}
vehicles | 78 | 2 | {1,2,3}
vehicles | 54 | 3 | {1,2,3}
vehicles | 77 | 3 | {1,2,3}
vehicles | 75 | 3 | {1,2,3}
vehicles | 76 | 2 | {1,2,3}

新しくノードを追加します。node4.cockroachで、ノードを起動。

$ cockroach start \
   --certs-dir=$CERTS_DIR \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node4.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach

クラスターへの参加およびデータのリバランスが完了するまで待ちます。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
   4
(4 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:14.070428 | 2021-12-19 11:20:12.677242 |          |         true |    true |               22 |                    22 |     56 |                  0 |           0            |                56 |       false        |   active   |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:15.943274 | 2021-12-19 11:20:10.064974 |          |         true |    true |               19 |                    19 |     57 |                  0 |           0            |                57 |       false        |   active   |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:16.096537 | 2021-12-19 11:20:10.404194 |          |         true |    true |               18 |                    18 |     56 |                  0 |           0            |                56 |       false        |   active   |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 11:18:03.424437 | 2021-12-19 11:20:13.97675  |          |         true |    true |               14 |                    14 |     50 |                  0 |           0            |                50 |       false        |   active   |    false
(4 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 1 | {1,2,3}
rides | 46 | 1 | {1,2,4}
rides | 71 | 1 | {1,3,4}
rides | 70 | 2 | {2,3,4}
rides | 68 | 2 | {2,3,4}
rides | 69 | 4 | {1,2,4}
rides | 67 | 4 | {1,2,4}
rides | 60 | 1 | {1,2,4}
rides | 59 | 3 | {1,2,3}
rides | 81 | 3 | {1,3,4}
user_promo_codes | 49 | 2 | {2,3,4}
users | 44 | 4 | {1,3,4}
users | 53 | 3 | {2,3,4}
users | 52 | 3 | {2,3,4}
users | 51 | 1 | {1,2,3}
users | 66 | 3 | {1,3,4}
users | 50 | 1 | {1,3,4}
users | 65 | 3 | {2,3,4}
users | 64 | 3 | {2,3,4}
users | 74 | 2 | {2,3,4}
vehicle_location_histories | 47 | 2 | {2,3,4}
vehicles | 45 | 4 | {1,3,4}
vehicles | 80 | 1 | {1,2,4}
vehicles | 79 | 2 | {1,2,3}
vehicles | 55 | 1 | {1,2,4}
vehicles | 78 | 2 | {1,2,3}
vehicles | 54 | 1 | {1,2,3}
vehicles | 77 | 3 | {1,3,4}
vehicles | 75 | 3 | {1,2,3}
vehicles | 76 | 2 | {1,2,4}

ここで、ノードを廃止する際にはcockroach node decommissionか、cockroach node drainがありそうです。

$ cockroach node -h
List, inspect, drain or remove nodes.

Usage:
  cockroach node [command] [flags]
  cockroach node [command]

Available Commands:
  ls           lists the IDs of all nodes in the cluster
  status       shows the status of a node or all nodes
  decommission decommissions the node(s)
  recommission recommissions the node(s)
  drain        drain a node without shutting it down

〜省略〜

ここから参考にするドキュメントは、こちらです。

Decommission Nodes / Remove a single node (live)

まずはcockroach node decommissionから使ってみましょう。

$ cockroach node decommission --certs-dir=$CERTS_DIR 4

コマンドを実行すると、対象のノードのレプリカがどんどん減っていく様子が表示されます。

  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |       50 |        true        | decommissioning |    false
(1 row)
..........
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |       48 |        true        | decommissioning |    false
(1 row)
...
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |       46 |        true        | decommissioning |    false
(1 row)
.......
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |       45 |        true        | decommissioning |    false
(1 row)
......
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |       44 |        true        | decommissioning |    false
(1 row)
........                                                                     

しばらく待っていると、最終的にはレプリカが0になって完了します。

.......
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |        3 |        true        | decommissioning |    false
(1 row)
..........
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |        2 |        true        | decommissioning |    false
(1 row)
...........
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |        1 |        true        | decommissioning |    false
(1 row)
.............
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   4 |  true   |        0 |        true        | decommissioning |    false
(1 row)

No more data reported on target nodes. Please verify cluster health before removing the nodes.

データもリバランスされ、ノードもクラスターから切り離されました。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
(3 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning |   membership   | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+----------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:14.070428 | 2021-12-19 11:26:30.621353 |          |         true |    true |               29 |                    29 |     73 |                  0 |           0            |                73 |       false        |     active     |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:15.943274 | 2021-12-19 11:26:32.508758 |          |         true |    true |               22 |                    22 |     73 |                  0 |           0            |                73 |       false        |     active     |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:16.096537 | 2021-12-19 11:26:32.685638 |          |         true |    true |               22 |                    22 |     73 |                  0 |           0            |                73 |       false        |     active     |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 11:18:03.424437 | 2021-12-19 11:25:09.355884 |          |        false |   false |             NULL |                  NULL |   NULL |               NULL |          NULL          |                 0 |        true        | decommissioned |    false
(4 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] |
 $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 1 | {1,2,3}
rides | 46 | 1 | {1,2,3}
rides | 71 | 1 | {1,2,3}
rides | 70 | 2 | {1,2,3}
rides | 68 | 2 | {1,2,3}
rides | 69 | 2 | {1,2,3}
rides | 67 | 1 | {1,2,3}
rides | 60 | 1 | {1,2,3}
rides | 59 | 3 | {1,2,3}
rides | 81 | 3 | {1,2,3}
user_promo_codes | 49 | 2 | {1,2,3}
users | 44 | 3 | {1,2,3}
users | 53 | 3 | {1,2,3}
users | 52 | 3 | {1,2,3}
users | 51 | 1 | {1,2,3}
users | 66 | 3 | {1,2,3}
users | 50 | 1 | {1,2,3}
users | 65 | 3 | {1,2,3}
users | 64 | 3 | {1,2,3}
users | 74 | 2 | {1,2,3}
vehicle_location_histories | 47 | 2 | {1,2,3}
vehicles | 45 | 1 | {1,2,3}
vehicles | 80 | 1 | {1,2,3}
vehicles | 79 | 2 | {1,2,3}
vehicles | 55 | 1 | {1,2,3}
vehicles | 78 | 2 | {1,2,3}
vehicles | 54 | 1 | {1,2,3}
vehicles | 77 | 3 | {1,2,3}
vehicles | 75 | 3 | {1,2,3}
vehicles | 76 | 2 | {1,2,3}

これで、ノードの廃止ができました、と。

次は、cockroach node drainの方を試してみることにします。

node5.cockroachで起動。

$ cockroach start \
   --certs-dir=$CERTS_DIR \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node5.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach

クラスターの状態。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
   5
(4 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning |   membership   | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+----------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:14.070428 | 2021-12-19 11:32:53.107335 |          |         true |    true |               24 |                    24 |     57 |                  0 |           0            |                57 |       false        |     active     |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:15.943274 | 2021-12-19 11:32:55.006681 |          |         true |    true |               15 |                    15 |     56 |                  0 |           0            |                56 |       false        |     active     |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:16.096537 | 2021-12-19 11:32:55.183922 |          |         true |    true |               18 |                    18 |     56 |                  0 |           0            |                56 |       false        |     active     |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 11:18:03.424437 | 2021-12-19 11:25:09.355884 |          |        false |   false |             NULL |                  NULL |   NULL |               NULL |          NULL          |                 0 |        true        | decommissioned |    false
   5 | node5.cockroach:26257 | node5.cockroach:26257 | v21.2.3 | 2021-12-19 11:31:40.591356 | 2021-12-19 11:32:57.133676 |          |         true |    true |               16 |                    16 |     49 |                  0 |           0            |                50 |       false        |     active     |    false
(5 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] |
 $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 5 | {1,2,5}
rides | 46 | 1 | {1,3,5}
rides | 71 | 1 | {1,2,3}
rides | 70 | 5 | {2,3,5}
rides | 68 | 1 | {1,3,5}
rides | 69 | 2 | {1,2,5}
rides | 67 | 3 | {1,3,5}
rides | 60 | 3 | {1,2,3}
rides | 59 | 3 | {1,2,3}
rides | 81 | 5 | {1,3,5}
user_promo_codes | 49 | 5 | {2,3,5}
users | 44 | 3 | {1,3,5}
users | 53 | 3 | {2,3,5}
users | 52 | 1 | {1,2,3}
users | 51 | 5 | {1,3,5}
users | 66 | 5 | {1,3,5}
users | 50 | 1 | {1,2,5}
users | 65 | 5 | {2,3,5}
users | 64 | 2 | {1,2,5}
users | 74 | 2 | {2,3,5}
vehicle_location_histories | 47 | 2 | {1,2,5}
vehicles | 45 | 1 | {1,2,3}
vehicles | 80 | 1 | {1,2,3}
vehicles | 79 | 2 | {2,3,5}
vehicles | 55 | 5 | {1,2,5}
vehicles | 78 | 2 | {1,2,5}
vehicles | 54 | 1 | {1,2,3}
vehicles | 77 | 3 | {2,3,5}
vehicles | 75 | 2 | {1,2,3}
vehicles | 76 | 5 | {1,2,5}

では、node5.cockroachをドレインしてみます。node1.cockroachから、node5.cockroachをドレイン。

$ cockroach node drain --certs-dir=$CERTS_DIR --host node5.cockroach
node is draining... remaining: 27
node is draining... remaining: 0 (complete)
ok

コマンド自体は、すぐに完了します。

クラスターやデータの状態を見てみます。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
   5
(4 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning |   membership   | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+----------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:14.070428 | 2021-12-19 11:37:00.616747 |          |         true |    true |               30 |                    30 |     57 |                  0 |           0            |                57 |       false        |     active     |    false
   2 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:15.943274 | 2021-12-19 11:36:58.028884 |          |         true |    true |               20 |                    20 |     56 |                  0 |           0            |                56 |       false        |     active     |    false
   3 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 11:16:16.096537 | 2021-12-19 11:36:58.179227 |          |         true |    true |               23 |                    23 |     56 |                  0 |           0            |                56 |       false        |     active     |    false
   4 | node4.cockroach:26257 | node4.cockroach:26257 | v21.2.3 | 2021-12-19 11:18:03.424437 | 2021-12-19 11:25:09.355884 |          |        false |   false |             NULL |                  NULL |   NULL |               NULL |          NULL          |                 0 |        true        | decommissioned |    false
   5 | node5.cockroach:26257 | node5.cockroach:26257 | v21.2.3 | 2021-12-19 11:31:40.591356 | 2021-12-19 11:37:00.138004 |          |         true |    true |                0 |                     0 |     50 |                  0 |           0            |                50 |       false        |     active     |    true
(5 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 1 | {1,2,5}
rides | 46 | 1 | {1,3,5}
rides | 71 | 1 | {1,2,3}
rides | 70 | 2 | {2,3,5}
rides | 68 | 1 | {1,3,5}
rides | 69 | 2 | {1,2,5}
rides | 67 | 3 | {1,3,5}
rides | 60 | 3 | {1,2,3}
rides | 59 | 3 | {1,2,3}
rides | 81 | 3 | {1,3,5}
user_promo_codes | 49 | 2 | {2,3,5}
users | 44 | 3 | {1,3,5}
users | 53 | 3 | {2,3,5}
users | 52 | 1 | {1,2,3}
users | 51 | 1 | {1,3,5}
users | 66 | 3 | {1,3,5}
users | 50 | 1 | {1,2,5}
users | 65 | 3 | {2,3,5}
users | 64 | 2 | {1,2,5}
users | 74 | 2 | {2,3,5}
vehicle_location_histories | 47 | 2 | {1,2,5}
vehicles | 45 | 1 | {1,2,3}
vehicles | 80 | 1 | {1,2,3}
vehicles | 79 | 2 | {2,3,5}
vehicles | 55 | 2 | {1,2,5}
vehicles | 78 | 2 | {1,2,5}
vehicles | 54 | 1 | {1,2,3}
vehicles | 77 | 3 | {2,3,5}
vehicles | 75 | 2 | {1,2,3}
vehicles | 76 | 2 | {1,2,5}

特に、データがリバランスされたりすることはありませんね。is_drainingはtrueになっていますが。

ここでもう1度drainの説明を見てみますが、あまり詳しく書かれていないようです。

  drain        drain a node without shutting it down

ただ、この時点でnode5.cockroachにはアクセスできなくなるようです。

$ cockroach node ls --certs-dir=$CERTS_DIR --host node5.cockroach
ERROR: cannot establish secure connection to insecure server.
Maybe use --insecure?

pq: SSL is not enabled on the server
Failed running "node ls"

この後は、cockroach node decommissionでノード廃止、ですね。

$ cockroach node decommission --certs-dir=$CERTS_DIR 5

実際のリバランスは、こちらを契機に行われるようです。

なのですが、今回は途中で止まりました…。なんなんでしょう…。

こちらを見ていると、cockroach node drainはより安全にノードを切り離したい場合に使われるようですね。

If you need maximum cluster availability, you can run cockroach node drain prior to node shutdown and actively monitor the draining process instead of automating it.

Decommission Nodes / Step 4. Stop the decommissioning node

レプリケーション係数を下回るように、ノードを廃止してみる

こちらに書かれているように、レプリケーション係数を下回る状態になるように、ノードを廃止してみましょう。

Decommission Nodes / Considerations

また3ノードの状態にしておきます。

~$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
(3 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 12:07:53.270469 | 2021-12-19 12:13:17.318499 |          |         true |    true |               26 |                    26 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   2 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 12:07:54.800607 | 2021-12-19 12:13:18.87348  |          |         true |    true |               20 |                    20 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   3 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 12:07:54.994782 | 2021-12-19 12:13:19.084322 |          |         true |    true |               27 |                    27 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
(3 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'

table_name | range_id | lease_holder | replicas
promo_codes | 48 | 3 | {1,2,3}
rides | 46 | 3 | {1,2,3}
rides | 62 | 1 | {1,2,3}
rides | 60 | 3 | {1,2,3}
rides | 59 | 1 | {1,2,3}
rides | 87 | 3 | {1,2,3}
rides | 58 | 1 | {1,2,3}
rides | 88 | 1 | {1,2,3}
rides | 86 | 3 | {1,2,3}
rides | 61 | 2 | {1,2,3}
user_promo_codes | 49 | 3 | {1,2,3}
users | 44 | 2 | {1,2,3}
users | 67 | 2 | {1,2,3}
users | 66 | 3 | {1,2,3}
users | 64 | 3 | {1,2,3}
users | 53 | 1 | {1,2,3}
users | 50 | 3 | {1,2,3}
users | 52 | 2 | {1,2,3}
users | 51 | 2 | {1,2,3}
users | 65 | 1 | {1,2,3}
vehicle_location_histories | 47 | 3 | {1,2,3}
vehicles | 45 | 3 | {1,2,3}
vehicles | 57 | 3 | {1,2,3}
vehicles | 56 | 2 | {1,2,3}
vehicles | 55 | 2 | {1,2,3}
vehicles | 68 | 2 | {1,2,3}
vehicles | 54 | 1 | {1,2,3}
vehicles | 85 | 1 | {1,2,3}
vehicles | 84 | 2 | {1,2,3}
vehicles | 69 | 1 | {1,2,3}

ここでnode3.cockroachを廃止しようとしてみます。

$ cockroach node decommission --certs-dir=$CERTS_DIR 3

すると、確かに進まなくなります。

$ cockroach node decommission --certs-dir=$CERTS_DIR 3

  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   3 |  true   |       73 |        true        | decommissioning |    false
(1 row)
.............

書かれているとおりですね。

If no other nodes are available, the decommissioning process will hang indefinitely.

Decommission Nodes / Considerations

これが進むようにするには、新しくノードを追加する必要があります。今回はnode4.cockroachを追加しましょう。

$ cockroach start \
   --certs-dir=$CERTS_DIR \
   --store=/var/lib/cockroach/data \
   --advertise-addr=node4.cockroach \
   --join=node1.cockroach \
   --join=node2.cockroach \
   --join=node3.cockroach

ノードを追加すると、ずっと停止していたノード廃止プロセスが動き出します。

                                                                                                                                                             
  id | is_live | replicas | is_decommissioning |   membership    | is_draining                                                                               
-----+---------+----------+--------------------+-----------------+--------------                                                                             
   3 |  true   |       73 |        true        | decommissioning |    false                                                                                  
(1 row)                                                                                                                                                      
...........................                                                                                                                                  
  id | is_live | replicas | is_decommissioning |   membership    | is_draining                                                                               
-----+---------+----------+--------------------+-----------------+--------------                                                                             
   3 |  true   |       69 |        true        | decommissioning |    false
(1 row)
......
  id | is_live | replicas | is_decommissioning |   membership    | is_draining 
-----+---------+----------+--------------------+-----------------+--------------
   3 |  true   |       67 |        true        | decommissioning |    false
(1 row)
......

そして完了。

.
  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   3 |  true   |        1 |        true        | decommissioning |    false
(1 row)

  id | is_live | replicas | is_decommissioning |   membership    | is_draining
-----+---------+----------+--------------------+-----------------+--------------
   3 |  true   |        0 |        true        | decommissioning |    false
(1 row)

No more data reported on target nodes. Please verify cluster health before removing the nodes.

新しく追加したノードでは、リバランスが進んでいきます。

オマケ: レプリケーション係数を下回るように、ノードを強制停止してみる

最後に、レプリケーション係数を下回る場合のノードの廃止はうまくいきませんでしたが、プロセスを強制的に
停止した場合の動きを見てみましょう。

まずは、また3ノードでクラスターを構築、データをロード。

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
(3 rows)


$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission
  id |        address        |      sql_address      |  build  |         started_at         |         updated_at         | locality | is_available | is_live | replicas_leaders | replicas_leaseholders | ranges | ranges_unavailable | ranges_underreplicated | gossiped_replicas | is_decommissioning | membership | is_draining
-----+-----------------------+-----------------------+---------+----------------------------+----------------------------+----------+--------------+---------+------------------+-----------------------+--------+--------------------+------------------------+-------------------+--------------------+------------+--------------
   1 | node1.cockroach:26257 | node1.cockroach:26257 | v21.2.3 | 2021-12-19 12:32:20.252109 | 2021-12-19 12:33:23.386698 |          |         true |    true |               30 |                    30 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   2 | node3.cockroach:26257 | node3.cockroach:26257 | v21.2.3 | 2021-12-19 12:32:20.657242 | 2021-12-19 12:33:23.784939 |          |         true |    true |               23 |                    23 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
   3 | node2.cockroach:26257 | node2.cockroach:26257 | v21.2.3 | 2021-12-19 12:32:20.705223 | 2021-12-19 12:33:23.826301 |          |         true |    true |               20 |                    20 |     73 |                  0 |           0            |                73 |       false        |   active   |    false
(3 rows)


$ cockroach sql --certs-dir=$CERTS_DIR --user myuser --database movr --format tsv -e 'show ranges from database movr' | perl -anl -F'\t' -e 'print "$F[0] | $F[3] | $F[5] | $F[7]"'
table_name | range_id | lease_holder | replicas
promo_codes | 48 | 3 | {1,2,3}
rides | 46 | 2 | {1,2,3}
rides | 86 | 1 | {1,2,3}
rides | 85 | 2 | {1,2,3}
rides | 83 | 2 | {1,2,3}
rides | 84 | 2 | {1,2,3}
rides | 81 | 2 | {1,2,3}
rides | 88 | 1 | {1,2,3}
rides | 82 | 2 | {1,2,3}
rides | 87 | 1 | {1,2,3}
user_promo_codes | 49 | 2 | {1,2,3}
users | 44 | 1 | {1,2,3}
users | 55 | 1 | {1,2,3}
users | 54 | 2 | {1,2,3}
users | 52 | 1 | {1,2,3}
users | 53 | 1 | {1,2,3}
users | 50 | 3 | {1,2,3}
users | 66 | 3 | {1,2,3}
users | 64 | 3 | {1,2,3}
users | 65 | 1 | {1,2,3}
vehicle_location_histories | 47 | 1 | {1,2,3}
vehicles | 45 | 2 | {1,2,3}
vehicles | 79 | 3 | {1,2,3}
vehicles | 78 | 3 | {1,2,3}
vehicles | 76 | 2 | {1,2,3}
vehicles | 77 | 3 | {1,2,3}
vehicles | 74 | 2 | {1,2,3}
vehicles | 80 | 3 | {1,2,3}
vehicles | 75 | 3 | {1,2,3}
vehicles | 67 | 3 | {1,2,3}

node2.cockroachとnode3.cockroachを停止してみます。

## node2.cockroach
$ kill `pgrep cockroach`


## node3.cockroach
$ kill `pgrep cockroach`

この状態になると、cockroach node lsのレスポンスは返ってきますが

$ cockroach node ls --certs-dir=$CERTS_DIR
  id
------
   1
   2
   3
(3 rows)

cockroach node statusなどは、応答が返ってこなくなります。

$ cockroach node status --certs-dir=$CERTS_DIR --ranges --decommission

これは、レプリケーション係数を下回った場合はハングアップするということでしょうかね…。

To be able to tolerate the failure of any 1 node, use at least 3 nodes with the default 3-way replication factor. In this case, if 1 node fails, each range retains 2 of its 3 replicas, a majority.

Deploy CockroachDB On-Premises / Requirements

まとめ

CockroachDBで、ノードの増減や廃止あたりを触ってみました。

ノードが停止しただけだとクラスターからノードがいなくなったことにはならなかったりと、ちゃんと動きを把握して
いないといけなさそうなところがいくつかあり。

実際使おうと思ったら、このあたりしっかり見ておかないとですね。