はじめに
Mnesiaは、Erlangという言語をベースとした並列プログラミング用のオープンソース開発環境であるErlang OTPに付属している高機能のデータベース管理システム(DBMS)です。Mnesiaは真の分散DBMSなので、世界中の何千ものノード間でデータを分散し、複製し、断片化することも朝飯前です。ユーザーがしなければならないのは、Mnesiaデータベースの分散先となるさまざまなErlangノードを実行することだけです。
Mnesiaという名前になった経緯は、少々眉唾ではありますが、もともとは「Amnesia(健忘症)」という名前だったものを、エリクソンの重役が「データベースに『物忘れ』を連想させる名前を付けるのはいかがなものか」と発言したことから、エンジニアが「A」の文字を取って「Mnesia」とし、「すべてを記憶するもの」の意味を持たせたと言われています。Mnesiaは、Erlangで実装されたあらゆるプログラムにフォールトトレランス機能を提供します。また、ユーザーは直接Erlangを使ってMnesiaデータベースとやり取りできます。Mnesiaでは、Erlangがデータベース言語になるのです。
この記事では、Mnesiaの重要な機能をいくつか紹介します。この記事のダウンロード可能なサンプル内のtest.erlファイルには、数行のコードをまとめた簡単な関数がいくつか記述されています。これは、主としてErlangシェルで使用します。
やむを得ない場合を除き、Erlang構文のすべての側面や基本概念について説明することはしません。そのような情報は、オンラインマニュアルで簡単に見つけることができます。アトム、変数、タプル、リストには特に注意してください。私のDevXの記事「Writing Parallel Programs with Erlang」にも、役立つ背景情報が書かれています。この記事では、Erlangの並列処理に関する側面について説明しています。
ノード:Erlangの心臓部
ノードという概念は、Erlangの心臓部です。Erlangシェルを起動するときに、名前とcookieと呼ばれる秘密のワードを指定すれば、そのErlangシェルをノードにできます。いくつかの例で、Erlangの動作を見ていきましょう。私のLAN上には3台のDebian Linuxマシン(charlie、delta、nemo)が接続されています。これらのマシンには、以下のコマンドを実行してErlangをインストールしてあります。
apt-get install erlang
今回の例では、意味のない文字列(AXHMTYGVJDNJIFGYADNJ)を秘密のワードとして選択し、ノード名はfirst、second、thirdとします。ここで、マシンcharlieとdeltaで以下の2つのコマンドを実行しました。
erl -sname first -setcookie AXHMTYGVJDNJIFGYADNJ erl -sname second -setcookie AXHMTYGVJDNJIFGYADNJ
これで、2つのErlangノードfirst@charlieとsecond@deltaを接続できるようになりました。次の例では、charlieからpingを1回実行して、deltaへの接続を確認しています。
(first@charlie)1> net_adm:ping(second@delta). pong
次の例では、どんなノードが接続されているかを問い合わせて、接続をテストしています。
(first@charlie)2> nodes(). [second@delta]
このように、既に2つの協調Erlangノードが簡単に通信できる状態になっています。
Mnesiaスキーマ
サンプルのtest.erlファイルには、test:start_schema(NodesList)
とtest:start_tables
という2つの関数が記述されています。これらは1回だけ実行する必要があります。これらの関数によって、Mnesiaスキーマを作成し、テーブルを定義し、定義したテーブルに初期データを設定します。
最初にしなければならない操作はMnesiaスキーマの作成です。この操作は、接続されているノード上でMnesiaエンジンを起動する前に行う必要があります。Mnesiaスキーマとは、ファイルシステム上の特殊なテーブルとローカルディレクトリです。このディレクトリはファイルを格納することができ、ノードごとに一意でなければなりません。デフォルトでは、Mnesiaスキーマは各データベースにつき1回、現在のディレクトリの下に「Mnesia.node_name@host」という名前で作成されます。ただし、erl
コマンドのオプション-mnesia dir [database_dir]
を使用して、デフォルトを無効にできます。
関数mnesia:create_schema(NodesList)
は、既に接続されているErlangノードのリストを引数として取ります。接続されているノードのいずれかから以下を実行すると、Mnesiaのdir
はローカルノードにのみ作成されます。
mnesia:create_schema([local_node_name@localhost]).
しかし、以下を実行すると、
mnesia:create_schema([local_node_name@localhost, remote_node_name1@host1, remote_node_name2@host2]).
引数リストに指定したすべてのノードにMnesiaスキーマのコピーが作成され、システムによってすべてのコピーの同期が保たれます。これは、冗長性とフェイルオーバーの問題に関して重要です。
これを実践するため、3つのノードにtest.erlファイルを配布し、以下のコマンドでコンパイルします。
c(test.erl).
first@charlieノードとsecond@deltaノードの両方にスキーマを作成するため、2つのノードのいずれかから以下を実行します。
mnesia:create_schema([first@charlie,second@delta]).
次に、もう一方のノードでmnesia:start()
を実行します。