ホーム » 技術 » Key Value Store » Flareを使う(複数台構成)

SAKURA Internet Inc.

アーカイブ

Flareを使う(複数台構成)

当ブログをご覧のみなさまこんにちは。さくらインターネット研究所の大久保です。

前回に引き続き、今回もFlareを取り上げたいと思います。前回はFlareをインストールし、とりあえず1台のサーバで動作させるところまでを説明しましたので、今回は複数台のサーバで動作させ、分散KVSの仕組みについてご紹介したいと思います。

Flareにおけるデータ分散アーキテクチャ

まず始めにFlareではどのようにデータを分散しているのか説明します。

Flareは分散KVSのソフトウェア一つで、複数のサーバにデータが分散して格納されます。Flareでのデータ分散の概念を表した図を以下に示します。

動作は以下の通りです。

  • データの格納先は、キーのハッシュ値を元にサーバのグループであるパーティションという単位で分散し、いづれか1つのパーティションに格納されます。
  • Flareの動作中にパーティションの追加はできますが、削除はできません。
  • パーティション内にはマスターノードが1台存在し、データのレプリケーションを行う複数台のスレーブノードを置くことができ、冗長化を図ることができます。
  • スレーブノードは任意のタイミングで追加、削除が可能です。
  • マスターノードがダウンすると、選ばれた1台のスレーブノードがマスターに昇格します。
  • データのsetはマスターノードのみで行われまが、データのgetは指定したbalance値の比率に応じてスレーブノードでも処理されます。

今回の実験サーバ構成

今回は以下のような計6台のサーバ構成で実験を行います。

役割 IPアドレス
インデックスサーバ 192.168.13.21
ストレージサーバ パーティション0 マスター 192.168.13.22
パーティション0 スレーブ 192.168.13.23
パーティション1 マスター 192.168.13.24
パーティション1 スレーブ 192.168.13.25
プロキシサーバ 192.168.13.26

各役割のサーバは以下の働きをします。

  • インデックスサーバ
    Flareクラスタ内に1台存在し、各ノードの死活監視、各ノードへのサーバリストの通知、各ノードへの指示を行います。インデックスサーバの冗長化は、2010年5月現在のバージョン1.0.9では実装されていません。
  • ストレージサーバ
    データを格納します。上記の通りマスター、スレーブの2種類が存在します。
  • プロキシサーバ
    memcachedプロトコルをアプリケーションに提供し、リクエストをFlareクラスタへ中継します。

サーバ設定

Step1. インデックスサーバの設定と起動

以下の設定ファイルを/home/admin/flare/flarei.confとして保存します。

data-dir = /home/admin/flare
log-facility = local0
server-name = 192.168.13.21

monitor-threshold=3
monitor-interval=1
monitor-read-timeout=1000

ここでは、ストレージサーバ障害発生時の切り替わりを早めるためタイマーの値を一部変更しています。なお、オプションの意味は以下URLのFlareのページに掲載されていますので、詳しくはこちらを参照ください。
http://labs.gree.jp/Top/OpenSource/Flare/Document/Reference.html

インデックスサーバ(flarei)を起動します。

% /usr/bin/flarei -f /home/admin/flare/flarei.conf --daemonize

Step2. ストレージサーバ・プロキシサーバ

ストレージサーバ・プロキシサーバの5台では、以下の設定を/home/admin/flare/flared.confとして保存します。server-nameは自身のIPアドレスを指定しますが、以下ではパーティション0 マスター(192.168.13.22)を例にした設定を示します。

data-dir = /home/admin/flare
log-facility = local0
storage-bucket-size = 16777216
index-server-name = 192.168.13.21
server-name = 192.168.13.22

※ 青文字で示した部分は各サーバのIPアドレスに変更する。

各サーバにて、flaredを起動します。

% /usr/bin/flared -f /home/admin/flare/flared.conf --daemonize

Step3. 各サーバの役割設定

インデックスサーバにtelnet接続し、各サーバの役割を設定します。設定前の初期状態では以下のように全てプロキシ状態になっているかと思います。

% telnet localhost 12120
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
stats nodes
STAT 192.168.13.22:12121:role proxy
STAT 192.168.13.22:12121:state active
STAT 192.168.13.22:12121:partition -1
STAT 192.168.13.22:12121:balance 0
STAT 192.168.13.22:12121:thread_type 16
STAT 192.168.13.23:12121:role proxy
STAT 192.168.13.23:12121:state active
STAT 192.168.13.23:12121:partition -1
STAT 192.168.13.23:12121:balance 0
STAT 192.168.13.23:12121:thread_type 17
STAT 192.168.13.24:12121:role proxy
STAT 192.168.13.24:12121:state active
STAT 192.168.13.24:12121:partition -1
STAT 192.168.13.24:12121:balance 0
STAT 192.168.13.24:12121:thread_type 19
STAT 192.168.13.25:12121:role proxy
STAT 192.168.13.25:12121:state active
STAT 192.168.13.25:12121:partition -1
STAT 192.168.13.25:12121:balance 0
STAT 192.168.13.25:12121:thread_type 18
STAT 192.168.13.26:12121:role proxy
STAT 192.168.13.26:12121:state active
STAT 192.168.13.26:12121:partition -1
STAT 192.168.13.26:12121:balance 0
STAT 192.168.13.26:12121:thread_type 20
END

