目次 |
異なるホスト間で通信する
異なるホスト間で通信する前に
前回、同じホスト内のノード間でのデータベースのレプリケーションについてみてきましたが、今回は異なるホスト間でデータベースのレプリケーションを行ってみたいと思います。
その前に、2つ問題点があります。
- Windowsでは-name オプションが yaws.bat内でサポートされていない。
- ショートネーム(-sname)のノードとロングネーム(-name)のノード間ではコミュニケーションできないので、テーブルの内容をダンプする必要がある。
yaws.batを編集して、-nameオプションに対応する。
異なるホスト間で通信するには-nameオプションでロングネームを指定してノードを立ち上げる必要があります。
Windowsのyaws.batでは -name オプションに対応していないので編集します。
安全のためyaws.batをyaws2.batにコピーしてから編集しました。
":: -sname xxx -- start with sname xxx" の行の上あたりに、6行ほど追加します。(Windowsの場合のみ)
:: -name xxx -- start with name xxx
IF %arg%=="-name" (
SET name=-name %1
SHIFT
GOTO :handle_cmd_line
)
:: -sname xxx -- start with sname xxx
このバッチを使い、新しくコンフィグファイルも作成し、次のように起動しておきます。
.confの変更点
- ポート番号の変更
- idの変更
>yaws2 -i -c /work/apps/yaws-web.conf -name web@ホストのロングネーム -M /work/apps/web-db
既存のデータを移行する
ショートネームのノードとロングネームのノードは通信できないため、既存のデータを通信で取得することができません。このため、テキストファイルにデータをダンプして移行してみたいと思います。 最初のwinノードを起動し、dump_to_textfile()でファイル名を指定してテキストでダンプファイルを出力します。
(win@PC-114)1> mnesia:dump_to_textfile("db.txt").
ok
以下、ダンプファイルの内容です。
{tables,[{counter,[{record_name,counter},
{attributes,[key,counter]}]},
{musician,[{record_name,musician},
{attributes,[id,name,birth_date,instrument,bio]}]}]}.
{counter,musician,3}.
{musician,1,'John Lennon',"1940/10/9","vocals",
<<"An iconic English 20th century rock and roll songwriter and singer...">>}.
{musician,2,'Paul McCartney',"1942/6/18","piano",
<<"Sir James Paul McCartney is a popular Grammy Award-winning English artist...">>}.
{musician,3,foo,
{datetime,{{2007,2,28},{0,0,0}}},
"guitar",<<"big musician. good">>}.
次に新しくロングネームで起動したノードでダンプファイルをロードします。
(web@ホスト名1)1> mnesia:load_textfile("db.txt").
New table counter
New table musician
{atomic,ok}
mnesia:info().です。
(web@ホスト名1)2> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
musician : with 3 records occupying 426 words of mem
counter : with 1 records occupying 291 words of mem
schema : with 3 records occupying 616 words of mem
===> System info in version "4.4", debug level = none <===
opt_disc. Directory "c:/work/apps/web-db" is NOT used.
use fallback at restart = false
running db nodes = ['web@ホスト名1']
stopped db nodes = []
master node tables = []
remote = []
ram_copies = [counter,musician,schema]
disc_copies = []
disc_only_copies = []
[{'web@ホスト名1',ram_copies}] = [schema,counter,musician]
5 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok
テーブルをすべてディスクに保存します。
(web@ホスト名1)4> mnesia:change_table_copy_type(schema,node(),disc_copies).
{atomic,ok}
(web@ホスト名1)5> mnesia:change_table_copy_type(counter,node(),disc_copies).
{atomic,ok}
(web@ホスト名1)6> mnesia:change_table_copy_type(musician,node(),disc_copies).
{atomic,ok}
これで、データベースをレプリケーションする元のノードの準備が終了です。
追加ホストのノードの準備
異なるホストのノード間で通信する場合には、お互いのcookieを同じにする必要があります。方法は
- ホームディレクトリにある.erlang.cookieの内容を同じにする
- erlang:set_cookie()で同じ値を指定する。
Windowsの場合、.erlang.cookieファイルはユーザーの%HOMEPATH%の直下にあります。
さて、2台目のホストですが、同じWindowsマシンが手元に無いので、Linuxにしました。Erlang,YawsとErlyWebのインストールをします。(手順は省略)
Windowsへのインストールのときと同じように、ErlyWebのソースを修正を必ず行ってください。
Erlangのインストールディレクトリ\lib\erlyweb-0.7\src\erlydb\erlydb.erl の381行目を修正します。
修正前:
{value, Val} ->
修正後:
{value, {ok,Val}} ->
修正後のコンパイルします。
$cd Erlangのインストールディレクトリ\lib\erlyweb-0.7\ $./make.sh
次にディレクトリの準備。
Linuxマシンの$HOME/work/appsに同じように、元の\work\apps\musicのフォルダをそのままコピーします。yaws.confも$HOME/work/appsに作成し、以下のようなサーバの設定を行います
<server サーバ名>
port = ポート番号
listen = 0.0.0.0
docroot = ホーム/work/apps/music/www
appmods = <"/music",erlyweb>
<opaque>
appname = music
</opaque>
</server>
追加のノードの起動とmnesiaの接続
yawsの起動はつぎのようにします。mnesiaのディレクトリを指定するときに絶対パスを指定するとエラーが出るようです。
$cd work/apps $yaws -i -c yaws.conf -name web@自サーバ名 -M db
元のサーバのノードにmnesiaを接続します。
(web@自サーバ名)3> mnesia:change_config(extra_db_nodes,['web@相手サーバ名']).
{ok,['web@自サーバ名']}
(web@自サーバ名)4> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
schema : with 3 records occupying 641 words of mem
===> System info in version "4.3.5", debug level = none <===
opt_disc. Directory "ホーム/work/apps/db" is NOT used.
use fallback at restart = false
running db nodes = ['web@相手サーバ名','web@自サーバ名']
stopped db nodes = []
master node tables = []
remote = [counter,musician]
ram_copies = [schema]
disc_copies = []
disc_only_copies = []
[{'web@自サーバ名',ram_copies},{'web@相手サーバ名',disc_copies}] = [schema]
[{'web@相手サーバ名',disc_copies}] = [counter,musician]
4 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok
次に、mnesiaのドライバのコンパイルオプションをつけて、ErlyWebのアプリケーションをコンパイルします。
(web@自サーバ名)2> erlyweb:compile("ホーム/work/apps/music",[{erlydb_driver, mnesia}]).
debug:erlyweb_compile:382: Compiling Erlang file "music_app_controller"
debug:erlyweb_compile:382: Compiling Erlang file "html_container_controller"
debug:erlyweb_compile:382: Compiling Erlang file "musician_controller"
debug:erlyweb_compile:382: Compiling Erlang file "musician_view"
debug:erlyweb_compile:377: Compiling ErlTL file "forms_view"
debug:erlyweb_compile:382: Compiling Erlang file "musician"
debug:erlyweb_compile:377: Compiling ErlTL file "html_container_view"
debug:erlyweb_compile:382: Compiling Erlang file "forms_controller"
debug:erlyweb_compile:114: Generating ErlyDB code for models: "musician.erl "
debug:erlydb:355:
--- To skip foreign key checks, compile with the {skip_fk_checks, true} option
debug:erlydb:391: Generating code for musician
{ok,{{2008,3,7},{11,53,5}}}
以上です、後は同一ホスト内で複数ノードを立ち上げた時のようにテーブルをコピーしてきたり、テーブルのコピータイプを変更します。

