当ブログをご覧のみなさまこんにちは。さくらインターネット研究所の大久保です。
前回に引き続き、今回も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台のストレージサーバでレコードを分散・冗長化する方法について説明しました。次回以降はさらにサーバを増やした場合どのようになるか?パフォーマンスはどうか?という点について調べていきます。
[…] This post was mentioned on Twitter by 鷲北 賢. 鷲北 賢 said: さくらインターネット研究所ブログ Flareを使う(複数台構成) http://research.sakura.ad.jp/2010/05/12/flare-servers1/ […]
[…] [Web]Flareを使う(複数台構成) ? さくらインターネット研究所 […]