分散Key/Valueストア,Kaiを使ってみよう!

第3回 Kaiの詳細(1) ─Kaiの要であるクラスタを極める

この記事を読むのに必要な時間:およそ 7.5 分

それでは,次のようなPerl Scriptを用意し,kai_test_cluster_get4.plという名前で保存してください。

リスト2 kai_test_cluster_get4.pl

#!/usr/bin/env perl

use strict;
use warnings;

use Test::More tests => 1;
use Cache::Memcached;

my $mem = Cache::Memcached->new({
    servers => ['127.0.0.1:11214'],
});

is $mem->get('foo'), 'bar';

用意したPerl Scriptを実行し,データを取得してください。

$ perl /path/to/kai_test_cluster_get4.pl
1..1
ok 1

このような実行結果となれば,クラスタへ新規に追加したノードから,データの取得が正常に行えています。

では,クラスタへ更にノードを複数追加し,古いノードを停止した後に,データが失われていないか試してみます。

まず始めに,追加するノードの設定ファイルを作成し,ノードを起動してください。

$ /path/to/make_kai_config.sh 5 6
$ /path/to/start_kai.sh kai5 kai6

次に,クラスタに新しいノードを参加させます。

$ /path/to/remsh.sh kai1
Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.1  (abort with ^G)
(kai1@centos)1> kai_rpc:check_node({{127,0,0,1}, 11014}, {{127,0,0,1}, 11015}).    % (c)
ok
(kai1@centos)2> kai_rpc:check_node({{127,0,0,1}, 11015}, {{127,0,0,1}, 11016}).    % (d)
ok
(kai1@centos)3> kai_rpc:check_node({{127,0,0,1}, 11016}, {{127,0,0,1}, 11014}).    % (e)
ok
(kai1@centos)4> 
User switch command
 --> q

基本的には,kai4をクラスタへ追加した場合と理屈は同じですが,少し複雑であるため,補足説明します。

(c) で,kai4にkai5を教える事で図2 矢印1⁠,kai5の情報は,kai4からクラスタ全体へ伝わります図2 矢印2⁠。

(d) で,kai5にkai6を教える事で図2 矢印3⁠,kai6の情報は,kai5からクラスタ全体へ伝わります図2 矢印4⁠。

(e) で,kai6にkai4を教える事で図2 矢印5⁠,kai6はkai4からクラスタ全体の情報を受け取り,kai5もkai6からクラスタ全体の情報を受け取ります図2 矢印6⁠。

図2 クラスタ {kai1,kai2,kai3,kai4} にノード {kai5,kai6} を追加する例

図2 クラスタ {kai1,kai2,kai3,kai4} にノード {kai5,kai6} を追加する例

これで,クラスタを構成するノード数は,6個となりました。なお,クラスタを構成する手順は,0.4以降のバージョンで簡略化される予定です。

クラスタが3個のノードで構成されていた頃から,データを一度も保存していませんが,前述の通り,全てのノードからデータを取得する事ができるか試してみましょう。

次のようなPerl Scriptを用意し,kai_test_cluster_get456.plという名前で保存してください。

リスト3 kai_test_cluster_get456.pl

#!/usr/bin/env perl

use strict;
use warnings;

use Test::More tests => 3;
use Cache::Memcached;

for (4..6) {
    my $mem = Cache::Memcached->new({
        servers => ['127.0.0.1:1121' . $_],
    });
    is $mem->get('foo'), 'bar';
}

用意したPerl Scriptを実行し,クラスタへ新規に追加したノードからデータを取得してください。

$ perl /path/to/kai_test_cluster_get456.pl
1..3
ok 1
ok 2
ok 3

このような実行結果となれば,クラスタへ新たに追加したノードからデータの取得が正常に行えています。

では,古いノードを停止します。それぞれのデータはN=3個ずつ複製されていますので(設定ファイルのnを参照⁠⁠,当たり前ですが,3個以上のノードをほぼ同時に停止すると一部のデータが失われる可能性があります。

ここでは,少し時間をずらしながら3個のノードを順に停止してみます。

$ /path/to/remsh.sh kai1
Erlang R13B (erts-5.7.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.1  (abort with ^G)
(kai1@centos)1> q().
ok
(kai1@centos)2>
User switch command
 --> r kai2@centos                    <- r で別のリモートシェルに切り替える
 --> c
Eshell V5.7.1  (abort with ^G)
(kai2@centos)1> q().               <- データの再配置が終わるまで,数秒待ってから停止
ok
(kai2@centos)2>
User switch command
 --> r kai3@mbp
 --> c
Eshell V5.7.1  (abort with ^G)
(kai3@centos)1> q().
ok
(kai3@centos)2>    
User switch command
 --> q

これで,初期にデータを保持していた古いノードは全て停止し,クラスタを構成するノードは,新たに追加した3個のノードとなりました。

では,先ほど用意したPerl Scriptを実行し,各ノードからデータを取得してください。

$ perl /path/to/kai_test_cluster_get456.pl
1..3
ok 1
ok 2
ok 3

このような実行結果となれば,ノード間のデータ再配置が正常に行われています。Kaiのクラスタでは,ノードの追加・除去にかかわらずデータが永続化されている事がお解り頂けたでしょうか?

著者プロフィール

幾田雅仁(いくたまさひと)

酪農,ゴルフのキャディさん,某大手パソコン通信の下請け,某大手ポータルサイトなどを経て,決済代行を生業とする株式会社ゼロに入社。

p2p?なにそれ?美味しいの?の状態で,Erlang 分散処理勉強会に参加し,Kai のプレゼンを見て感銘を受け,無理矢理開発に参加し,現在に至る。