XenでMogileFSしてみる

ということで興味が湧いたMogileFSを触ってみました。分散ファイルシステムもいくつかありそうですが、やっぱりHadoopも触ってみたいところですね。Hadoopファイルシステムだけでなく分散処理の実装も込みみたいですが。インストールはLVSで失敗したけど懲りずにXenでやりました(LVSはあの後も色々試したけどうまく行かず (x_x) )。やぱ仮想化は便利ですね。

MogileFSの特徴なんかはsixapartの方がこちらで紹介してくれています。
http://www.sixapart.jp/techtalk/2006/10/dev_mogilefs.html
公式はこちら
http://www.danga.com/mogilefs/

構成要素は

  • Storage Node (実ファイル保存する)
  • trackers (実ファイルのありかを教えてくれる。コントローラみたいな役割。)

といったコンポーネントみたいです。trackerは各ファイルがどこにあるかをmysqlに保持してもつみたいです。
後はクライアント用のPerlで作られたAPIがあるみたいです。

http://www.sixapart.jp/techtalk/2006/10/dev_mogilefs.html

ということで、trackersとtracker'sデータベース用に1ホスト。実ファイル置き場用として2ホスト。クライアント用に1ホストと考えて、計4つXenでゲストOSを作ろうと思います。準仮想化で出たばっかりのCent OS 5.3をインストール。ホストOSもこっそり5.2からyum upgradeして上げておきました。各々のホスト名とアドレスは以下。

ホスト名アドレス
trackers192.168.0.191
mogstored1192.168.0.192
mogstored2192.168.0.193
client192.168.0.194

XenでゲストOSを作成

# mkdir /opt/xen/trackers
# virt-install -n trackers -r 256 -f /opt/xen/tracers/trackers.img -s 8 --nographics -l http://mirror.centos.org/centos/5.3/os/i386/
完全仮想化のゲストがいいですか (yes または no)? これは修正不要のオペレーティングシステムの実行を可能にします。 no

インストールを開始しています...
ファイル CentOS を読出中...                             467 kB 00:01 
ファイル vmlinuz を? 100% |=========================| 2.1 MB    00:04     
ファイル initrd.img ? 100% |=========================| 6.0 MB    00:13     

...画面に従って

インストールが終了したら例によってvirt-cloneで複製します。

# mkdir /opt/xen/mogstored1
# mkdir /opt/xen/mogstored2
# mkdir /opt/xen/client

# virt-clone --original trackers --name mogstored1 --file /opt/xen/mogstored1/mogstored1.img
# virt-clone --original trackers --name mogstored2 --file /opt/xen/mogstored1/mogstored2.img
# virt-clone --original trackers --name client --file /opt/xen/client/client.img

trackersの構築

tarackersには各ファイルがどこにいるのかを管理するためのDBが必要となるようでmysqlが必要です。ということでmysqlのインストールとmogileFSのインストールを行います。色々引きずられて結構CPANからモジュールをインストールしないとダメでした。トラッカーはtrackersという名前で作成したのでこいつを起動して色々いれて行きます。

xm create -c /etc/xen/trackers

Mogilefsmysql系のcpanモジュールにもいくつか依存しているみたいなので先にmysqlをインストールしておきます。

# yum -y install mysql mysql-server
# /etc/init.d mysqld start

CPANモジュールインストール。下記以外にもmysqlインストール時に同時にインストールされるDBI, DBD::mysqlにも依存している模様。

cpan> install Danga::Socket
      ※以下もインストールする必要あり
      Sys::Syscall

cpan> install IO::AIO

cpan> install Net::Netmask

cpan> install Perlbal
      ※以下もインストールする必要あり
      Compress::Raw::Bzip2
      Compress::Raw::Zlib
      Compress::Zlib
      HTML::Tagset
      HTML::Parser
      HTTP::Response
      BSD::Resource
      HTTP::Date

cpan> install MogileFS::Client
      ※以下もインストールする必要あり
      IO::WrapTie

cpan> install Gearman::Client

cpan> install Gearman::Client::Async

cpan> install Gearman::Server

sixapartのsvnリポジトリからソースをチェックアウトしてMogilefsをインストールします。trackerとかストレージnode用のデーモンはtrunk/serverの下のファイルになるみたいです。

$ svn co http://code.sixapart.com/svn/mogilefs/trunk
$ cd trunk/server
$ perl Makefile.PL
$ make
$ make test
$ su
# make install

続いてtracker用のデータベースを作成します。mogdbsetupコマンドで作成できる模様。データベースはInnoDBでないとダメみたいなのでmy.cnfをいじってデフォルトをInnoDBにしました。mysqldセクションにderault-table-type=InnoDBを追加しておきます。

# vi /etc/my.cnf

default-table-type=InnoDB

mysqld再起動

# /etc/init.d/mysqld restart

データベース作成

# mogdbsetup --dbuser=mogile --dbpass=mogpass --yes

データベースを確認

# mysql -u mogile -p

mysql> show databases;
                                          • +
Database
                                          • +
information_schema
mogilefs
test
                                          • +
mysql> use mogilefs; mysql> show tables;
                                              • +
