logo
banner

ErlyWebでmnesiaを分散データベースにする(2)



目次

異なるホスト間で通信する

異なるホスト間で通信する前に

前回、同じホスト内のノード間でのデータベースのレプリケーションについてみてきましたが、今回は異なるホスト間でデータベースのレプリケーションを行ってみたいと思います。
その前に、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}}}

以上です、後は同一ホスト内で複数ノードを立ち上げた時のようにテーブルをコピーしてきたり、テーブルのコピータイプを変更します。

Copyright (C) 2007 KLab Inc. All Rights Reserved.