既存のDroongaクラスタについて、新しいreplicaを追加し、既存のreplicaを削除し、および、既存のreplicaを新しいreplicaで置き換えるための手順を学ぶこと。
このチュートリアルでは、最初のチュートリアルで準備した2つの既存のDroongaノード:node0
(192.168.100.50
) 、 node1
(192.168.100.51
) と、新しいノードとして使うもう1台のコンピュータ node2
(192.168.100.52
) があると仮定します。
あなたの手元にあるDroongaノードがこれとは異なる名前である場合には、以下の説明の中のnode0
、node1
、node2
は実際の物に読み替えて下さい。
Droongaのノードの集合には、「replica」と「slice」という2つの軸があります。
「replica」のノード群は、完全に同一のデータを持っており、検索などのリクエストを各ノードが並行して処理する事ができます。 新しいreplicaを追加する事によって、増加するリクエストに対して処理能力を増強することができます。
他方、「slice」のノード群はそれぞれ異なるデータを持ちます(例えば、あるノードは2013年のデータ、別のノードは2014年のデータ、という具合です)。 新しいsliceを追加する事によって、増大するデータ量に対してクラスタとしての容量を拡大することができます。
現在の所、Groonga互換のシステムとして設定されたDroongaクラスタについては、replicaを追加することはできますが、sliceを追加することはできません。 この点については将来のバージョンで改善する予定です。
ともかく、このチュートリアルでは既存のDroongaクラスタに新しいreplicaを追加する手順を解説します。 早速始めましょう。
このケースでは、検索のように読み取りのみを行うリクエストに対しては、クラスタの動作を止める必要はありません。 サービスを停止することなく、その裏側でシームレスに新しいreplicaを追加することができます。
その一方で、クラスタへの新しいデータの流入は、新しいノードが動作を始めるまでの間停止しておく必要があります。 (将来的には、新しいノードを完全に無停止で追加できるようにする予定ですが、今のところはそれはできません。)
ここでは、node0
と node1
の2つのreplicaノードからなるDroongaクラスタがあり、新しいreplicaノードとして node2
を追加すると仮定します。
まず、新しいコンピュータをセットアップし、必要なソフトウェアのインストールと設定を済ませます。
(on node2)
# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \
HOST=node2 bash
# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \
ENGINE_HOST=node2 HOST=node2 bash
注意点として、空でないノードを既存のクラスタに追加することはできません。 もしそのコンピュータがかつてDroongaノードとして使われていた事があった場合には、最初に古いデータを消去する必要があります。
(on node2)
# droonga-engine-configure --quiet \
--clear --reset-config --reset-catalog \
--host=node2
# droonga-http-server-configure --quiet --reset-config \
--droonga-engine-host-name=node2 \
--receive-host-name=node2
では、サービスを起動しましょう。
(on node2)
# service start droonga-engine
# service start droonga-http-server
この時点で、この新しいノードは既存のクラスタのノードとしては動作していません。
この事は、system.status
コマンドを通じて確認できます:
$ curl "http://node0:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node1:10031/droonga": {
"live": true
}
}
}
$ curl "http://node1:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node1:10031/droonga": {
"live": true
}
}
}
$ curl "http://node2:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node2:10031/droonga": {
"live": true
}
}
}
新しいreplicaとの間でデータを完全に同期する必要があるので、クラスタの構成を変更する前に、クラスタへのデータの書き込みを行うリクエストの流入を一時停止する必要があります。 そうしないと、新しく追加したreplicaが中途半端なデータしか持たない矛盾した状態となってしまい、リクエストに対してクラスタが返す処理結果が不安定になります。
データの書き込みを伴うリクエストとは、具体的には、クラスタ内のデータを変更する以下のコマンドです:
add
column_create
column_remove
delete
load
table_create
table_remove
cronjobとして実行されるバッチスクリプトによって load
コマンド経由で新しいデータを投入している場合は、cronjobを停止して下さい。
クローラが add
コマンド経由で新しいデータを投入している場合は、クローラを停止して下さい。
あるいは、クローラやローダーとクラスタの間にFluentdを置いてバッファとして利用しているのであれば、バッファからのメッセージ出力を停止して下さい。
前項から順番にチュートリアルを読んでいる場合、クラスタに流入しているリクエストはありませんので、ここでは特に何もする必要はありません。
新しいreplicaノードを既存のクラスタに追加するには、いずれかの既存のノードもしくは新しいreplicaノードのいずれかにおいて、catalog.json
が置かれているディレクトリで、droonga-engine-join
コマンドを実行します:
(on node2)
$ droonga-engine-join --host=node2 \
--replica-source-host=node0
Joining new replica to the cluster...
...
Update existing hosts in the cluster...
...
Done.
--host
オプションで、その新しいreplicaノードのホスト名を指定して下さい。--replica-source-host
オプションで、クラスタ中の既存のノードの1つのホスト名を指定して下さい。コマンドを実行すると、自動的に、クラスタのデータが新しいreplicaノードへと同期され始めます。
データの同期が完了すると、ノードが自動的に再起動してクラスタに参加します。
すべてのノードのcatalog.json
も同時に更新され、この時点をもって、新しいノードは晴れてそのクラスタのreplicaノードとして動作し始めます。
これで、ノードがクラスタに参加しました。この事は system.status
コマンドで確かめられます:
$ curl "http://node0:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node1:10031/droonga": {
"live": true
},
"node2:10031/droonga": {
"live": true
}
}
}
古いレスポンスキャッシュを無視するために、各リクエストに追加の一意なパラメータを加えていることに注意して下さい。
さて、準備ができました。 すべてのreplicaは完全に同期した状態となっているので、このクラスタはリクエストを安定して処理できます。 cronjobを有効化する、クローラの動作を再開する、バッファからのメッセージ送出を再開する、などの操作を行って、クラスタ内のデータを変更するリクエストの流入を再開して下さい。
以上で、Droongaクラスタに新しいreplicaノードを無事参加させる事ができました。
Droongaノードは、メモリ不足、ディスク容量不足、ハードウェア障害など、様々な致命的な理由によって動作しなくなり得ます。 Droongaクラスタ内のノードは互いに監視しあっており、動作しなくなったノードに対してはメッセージの配送を自動的に停止して、動作しないノードがあってもクラスタ全体としては動作し続けるようになっています。 このような時には、動作していないノードを取り除く必要があります。
もちろん、他の目的に転用したいといった理由から、正常動作中のノードを取り除きたいと考える場合もあるでしょう。
ここでは、node0
、 node1
、node2
の3つのreplicaノードからなるDroongaクラスタがあり、最後のノード node2
をクラスタから離脱させようとしていると仮定します。
新しいreplicaノードを既存のクラスタから削除するには、クラスタ内のいずれかのノードの上で、catalog.json
が置かれたディレクトリにおいて droonga-engine-unjoin
コマンドを実行します:
(on node0)
$ droonga-engine-unjoin --host=node2
Unjoining replica from the cluster...
...
Done.
--host
オプションで、クラスタから削除するノードのホスト名またはIPアドレスを指定して下さい。catalog.json
が置かれたディレクトリで実行するか、もしくはそのディレクトリのパスを --base-dir
オプションで指定して下さい。すると、ノードがクラスタから自動的に離脱し、すべてのノードの catalog.json
も同時に更新されます。
これで、ノードはクラスタから無事離脱しました。
これで、ノード node2
がクラスタから離脱しました。この事は system.status
コマンドで確かめられます:
$ curl "http://node0:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node1:10031/droonga": {
"live": true
}
}
}
$ curl "http://node1:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node1:10031/droonga": {
"live": true
}
}
}
$ curl "http://node2:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node1:10031/droonga": {
"live": true
}
}
}
古いレスポンスキャッシュを無視するために、各リクエストに追加の一意なパラメータを加えていることに注意して下さい。
node2
までもが、node2
がクラスタの一員ではないと報告していることに注目して下さい。
これは、クラスタから離脱したノードと新しいノードとの違いです。
ノードの置き換えは、上記の手順の組み合わせで行います。
ここでは、node0
と node1
の2つのreplicaノードからなるDroongaクラスタがあり、node1
が不安定で、それを新しいreplicaノード node2
で置き換えようとしていると仮定します。
まず、不安定になっているノードを取り除きます。以下のようにしてクラスタからノードを離脱させて下さい:
(on node0)
$ droonga-engine-unjoin --host=node1
レスポンスキャッシュを空にします:
これで、ノードがクラスタから離脱しました。この事は system.status
コマンドで確かめられます:
$ curl "http://node0:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
}
}
}
古いレスポンスキャッシュを無視するために、各リクエストに追加の一意なパラメータを加えていることに注意して下さい。
次に、新しいreplica node2
を用意します。
必要なパッケージをインストールし、catalog.json
を生成して、サービスを起動します。
(on node2)
# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \
HOST=node2 bash
# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \
ENGINE_HOST=node2 HOST=node2 bash
そのコンピュータがかつてDroongaノードの一員だったことがある場合は、インストール作業の代わりに、古いデータを消去する必要があります:
(on node2)
# droonga-engine-configure --quiet \
--clear --reset-config --reset-catalog \
--host=node2
# droonga-http-server-configure --quiet --reset-config \
--droonga-engine-host-name=node2 \
--receive-host-name=node2
そうしたら、そのノードをクラスタに参加させましょう。
(on node2)
$ droonga-engine-join --host=node2 \
--replica-source-host=node0
最終的に、node0
と node2
の2つのノードからなるDroongaクラスタができあがりました。
この事は、system.status
コマンドの結果を見ると確認できます:
$ curl "http://node0:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node2:10031/droonga": {
"live": true
}
}
}
$ curl "http://node2:10041/droonga/system/status?_=$(date +%s)" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"live": true
},
"node2:10031/droonga": {
"live": true
}
}
}
古いレスポンスキャッシュを無視するために、各リクエストに追加の一意なパラメータを加えていることに注意して下さい。
このチュートリアルでは、既存のDroongaクラスタに新しいreplicaノードを追加する方法を学びました。 また、既存のreplicaを取り除く方法と、既存のreplicaを新しいreplicaで置き換える方法も学びました。