各サーバの役割を設定します。

※ 192.168.13.22をパーティション0のマスターに設定します。
node role 192.168.13.22 12121 master 1 0
OK

※ 192.168.13.23をパーティション0のスレーブに設定します。
node role 192.168.13.23 12121 slave 1 0
OK
node role 192.168.13.23 12121 slave 1 0
OK

※ 192.168.13.24をパーティション1のマスターに設定します。
node role 192.168.13.24 12121 master 1 1
OK

※ 192.168.13.24をactiveにします。
node state 192.168.13.24 12121 active
OK

※ 192.168.13.25をパーティション1のスレーブに設定します。
node role 192.168.13.25 12121 slave 1 1
OK
node role 192.168.13.25 12121 slave 1 1
OK

ここでは、全てbalance値(getクエリがこの値で重み付けされる)はデフォルトの1に設定していますが、スレーブサーバを設定する際、すぐにgetクエリを受けないように設定直後はbalance値が0となります。そこで、もう一度同じコマンドでbalance値を変更する必要があります。

また、パーティション1のマスターを追加した後もすぐにはactiveにならず、一旦prepare状態になりますので、node stateコマンドでactive状態に設定します。

なお、コマンドの意味は以下URLのFlareのページに掲載されていますので、詳しくはこちらを参照ください。
http://labs.gree.jp/Top/OpenSource/Flare/Document/Reference/Compatibility.html

正常に設定が完了すると以下のような状態になります。赤文字のところが役割とパーティションを表していますので、これが正しく設定されたか確認します。

stats nodes
STAT 192.168.13.22:12121:role master
STAT 192.168.13.22:12121:state active
STAT 192.168.13.22:12121:partition 0
STAT 192.168.13.22:12121:balance 1
STAT 192.168.13.22:12121:thread_type 16
STAT 192.168.13.23:12121:role slave
STAT 192.168.13.23:12121:state active
STAT 192.168.13.23:12121:partition 0
STAT 192.168.13.23:12121:balance 1
STAT 192.168.13.23:12121:thread_type 17
STAT 192.168.13.24:12121:role master
STAT 192.168.13.24:12121:state active
STAT 192.168.13.24:12121:partition 1
STAT 192.168.13.24:12121:balance 1
STAT 192.168.13.24:12121:thread_type 19
STAT 192.168.13.25:12121:role slave
STAT 192.168.13.25:12121:state active
STAT 192.168.13.25:12121:partition 1
STAT 192.168.13.25:12121:balance 1
STAT 192.168.13.25:12121:thread_type 18
STAT 192.168.13.26:12121:role proxy
STAT 192.168.13.26:12121:state active
STAT 192.168.13.26:12121:partition -1
STAT 192.168.13.26:12121:balance 0
STAT 192.168.13.26:12121:thread_type 20
END

これでサーバの準備ができました。

動作確認

プロキシサーバの12121番ポートに接続します。以下の通り正常に動作していることが確認できます。

% telnet localhost 12121
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
set test1 0 0 5
abcde
STORED
set test2 0 0 5
12345
STORED
get test1
VALUE test1 0 5
abcde
END
get test2
VALUE test2 0 5
12345
END

次にプロキシサーバにて以下のperlスクリプトを走らせ、100万レコードを格納してみます。

#!/usr/bin/env perl

use Cache::Memcached;

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

$value = "01234567890123456789012345678901234567890123456789";

foreach (0 .. 999999) {
	$key = sprintf("test%08d", $_);
	unless ($mem->set($key, $value)) {
		warn "set failed $_\n";
		sleep(1);
		redo;
	}
}

コードをご覧いただければ一目瞭然ですが、格納するキーと値は以下の通りです。

キー
test00000000〜test00999999 01234567890123456789012345678901234567890123456789 (50bytes)

スクリプトを実行すると以下のようにデータが格納されていることが確認できます。

% telnet localhost 12121
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
get test00000000
VALUE test00000000 0 50
01234567890123456789012345678901234567890123456789
END
get test00999999
VALUE test00999999 0 50
01234567890123456789012345678901234567890123456789
END

各ストレージサーバに格納されているレコード数は、ストレージサーバに接続してstatsコマンドを入力すると、curr_itemsというフィールドで取得することができます。以下は4台のストレージサーバからnetcat(nc)コマンドを用いて情報を取得した例です。

% echo 'stats'|nc 192.168.13.22 12121|grep curr_items
STAT curr_items 500001
% echo 'stats'|nc 192.168.13.23 12121|grep curr_items
STAT curr_items 500001
% echo 'stats'|nc 192.168.13.24 12121|grep curr_items
STAT curr_items 500001
% echo 'stats'|nc 192.168.13.25 12121|grep curr_items
STAT curr_items 500001

上記のように2つのパーテションにきれいにデータが分散しており、マスターとスレーブでレコード数が等しくなっていることが確認できます。

まとめ

今回は4台のストレージサーバでレコードを分散・冗長化する方法について説明しました。次回以降はさらにサーバを増やした場合どのようになるか?パフォーマンスはどうか?という点について調べていきます。


2件のコメント

コメントは停止中です。