データのバックアップと復元を手動で行う際の手順を学ぶこと。
このチュートリアルでは、1つ前のチュートリアルで準備した2つの既存のDroongaノード:node0
(192.168.100.50
) 、 node1
(192.168.100.51
) と、作業環境として使うもう1台のコンピュータ node2
(192.168.100.52
) があると仮定します。
あなたの手元にあるDroongaノードがこれとは異なる名前である場合には、以下の説明の中のnode0
、node1
、node2
は実際の物に読み替えて下さい。
drndump
のインストール最初に、作業マシンのnode2
にRubygems経由で drndump
と名付けられたコマンドラインツールをインストールします:
# gem install drndump
その後、drndump
コマンドが正しくインストールできたかどうかを確認します:
$ drndump --version
drndump 1.0.1
drndump
コマンドはすべてのスキ−マ定義とデータをJSONs形式で取り出します。既存のDroongaクラスタのすべての内容をダンプ出力してみましょう。
例えば、クラスタが node0
(192.168.100.50
) と node1
(192.168.100.51
) の2つのノードから構成されていて、別のホスト node2
(192.168.100.52
) にログインしている場合、コマンドラインは以下の要領です。
# drndump --host=node0 \
--receiver-host=node2
{
"type": "table_create",
"dataset": "Default",
"body": {
"name": "Location",
"flags": "TABLE_PAT_KEY",
"key_type": "WGS84GeoPoint"
}
}
...
{
"dataset": "Default",
"body": {
"table": "Store",
"key": "store9",
"values": {
"location": "146702531x-266363233",
"name": "Macy's 6th Floor - Herald Square - New York NY (W)"
}
},
"type": "add"
}
{
"type": "column_create",
"dataset": "Default",
"body": {
"table": "Location",
"name": "store",
"type": "Store",
"flags": "COLUMN_INDEX",
"source": "location"
}
}
{
"type": "column_create",
"dataset": "Default",
"body": {
"table": "Term",
"name": "store_name",
"type": "Store",
"flags": "COLUMN_INDEX|WITH_POSITION",
"source": "name"
}
}
以下の点に注意して下さい:
--host
オプションには、クラスタ内のいずれかのノードの正しいホスト名またはIPアドレスを指定します。--receiver-host
オプションには、今操作しているコンピュータ自身の正しいホスト名またはIPアドレスを指定します。
この情報は、Droongaクラスタがメッセージを送り返すために使われます。実行結果は標準出力に出力されます。 結果をJSONs形式のファイルに保存する場合は、リダイレクトを使って以下のようにして下さい:
$ drndump --host=node0 \
--receiver-host=node2 \
> dump.jsons
droonga-client
のインストールdrndump
コマンドの実行結果は、Droonga用のメッセージの一覧です。
Droongaクラスタにそれらのメッセージを送信するには、droonga-send
コマンドを使います。
このコマンドを含んでいるGemパッケージ droonga-client
を、作業マシンであるnode2
にインストールして下さい:
# gem install droonga-client
droonga-send
コマンドが正しくインストールされた事を確認しましょう:
$ droonga-send --version
droonga-send 0.2.1
2つのノード node0
(192.168.100.50
) と node1
(192.168.100.51
) からなる空のクラスタがあり、今 node2
(192.168.100.52
) にログインして操作を行っていて、ダンプファイルが dump.jsons
という名前で手元にあると仮定します。
もし順番にこのチュートリアルを読み進めているのであれば、クラスタとダンプファイルが既に手元にあるはずです。以下の操作でクラスタを空にしましょう:
$ endpoint="http://node0:10041"
$ curl "$endpoint/d/table_remove?name=Location" | jq "."
[
[
0,
1406610703.2229023,
0.0010793209075927734
],
true
]
$ curl "$endpoint/d/table_remove?name=Store" | jq "."
[
[
0,
1406610708.2757723,
0.006396293640136719
],
true
]
$ curl "$endpoint/d/table_remove?name=Term" | jq "."
[
[
0,
1406610712.379644,
6.723403930664062e-05
],
true
]
これでクラスタは空になりました。
確かめてみましょう。
以下のように、select
とtable_list
コマンドは空の結果を返します:
$ curl "$endpoint/d/table_list" | jq "."
[
[
0,
1406610804.1535122,
0.0002875328063964844
],
[
[
[
"id",
"UInt32"
],
[
"name",
"ShortText"
],
[
"path",
"ShortText"
],
[
"flags",
"ShortText"
],
[
"domain",
"ShortText"
],
[
"range",
"ShortText"
],
[
"default_tokenizer",
"ShortText"
],
[
"normalizer",
"ShortText"
]
]
]
]
$ curl -X DELETE "$endpoint/cache" | jq "."
true
$ curl "$endpoint/d/select?table=Store&output_columns=name&limit=10" | jq "."
[
[
0,
1401363465.610241,
0
],
[
[
[
null
],
[]
]
]
]
select
コマンドにクエストを送る前に、まずキャッシュを削除しておくことに注意して下さい。
これを忘れると、古い情報に基づいて、キャッシュされた結果が意図せず返されてしまいます。
既定の設定では、レスポンスキャッシュは直近の100リクエストに対して保存され、保持期間は1分間です。
上記のように、/cache
のパスの位置にHTTPのDELETE
のリクエストを送信すると、手動でレスポンスキャッシュを削除できます。
drndump
コマンドの実行結果はダンプ出力元と同じ内容のデータセットを作るために必要な情報をすべて含んでいます。そのため、クラスタが壊れた場合でも、ダンプファイルからクラスタを再構築する事ができます。
やり方は単純で、単にダンプファイルをdroonga-send
コマンドを使って空のクラスタに流し込むだけです。
ダンプファイルからクラスタの内容を復元するには、以下のようなコマンドを実行します:
$ droonga-send --server=node0 \
dump.jsons
注意:
--server
オプションには、クラスタ内のいずれかのノードの正しいホスト名またはIPアドレスを指定します。これで、データが完全に復元されました。確かめてみましょう:
$ curl -X DELETE "$endpoint/cache" | jq "."
true
$ curl "$endpoint/d/select?table=Store&output_columns=name&limit=10" | jq "."
[
[
0,
1401363556.0294158,
7.62939453125e-05
],
[
[
[
40
],
[
[
"name",
"ShortText"
]
],
[
"1st Avenue & 75th St. - New York NY (W)"
],
[
"76th & Second - New York NY (W)"
],
[
"Herald Square- Macy's - New York NY"
],
[
"Macy's 5th Floor - Herald Square - New York NY (W)"
],
[
"80th & York - New York NY (W)"
],
[
"Columbus @ 67th - New York NY (W)"
],
[
"45th & Broadway - New York NY (W)"
],
[
"Marriott Marquis - Lobby - New York NY"
],
[
"Second @ 81st - New York NY (W)"
],
[
"52nd & Seventh - New York NY (W)"
]
]
]
]
複数のDroongaクラスタが存在する場合、片方のクラスタの内容をもう片方のクラスタに複製することができます。
droonga-engine
パッケージはdroonga-engine-absorb-data
というユーティリティコマンドを含んでおり、これを使うと、既存のクラスタから別のクラスタへ直接データをコピーする事ができます。ローカルにダンプファイルを保存する必要がない場合には、この方法がおすすめです。
ノード node0
(192.168.100.50
) を含む複製元クラスタと、ノード node1' (
192.168.100.51`) を含む複製先クラスタの2つのクラスタがあると仮定します。
もし順番にこのチュートリアルを読み進めているのであれば、2つのノードを含むクラスタが手元にあるはずです。droonga-engine-catalog-modify
を使って2つのクラスタを作り、1つを空にしましょう。手順は以下の通りです:
(on node0)
# droonga-engine-catalog-modify --replica-hosts=node0
(on node1)
# droonga-engine-catalog-modify --replica-hosts=node1
これらのコマンドによって、2ノードからなる1つのクラスタが、それぞれ1ノードからなる2つのクラスタへ分割されます。
カタログ定義ファイルの変更はdroonga-engine
サービスによって自動的に検出され、プロセスが自動的に再起動されます。
この処理には時間がかかるため、完了まで1分程度待つ必要があります。
もしそのノード上で動作中のdroonga-engine-service
のプロセスが2つ以上あるのであれば、そのノードはまだ再起動処理の途中です。
(新しいサービスのプロセスが動作し始めたら、古いプロセスが自動的に終了します。)
(on node0, node1)
$ ps aux | grep droonga-engine-service | grep -v grep | wc -l
2
しばらく待つと、各ノード上でサービスのプロセスが1つだけ動作している状態になります:
(on node0, node1)
$ ps aux | grep droonga-engine-service | grep -v grep | wc -l
1
これで、2つの別々のクラスタができました:
$ curl "http://node0:10041/droonga/system/status" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"status": "active"
}
},
"reporter": "..."
}
$ curl "http://node1:10041/droonga/system/status" | jq "."
{
"nodes": {
"node1:10031/droonga": {
"status": "active"
}
},
"reporter": "..."
}
では、片方のクラスタを空にしましょう:
(on node1)
$ endpoint="http://node1:10041"
$ curl "$endpoint/d/table_remove?name=Location"
$ curl "$endpoint/d/table_remove?name=Store"
$ curl "$endpoint/d/table_remove?name=Term"
$ curl -X DELETE "http://node1:10041/cache" | jq "."
true
$ curl "http://node1:10041/d/select?table=Store&output_columns=name&limit=10" | jq "."
[
[
0,
1401363465.610241,
0
],
[
[
[
null
],
[]
]
]
]
$ curl -X DELETE "http://node0:10041/cache" | jq "."
true
$ curl "http://node0:10041/d/select?table=Store&output_columns=name&limit=10" | jq "."
[
[
0,
1401363556.0294158,
7.62939453125e-05
],
[
[
[
40
],
[
[
"name",
"ShortText"
]
],
[
"1st Avenue & 75th St. - New York NY (W)"
],
[
"76th & Second - New York NY (W)"
],
[
"Herald Square- Macy's - New York NY"
],
[
"Macy's 5th Floor - Herald Square - New York NY (W)"
],
[
"80th & York - New York NY (W)"
],
[
"Columbus @ 67th - New York NY (W)"
],
[
"45th & Broadway - New York NY (W)"
],
[
"Marriott Marquis - Lobby - New York NY"
],
[
"Second @ 81st - New York NY (W)"
],
[
"52nd & Seventh - New York NY (W)"
]
]
]
]
droonga-http-server
は同じコンピュータ上のdroonga-engine
に関連付けられていることに注意してください。
上記の手順でクラスタを2つに分割した後は、node0
のdroonga-http-server
はnode0
のdroonga-engine
とだけ通信し、node1
のdroonga-http-server
はnode1
のdroonga-engine
とだけ通信します。
詳しくは次のチュートリアルも参照して下さい。
2つのクラスタの間でデータをコピーするには、いずれかのノード上で以下のようにdroonga-engine-absorb-data
コマンドを実行します:
(on node1)
$ droonga-engine-absorb-data --host=node1 \
--source-host=node0 \
--receiver-host=node1
Start to absorb data from Default at node0:10031/droonga
to Default at node1:10031/droonga
via node1 (this host)
Absorbing...
Getting the timestamp of the last processed message in the source node...
The timestamp of the last processed message in the source node: 2015-04-29T10:07:08.230158Z
Setting the destination node to ignore messages older than the timestamp...
100% done (maybe 00:00:00 remaining)
Done.
このコマンドは、以下のようにして別のノード上で実行することもできます:
(on node2)
$ droonga-engine-absorb-data --host=node1 \
--source-host=node0 \
--receiver-host=node2
Start to absorb data from Default at node0:10031/droonga
to Default at node1:10031/droonga
via node2 (this host)
...
この時、コマンドを実行するノードのホスト名かIPアドレスを--receiver-host
オプションで指定する必要があることに注意してください。
以上の操作で、2つのクラスタの内容が完全に同期されました。確かめてみましょう:
$ curl -X DELETE "http://node1:10041/cache" | jq "."
true
$ curl "http://node1:10041/d/select?table=Store&output_columns=name&limit=10" | jq "."
[
[
0,
1401363556.0294158,
7.62939453125e-05
],
[
[
[
40
],
[
[
"name",
"ShortText"
]
],
[
"1st Avenue & 75th St. - New York NY (W)"
],
[
"76th & Second - New York NY (W)"
],
[
"Herald Square- Macy's - New York NY"
],
[
"Macy's 5th Floor - Herald Square - New York NY (W)"
],
[
"80th & York - New York NY (W)"
],
[
"Columbus @ 67th - New York NY (W)"
],
[
"45th & Broadway - New York NY (W)"
],
[
"Marriott Marquis - Lobby - New York NY"
],
[
"Second @ 81st - New York NY (W)"
],
[
"52nd & Seventh - New York NY (W)"
]
]
]
]
これらの2つのクラスタを結合するために、以下のコマンド列を実行しましょう:
(on node0)
# droonga-engine-catalog-modify --add-replica-hosts=node1
(on node1)
# droonga-engine-catalog-modify --add-replica-hosts=node0
これで、1つだけクラスタがある状態になりました。最初の状態に戻ったという事になります。 (もちろん、サービスが完全に再起動されるまでしばらく待つ必要があります。)
$ curl "http://node0:10041/droonga/system/status" | jq "."
{
"nodes": {
"node0:10031/droonga": {
"status": "active"
},
"node1:10031/droonga": {
"status": "active"
}
},
"reporter": "..."
}
このチュートリアルでは、Droongaクラスタのバックアップとデータの復元の方法を実践しました。 また、既存のDroongaクラスタの内容を別の空のクラスタへ複製する方法も実践しました。
続いて、既存のDroongaクラスタに新しいreplicaを追加する手順を学びましょう。