ノンストップでノードを追加する場面の検証手順
YUKI "Piro" Hiroshi edited this page Apr 7, 2015
·
45 revisions
- Droonga Clusterを2ノード以上の構成でセットアップしておく。 仮に、2ノード構成で各ノードの名前がnode0, node1とする。
- log-searchリポジトリの説明を参照して、Droongaノードの1台(仮に、node0とする)をスタンドアロンのログ検索サーバとしてセットアップしておく。
$ sudo service droonga-engine start
$ sudo service droonga-http-server start
$ sudo service td-agent restart
$ logger test1
$ logger test2
$ logger test3
$ curl "http://localhost:10041/d/select?table=Logs&limit=5&sortby=-timestamp&_=$(date +%s)"
これで、検索結果にtest1, test2, test3のログが出ていれば準備はOK。
node0上で以下のコマンドを実行しておき、1秒ごとにログが追記されるようにしておく。
$ while true; do logger "Periodically log at $(date)"; sleep 1; done
別のコンソールで以下のコマンドを実行しておき、ログの件数が増えていくことを監視できるようにしておく。
DBを直接参照してレコード数を監視
$ while true; do echo "$(date) / Groonga@$(uname -n) / $(sudo -u droonga-engine -H groonga ~droonga-engine/droonga/databases/000/db select --table Logs --limit 0 | jq ".[1][0][0][0]")"; sleep 1; done
Droonga HTTP Server経由でレコード数を監視
$ while true; do echo "$(date) / HTTP@$(uname -n) / $(curl -s "http://localhost:10041/d/select?table=Logs&limit=0&_=$(date +%s)" | jq ".[1][0][0][0]")"; sleep 0.1; done
system.statusの結果を監視
$ while true; do echo '{"dataset":"Default","type":"system.status"}' | droonga-request --host node0 --receiver-host $(uname -n) | tail -n +2 | jq ".body"; sleep 1; done
or
$ while true; do echo "$(date) / $(curl -s "http://localhost:10041/droonga/system/status?_=$(date +%s)" | jq .)"; sleep 0.5; done
Droonga HTTP Serverが認識しているdroonga-engineノードの一覧を監視
$ while true; do echo "$(date) / $(curl -s "http://localhost:10041/engines?_=$(date +%s)" | jq .)"; sleep 1; done
転送バッファの内容を監視
$ while true; do ls ~droonga-engine/droonga/state/buffer/intentional/*/; echo "-----"; sleep 1; done
vagrantのホストOS側で操作する。
reset-nodes.sh:
#!/bin/bash
NODE0_SUDO="vagrant ssh node0 -- sudo"
NODE1_SUDO="vagrant ssh node1 -- sudo"
NODE2_SUDO="vagrant ssh node2 -- sudo"
wait_all() {
wait $NODE0_PID
wait $NODE1_PID
wait $NODE2_PID
}
node0_async_sudo() {
$NODE0_SUDO "$*" &
NODE0_PID=$!
}
node1_async_sudo() {
$NODE1_SUDO "$*" &
NODE1_PID=$!
}
node2_async_sudo() {
$NODE2_SUDO "$*" &
NODE2_PID=$!
}
echo "stopping services..."
$NODE0_SUDO service droonga-http-server stop
node0_async_sudo service droonga-engine stop
node1_async_sudo service droonga-engine stop
node2_async_sudo service droonga-engine stop
wait_all
echo "regenerating cluster informations..."
node0_async_sudo droonga-engine-catalog-generate --hosts=node0,node1
node1_async_sudo droonga-engine-catalog-generate --hosts=node0,node1
node2_async_sudo droonga-engine-catalog-generate --hosts=node2
wait_all
echo "deleting old data..."
node0_async_sudo rm -rf ~droonga-engine/droonga/state ~droonga-engine/droonga/*.log
node1_async_sudo rm -rf ~droonga-engine/droonga/state ~droonga-engine/droonga/*.log
node2_async_sudo rm -rf ~droonga-engine/droonga/databases ~droonga-engine/droonga/state ~droonga-engine/droonga/*.log
wait_all
if [ "$1" = "update" ]
then
SCRIPT_URL="https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh"
node0_async_sudo curl -s -o /tmp/install.sh $SCRIPT_URL
node1_async_sudo curl -s -o /tmp/install.sh $SCRIPT_URL
node2_async_sudo curl -s -o /tmp/install.sh $SCRIPT_URL
wait_all
node0_async_sudo env VERSION=master bash /tmp/install.sh
node1_async_sudo env VERSION=master bash /tmp/install.sh
node2_async_sudo env VERSION=master bash /tmp/install.sh
wait_all
fi
./copy-db.sh node0 node1
echo "restarting services..."
node0_async_sudo service droonga-engine start
node1_async_sudo service droonga-engine start
node2_async_sudo service droonga-engine start
wait_all
$NODE0_SUDO service droonga-http-server start
echo "done."
コピー時は、ログの流入を止めてから行う。 vagrantのホストOS側で操作する。
copy-db.sh:
#!/bin/bash
SOURCE=$1
DESTINATION=$2
if [ "$SOURCE" = "" ]
then
echo "you must specify the source host"
exit 1
fi
if [ "$DESTINATION" = "" ]
then
echo "you must specify the destination host"
exit 1
fi
echo "copying database from $SOURCE to $DESTINATION"
SOURCE_SUDO="vagrant ssh $SOURCE -- sudo"
DESTINATION_SUDO="vagrant ssh $DESTINATION -- sudo"
$SOURCE_SUDO service td-agent stop
$SOURCE_SUDO service droonga-http-server stop
$SOURCE_SUDO service droonga-engine stop
$SOURCE_SUDO rm -f /vagrant/databases.tar
$SOURCE_SUDO tar -cvz -f /vagrant/databases.tar -C ~droonga-engine/droonga/ databases
$DESTINATION_SUDO rm -rf ~droonga-engine/droonga/databases
$DESTINATION_SUDO tar -xv -f /vagrant/databases.tar -C ~droonga-engine/droonga/
echo "done."
ログ流入の復活
$SOURCE_SUDO service droonga-engine start
$SOURCE_SUDO service droonga-http-server start
$SOURCE_SUDO service td-agent start
コマンドのshorthandを用意
serf="sudo -u droonga-engine -H /home/droonga-engine/droonga/serf"
まず新ノードをjoinさせる
logger "0: start join"
$serf query -rpc-addr node2:7373 change_role '{"node":"node2:10031/droonga","role":"absorb-destination"}'
logger "1: role of the joining node is changed"
$serf query -rpc-addr node2:7373 join '{"node":"node2:10031/droonga","type":"replica","source":"node1:10031/droonga","dataset":"Default"}'
logger "2: other nodes are registered to the joining node"
この時点で、droonga-http-server@node2は、接続先engineが存在しない(認識できていない)。 よって、全てが完了した後でdroonga-http-serverからserfクラスタへの再joinが必要となるが、現在はその仕組みがないので、手動でのdroonga-http-serverver再起動などの作業が必要である。何か対策を考えないといけない。
次に、他のノードから新ノードを見えるようにする。
$serf query -rpc-addr node1:7373 add_replicas '{"cluster_id":"8951f1b01583c1ffeb12ed5f4093210d28955988","dataset":"Default","hosts":["node2"]}'
logger "3: joining node is registered to other nodes"
これで、各ノードは同一クラスタで、且つ新ノードのみが機能していない状態になる。 新ノード宛の書き込みメッセージの配送が始まるが、メッセージはバッファに溜まるようになっている。
次に、コピー元ノードの更新を止めて、データをコピーする。
$serf query -rpc-addr node1:7373 change_role '{"node":"node1:10031/droonga","role":"absorb-source"}'
logger "4: source node is deactivated"
$serf query -rpc-addr node2:7373 absorb_data '{"node":"node2:10031/droonga","source":"node1:10031/droonga","port":10031,"tag":"droonga","dataset":"Default","messages_per_second":100}'
logger "5: data copying process is started"
$serf query -rpc-addr node2:7373 report_metadata '{"node":"node2:10031/droonga","key":"absorbing"}'
logger "6: completely copied"
$serf query -rpc-addr node1:7373 report_metadata '{"node":"node1:10031/droonga","key":"last_processed_message_timestamp"}'
logger "7: checking last_processed_message_timestamp"
$serf query -rpc-addr node2:7373 accept_messages_newer_than '{"node":"node2:10031/droonga","timestamp":"2015-03-24T04:36:09.423Z"}'
logger "8: effective_message_timestamp is updated"
最後に、roleを戻す。
$serf query -rpc-addr node1:7373 change_role '{"node":"node1:10031/droonga","role":null}'
logger "9: source node is activated"
$serf query -rpc-addr node2:7373 change_role '{"node":"node2:10031/droonga","role":null}'
logger "10: joining node is activated"