Tables_in_mogilefs
                                              • +
class
device
domain
file
file_on
file_on_corrupt
file_to_delete
file_to_delete2
file_to_delete_later
file_to_queue
file_to_replicate
fsck_log
host
server_settings
tempfile
unreachable_fids
                                              • +
16 rows in set (0.00 sec)

mogilefsというデータベースが出来てます。次はmogilefsdを起動させます。これがtrackerとなるデーモンですね。rootでは実行できないそうなので専用ユーザを作って実行します。

useradd -s /bin/false mogile

デーモンの設定ファイルを作ります。設定ファイルは先程のsixapartの方の設定をそのまま使わせてもらいました。

# mkdir /etc/mogilefs
# vi /etc/mogilefs/mogilefsd.conf

## デーモンとして実行する
daemonize = 1
## DB接続先. ユーザー, パスワード
db_dsn = DBI:mysql:mogilefs:host=127.0.0.1
db_user = mogile
db_pass = mogpass
## mogilefsd が client からの要求を受け付けるポート番号
conf_port = 7001
## client からの要求を処理するプロセスの数
listener_jobs = 10

ということで準備が出来たので起動です。無事起動できるっぽいです。

# sudo -u mogile mogilefsd
# ps auxww | grep mogilefsd
mogile   17685  0.7  4.3  20440 11488 ?        S    16:21   0:00 mogilefsd
mogile   17686  0.0  4.4  20440 11728 ?        S    16:21   0:00 mogilefsd [replicate]
mogile   17687  0.0  4.4  20440 11556 ?        S    16:21   0:00 mogilefsd [delete]
mogile   17688  0.0  4.1  20440 10840 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17689  0.0  4.1  20440 10840 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17690  0.0  4.1  20440 10840 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17691  0.0  4.1  20440 10840 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17692  0.0  4.1  20440 10840 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17693  0.0  4.1  20440 10852 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17694  0.0  4.1  20440 10852 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17695  0.0  4.1  20440 10856 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17696  0.0  4.1  20440 10856 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17697  0.0  4.1  20440 10856 ?        S    16:21   0:00 mogilefsd [queryworker]
mogile   17698  0.0  4.4  20440 11700 ?        S    16:21   0:00 mogilefsd [monitor]
mogile   17699  0.1  4.4  20440 11648 ?        S    16:21   0:00 mogilefsd [reaper]
mogile   17700  0.0  4.4  20440 11660 ?        S    16:21   0:00 mogilefsd [job_master]
mogile   17701  0.0  4.3  20440 11460 ?        SN   16:21   0:00 mogilefsd [fsck]
root     17708  0.0  0.2   3924   684 xvc0     R+   16:21   0:00 grep mogilefsd

同様にmofilefsをコントロールするためのユーティリティコマンド(mogadm,mogtool)をインストールします。

$ cd trunk/utils
$ perl Makefile.PL
$ make
$ su
# make install

mogstored構築

インストール手順はtrackerと同じです。ということでmogstoredの設定をしていきます。設定ファイルは/etc/mogilefs/mogstored.confになる模様。mogstored1に構築していきます。

# xm console mogstored1
# mkdir /etc/mogilefs
# vi /etc/mogilefs/mogstored.conf

## HTTP リクエストを待ち受け付ける IP・ポート
httplisten = 0.0.0.0:7500
## Perlbal 管理用リクエストを受け付ける IP・ポート
mgmtlisten = 0.0.0.0:7501
## Apache の設定で言うところの DocumentRoot
docroot = /var/mogdata

docrootで指定した/var/mogdataにファイルが保存されるんですかね。ディレクトリを作成しておきます。

# mkdir -p /var/mogdata/dev1
※ mogstotred2では /var/mogdata/dev2 を作成する

起動します。こちらはrootで起動する模様。

# sudo mogstored -d

起動確認

# ps auxww | grep mogstore

avahi     1683  0.0  0.5   2604  1340 ?        Ss   22:54   0:00 avahi-daemon: running [mogstored1.local]
root      1761  0.4  3.8  14444 10148 ?        S    22:56   0:00 mogstored
root      1762  0.0  0.7   6120  2032 ?        S    22:56   0:00 mogstored [diskusage]
root      1763  0.0  0.8   6120  2108 ?        S    22:56   0:00 mogstored [iostat]
root      1765  0.8  1.5   7920  4072 ?        S    22:56   0:00 mogstored [fidsizes]

mogstored2でも同様のことを行います。

trackersへmogstoredを登録

trackersにファイルを保存するサーバmogstored[12]を登録します。登録には以下をtrackersホスト上で行えば良いみたいです。

ドメインmogilefs上でのグループで、クラスはコピーする数(3台のホストにコピーする〜)などを管理するもののようです。ホストはmogstored自体。デバイスは各ホストごとに割り当てられるデバイス番号の用でホスト間で重複してはいけないようです。

ホストの追加

# mogadm --trackers="192.168.0.191:7001" host add mogstored1 --ip=192.168.0.192 --port=7500
# mogadm --trackers="192.168.0.191:7001" host add mogstored2 --ip=192.168.0.193 --port=7500

