piroor
null+****@clear*****
Fri Nov 21 01:24:16 JST 2014
piroor 2014-11-21 01:24:16 +0900 (Fri, 21 Nov 2014) New Revision: 34539a2d8394c44995a335d906a73456b9221bf7 https://github.com/droonga/wikipedia-search/wiki/Droonga%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%81%AB%E3%83%8E%E3%83%B3%E3%82%B9%E3%83%88%E3%83%83%E3%83%97%E3%81%A7%E3%83%8E%E3%83%BC%E3%83%89%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B%E6%89%8B%E9%A0%86/34539a2d8394c44995a335d906a73456b9221bf7 Message: Updated Droongaクラスタにノンストップでノードを追加する手順 (markdown) Modified files: Droongaクラスタにノンストップでノードを追加する手順.md Modified: Droongaクラスタにノンストップでノードを追加する手順.md (+39 -102) =================================================================== --- Droongaクラスタにノンストップでノードを追加する手順.md 2014-11-21 00:10:34 +0900 (1daf7fa) +++ Droongaクラスタにノンストップでノードを追加する手順.md 2014-11-21 01:24:16 +0900 (8861b64) @@ -20,34 +20,17 @@ ### 実装しなければならない機能 -ノンストップでもストップ有りでも必要な機能: - - * graceful restart:古いプロセスは、新たなメッセージの受け取りは締め切るが、その時点までに受け取っていたメッセージについてはすべて処理を完了させてから、完全にプロセスを終了する。新しいプロセスは、すぐにメッセージの受け取りと処理を始める。→現在は可能。 - * droonga-replicate コマンド - * droonga-requestのstdin対応 →これは既に可能。 - -ノンストップでの追加のために必要な機能: - - * graceful stop:新たなメッセージの受け取りは締め切るが、その時点までに受け取っていたメッセージについてはすべて処理を完了させてから、完全にプロセスを終了する。→現在は可能。 * last message time保持、graceful stop後に出力 * effective message time保持、セット - * バッファ機能→可能となっているはず。 - - -### Serfによる死活管理 - -serfを利用したクラスタの死活監視の仕組みについて、以下の挙動になるよう変更を行っておく。 - - * serfの各ノードは、change_portイベントまたはクエリを受信すると、serfのポート番号を変更する。(これは、live nodesが認識される先のクラスタを分けるため。) - -### catalog.jsonの更新 - -droonga-engineは以下の挙動になるよう変更を行っておく。 - - * 新しいcatalog.jsonが監視対象ディレクトリ(staging-catalog)以下に配置されたら、即座にそれを検知する。 - * effectiveDateが現在時刻より前であれば、監視対象ディレクトリに置かれたstagingなcatalog.jsonの内容を、メモリ上のcatalog.jsonの内容に即座に反映する。と同時に、ファイルへの書き込み権限がある場合は、本番のcatalog.jsonにも変更を反映する。 - -もしくは、serfのメッセージを使って「新しいcatalogはここにあるよ」と通知、ダウンロードさせる仕組み。 + * serfのポート番号変更機能(デフォルト:7946、複製元:7947、複製先:7948) + * バッファ機能の拡張 + * リードオンリーなメッセージはバッファに溜めない + * メッセージ配送先決定処理の拡張 + * 一度ノードがliveでなくなった後、再びliveの状態に戻ったら、バッファが空になるまではリードオンリーのメッセージを配送しない。 + バッファが空になったらリードオンリーのメッセージも配送し始める。 + * 書き込み頻度が高いとバッファがいつまでも空にならない。 + バッファの残りが何個を切ったらバッファが空になったのと同じと見なしてリードオンリーのメッセージの配送を再開する、という風にするべきか? + その場合、しきい値は誰が決めるか? ### 最後に受け取ったメッセージのtimestamp @@ -60,87 +43,47 @@ droonga-engineは以下の挙動になるよう変更を行っておく。 * この情報は不揮発性の情報として与えられ、読み込んだ後はメモリ上の揮発性の情報として保持する。 * effective_message_timestampが設定されている場合、入ってきたメッセージのtimestampをチェックして、古いメッセージであれば破棄する。 -### バッファ - -ノードの状態に応じて挙動を帰るバッファを実装する。 - - * readなメッセージが来た場合、生存ノード同士だけで配送先を決める。 - * writeなメッセージが来た場合、「配送するだけで、結果を待たない」という設定のメッセージを、生死に関わらずすべてのノードに送る。 - * 死んでいるノードへ配送するように指示されたメッセージは、内蔵のバッファに溜め込まれる。 - - ## 基本方針 1. node2をクラスタに仮追加する。 - 2. node1をクラスタから切り離す。 + 2. node1を元のクラスタから半分切り離す。 3. node1からnode2へデータを複製する。 4. node1, node2を元のクラスタに戻す。 ## step1: node2をクラスタに仮追加する -複製作業に関わらないノード(生存ノード、ここではnode0のみ)のcatalog.jsonに、node2の情報を加えて、最終的な構成の状態にあたるcatalog.jsonを用意する。 +node2を以下の状態に設定する。 - node0% droonga-catalog-modify-replicas --dataset=Starbucks \ - --add-hosts=192.168.100.52 \ - --remove-hosts="" \ - --source=~/droonga/catalog.json \ - --output=~/tmp/catalog.json - node0% scp catalog.json 192.168.100.52:/tmp/ - node2% echo 7375 > ~/droonga/state/serf_port - node2% droonga-catalog-modify-replicas --dataset=Starbucks \ - --add-hosts="" \ - --remove-hosts="192.168.100.50,192.168.100.51" \ - --source=/tmp/catalog.json \ - --output=~/droonga/staging-catalog/catalog.json - node0% cp /tmp/catalog.json ~/droonga/staging-catalog/ + * serfのポート番号は7948(複製先)。 + * catalog.jsonの内容は、node2のみからなるサブクラスタ。 -この時点で、 +その上で、すべての既存ノード(node0, node1)のcatalog.jsonを変更し、node2をクラスタに追加する。 - * node2はserfの監視ポートが違う(7375)ので、元のクラスタから見たらノードとして動作しない。 - * node2は、node0, node1から見た時は死んだノードとして扱われるようになる。 - * node2自身から見た時は、node2だけのクラスタとなっている。 - * 生存ノードからnode2へ配送される予定だったwriteなメッセージが、バッファに溜まり始める。 +これにより、以下の状態になる。 + * node2はserfの監視ポートが違うので、元のクラスタから見たら存在しないままである。 + * よって、node2は、node0, node1から見た時は死んだノードとして扱われるようになる。 + * 生存ノードからnode2へ配送される予定だったwriteなメッセージは、バッファに溜まり始める。 -## step2: node1をクラスタから切り離す +## step2: node1を元のクラスタから半分切り離す。 -node1のcatalog.jsonをクラスタから切り離す。 +node1を以下の状態に設定する。 - node1% droonga-graceful-stop --output=~/droonga/last-message-timestamp + * serfのポート番号は7947(複製元)。 + * catalog.jsonの内容は、node1, node2のみからなるサブクラスタ。 -node1のノード構成を変更する。 +これにより、以下の状態になる。 - node1% echo 7374 > ~/droonga/state/serf_port - node1% droonga-catalog-modify-replicas --dataset=Starbucks \ - --add-hosts="" \ - --remove-hosts=192.168.100.50,192.168.100.52 \ - --source=~/droonga/catalog.json \ - --output=~/droonga/staging-catalog/catalog.json - -この時点で、 - - * node1はserfの監視ポートが違う(7374)ので、元のクラスタから見たらノードとして動作しない。 + * node1はserfの監視ポートが違うので、元のクラスタから見たらノードとして動作しなくなる。 * node1は、node0から見た時は死んだノードとして扱われるようになる。 - * node1自身から見た時は、node1だけのクラスタとなっている。 - * node0からnode1へ配送される予定だったwriteなメッセージが、バッファに溜まり始める。 + * node1自身から見た時は、node1(生存)とnode2(停止中)のクラスタとなっている。 + * そのため、node1からnode2へ配送される予定だったwriteなメッセージはバッファ上に残っている。 + * node0からnode1とnode2へ配送される予定だったwriteなメッセージが、node0のバッファに溜まり始める。 ## step3: node1からnode2へデータを複製する。 -drndumpでデータを複製する。 - - node1% drndump --host=192.168.100.51 \ - --dataset=Starbacks | \ - droonga-client --host=192.168.100.52 - -※step2, step3を1操作で行うコマンドの案 - - node1% droonga-replicate --from-host=192.168.100.51 \ - --from-port=10031 \ - --to-host=192.168.100.52 \ - --to-port=10031 \ - --datasets=Starbacks \ - --tag=starbacks +serfでメッセージを送り、node2がnode1からデータを吸い出す。 データの複製が終わったら、node1のlast_message_timestampをnode2のeffective_message_timestampに設定する。 @@ -149,26 +92,20 @@ drndumpでデータを複製する。 ## step4: node1, node2を元のクラスタに戻す。 -最終的な構成のクラスタのためのcatalog.jsonをnode1, node2に展開する。 - - node0% scp catalog.json 192.168.100.51:~/droonga/staging-catalog/ - node0% scp catalog.json 192.168.100.52:~/droonga/staging-catalog/ - -droonga-engineが自動的に新しいcatalog.jsonを認識する。 - -しかし、node1とnode2はserfのポート番号が違うため、まだ生存ノードから見たら死んだノード扱いになっている。 -そこで、serfのポート番号を元に戻す。 +node0, node1を以下の状態に設定する。 - node1% echo 7373 > ~/droonga/state/serf_port - node2% echo 7373 > ~/droonga/state/serf_port + * serfのポート番号は7946(デフォルト)。 + * catalog.jsonの内容は、node0, node1, node2からなるサブクラスタ。 ここで、node1とnode2は、生存ノードから見た時に、ステータスが「死んでいるノード」から「復帰中のノード」に切り替わる。 - * 生存ノードはバッファに溜め込んでおいたwriteなメッセージを、復帰中のノード(node1とnode2)に配送し始める。 - * node2は、effective_message_timestampに基づいて、バッファから配送されてきたメッセージのうち、node1には渡されていないがnode2には渡されていたというメッセージ(=すでにdrndumpを通じてnode1から結果を受け取っているメッセージ)を破棄する。 - * バッファが空になるまでは、復帰中のノード宛のメッセージはバッファに貯まっていく。 - * バッファが空になったら、復帰中のノードは「生きている」状態に戻る。 - * 生存ノードの状態に戻った後は、通常通りメッセージが流れてくるようになる。 - * 「有効期限切れと見なすメッセージの時刻」はもう不要なので、破棄する。 + * node1はnode2に、バッファに溜め込んでおいたwriteなメッセージを配送し始める。 + * node2は、effective_message_timestampに基づいて、受け取る必要が無い有効期限切れのメッセージを破棄する。 + * effective_message_timestampよりも新しいメッセージを受信したら、「有効期限切れと見なすメッセージの時刻」はもう不要なので、破棄する。 + * node0はnode1とnode2に、バッファに溜め込んでおいたwriteなメッセージ配送し始める。 + * node2は、effective_message_timestampに基づいて、受け取る必要が無い有効期限切れのメッセージを破棄する。 + * effective_message_timestampよりも新しいメッセージを受信したら、「有効期限切れと見なすメッセージの時刻」はもう不要なので、破棄する。 + * node1, node2向けのバッファが空になるまでは、node1, node2宛のメッセージは引き続きバッファに貯まっていく。 + * バッファが空でない間は、リードオンリーのメッセージはそのノードには配送されリードオンリーのメッセージも配送され始める。 以上でノードの追加は完了である。 \ No newline at end of file -------------- next part -------------- HTML����������������������������...下載