追加ホストの確認

# mogadm --trackers="192.168.0.191:7001" host list

mogstored1 [1]: down
  IP:       192.168.0.192:7500

mogstored2 [2]: down
  IP:       192.168.0.193:7500

ステータスがdownになっています。これはコマンドを使ってaliveにリマークすることによって起動状態にできるみたいです。要はtrackers上でコピー先として使えるかどうか制御できるんだと思います。

バイスの追加

#  mogadm --trackers="192.168.0.191:7001" device add mogstored1 1
#  mogadm --trackers="192.168.0.191:7001" device add mogstored2 2

最後の数字がデバイスidです。これがmostored[12]を作成した時に作ったディレクトリ /var/mogdata/dev? の?にあたる数字になるんですかね。

バイスの確認

# mogadm --trackers="192.168.0.191:7001" device list
mogstored1 [1]: down
                   used(G) free(G) total(G)
  dev1: down       0.000   0.000   0.000  

mogstored2 [2]: down
                   used(G) free(G) total(G)
  dev2: down       0.000   0.000   0.000

ここもステータスがdownになっています。

ドメインの追加

# mogadm --trackers="192.168.0.191:7001" domain add mydomain

クラスの追加

# mogadm --trackers="192.168.0.191:7001" class add mydomain myclass

ドメイン確認

# mogadm --trackers="192.168.0.191:7001" domain list

  domain               class                mindevcount
 -------------------- -------------------- -------------
  mydomain             default                   2
  mydomain             myclass                   2

mindevcountがコピーするデータの数を表しているみたいです。

ステータスをaliveに変更

# mogadm --trackers="192.168.0.191:7001" device mark mogstored1 1 alive
# mogadm --trackers="192.168.0.191:7001" device mark mogstored2 2 alive
# mogadm --trackers="192.168.0.191:7001" host mark mogstored1 alive
# mogadm --trackers="192.168.0.191:7001" host mark mogstored2 alive

ホストのステータスを確認(aliveになってるか)

# mogadm --trackers="192.168.0.191:7001" host list

mogstored1 [1]: alive
  IP:       192.168.0.192:7500

mogstored2 [2]: alive
  IP:       192.168.0.193:7500

バイスのステータスの確認(aliveになってるか)

# mogadm --trackers="192.168.0.191:7001" device list
mogstored1 [1]: alive
                   used(G) free(G) total(G)
  dev1: alive      0.000   0.000   0.000  

mogstored2 [2]: alive
                   used(G) free(G) total(G)
  dev2: alive      0.000   0.000   0.000

全体的なチェック、ちなみにmogstoredの方で7500を開けてないとRefuseがでます。(今回はとりあえずiptablesをとめました)

# mogadm --trackers="192.168.0.191:7001" check

Checking trackers...
  192.168.0.191:7001 ... OK

Checking hosts...
  [ 1] mogstored1 ... OK
  [ 2] mogstored2 ... OK

Checking devices...
  host device         size(G)    used(G)    free(G)   use%   ob state   I/O%
  ---- ------------ ---------- ---------- ---------- ------ ---------- -----
  [ 1] dev1             7.114      1.569      5.544  22.06%  writeable   0.0
  [ 2] dev2             7.114      1.569      5.544  22.06%  writeable   0.0
  ---- ------------ ---------- ---------- ---------- ------
             total:    14.227      3.139     11.089  22.06%

よさそう。ということで、まずはtrackers->mogstored1にtelnetで接続してファイルが置けるか単体テストしてみます。

# telnet 192.168.0.192 7500
Trying 192.168.0.192...
Connected to 192.168.0.192 (192.168.0.192).
Escape character is '^]'.
PUT /dev1/test HTTP/1.0
Content-length:4

test
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 18
Server: Perlbal
Connection: close

<h1>200 - OK</h1>
Connection closed by foreign host.

これでmogstored1の/var/mogdata/dev1の中をみるとtestというファイルができていました。ちゃんと動いてそうですね。続いてPerlAPIを触る前にmogtoolコマンドでファイルの保存が試せるみたいなので試しました。test2.txtというファイルを作成してtest2という名前でmogstored[12]に保存します。

# echo test2 > /var/tmp/test2.txt
# mogtool --trackers="192.168.0.191:7001" --domain=mydomain --class=myclass inject /var/tmp/test2.txt test2
file test2: 126a8a51b9d1bbd07fddc65819a542c3, len = 6
Spawned child 16901 to deal with chunk number 1.
        chunk 1 saved in 0.17 seconds.
Child 16901 successfully finished with chunk 1.
Replicating: 1

1つファイルをレプリケートしたと出てるのでよさそうですね。保存したファイルは以下のような形で保存されてました。名前が機械的ですが、たぶんこの辺のリレーションはmysqlに保存されているんでしょうね。

#mogstored1
/var/mogdata/dev1/0/000/000/0000000001.fid 

#mogstored2
/var/mogdata/dev2/0/000/000/0000000001.fid

とりあえず動作確認はできたので次はPerlのクライアント使うなりなんなりしてみようかと思います。エントリも結構長くなったし....。