2008-06-30

MogileFS を Ruby の mogilefs-client から触ってみた

はてなブックマーク   livedoor clip

日野原です。

今回はこの前に引き続いて MogileFS の話題です。

前回の最後に唐突に ruby から触ると言う話をした通り ruby のクライアントライブラリから MogileFS を操作してみましょう。

まず環境ですが、前回と同じ Fedora7 on coLinux です。
その上に、ruby と rubygems をインストールしておきます。

% sudo yum install ruby ruby-ri ruby-rdoc ruby-libs\
  ruby-irb ruby-devel rubygems

次に MogileFS のクライアントを gem でインストールします。

% sudo gem install mogilefs-client

ではこれで ruby のプログラムから触ってみましょう。
まずは下準備です。

% irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'mogilefs'
=> true

次に domain と class を作成します。(結果は見やすいように改行しています)

irb(main):003:0> mogadm = MogileFS::Admin.new :hosts => ["127.0.0.1:7001"]
=> #<MogileFS::Admin:0xb7649c10
              @readonly=false,
              @backend=#<MogileFS::Backend:0xb7649bc0
                                   @mutex=#<Mutex:0xb7649b70>,
                                   @lasterrstr=nil,
                                   @lasterr=nil,
                                   @hosts=["127.0.0.1:7001"],
                                   @socket=nil,
                                   @timeout=3,
                                   @dead={}>,
              @hosts=["127.0.0.1:7001"],
              @timeout=nil>
irb(main):004:0> mogadm.create_domain "hoge"
=> "hoge"
irb(main):005:0> mogadm.create_class "hoge", "important", 3
=> "important"
irb(main):006:0> mogadm.create_class "hoge", "normal", 2
=> "normal"

これでファイルを保存する準備が整いました。
ここで作った domain とは、保存するファイルのまとまりを表すもので、ファイルは必ず domain に属します。蓄積されているファイルを取得するときには、この domain と key の対を指定します。
key とはファイルごとに一意に定める値です。domain をまたがって key を一意にする必要があるかどうかはまだ調べていないので、興味のある方は自分で調べてみてください。
class はファイルの持つ属性で、class ごとにいくつのコピーを保持しておくかを指定することができます。ここでは、important というクラスを持つファイルは 3つのコピーを、normal クラスのファイルは 2つのコピーを保持しておくように指定しました。

では実際にファイルを保存してみましょう。
irb を起動したカレントディレクトリに test.jpg という JPEG 画像と、「Hello, world!」と書かれている ttt というテキストファイルを置いておきます。(結果は見やすいように改行しています)

irb(main):007:0> mog = MogileFS::MogileFS.new :hosts => ["127.0.0.1:7001"], :domain => "hoge"
=> #<MogileFS::MogileFS:0xb76328a8
                @readonly=false,
                @root=nil,
                @backend=#<MogileFS::Backend:0xb7632844
                              @mutex=#<Mutex:0xb76327f4>,
                              @lasterrstr=nil,
                              @lasterr=nil,
                              @hosts=["127.0.0.1:7001"],
                              @socket=nil,
                              @timeout=3,
                              @dead={}>,
                @hosts=["127.0.0.1:7001"],
                @domain="hoge",
                @timeout=nil>
irb(main):008:0> mog.store_file "testimage001", "normal", File.new("test.jpg")
=> 1441195
irb(main):009:0> mog.store_file "testtext001", "important", File.new("ttt")
=> 14
irb(main):010:0> mog.store_file "testtext002", "important", "ttt"
=> 14

store_file の引数は一つ目から順に key, class, ファイルです。
ファイルの指定は File オブジェクトでもファイル名でもいいらしいです。
また、store_content を使えば

irb(main):011:0> mog.store_content "testtext003", "normal", "I'm hungry..."
=> 13

のように文字列を直接保存することもできます。

ちなみに、これらのファイルは /etc/mogilefs/mogstored.conf の中で指定した docroot 以下に保存されています。
実際にちょっと見てみましょう。

% ls -l /var/mogdata/dev1/0/000/000/
合計 1420
-rw-r--r-- 1 root root 1441195 2008-06-26 21:23 0000000002.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:24 0000000003.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:25 0000000004.fid
% ls -l /var/mogdata/dev2/0/000/000/
合計 1424
-rw-r--r-- 1 root root 1441195 2008-06-26 21:23 0000000002.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:24 0000000003.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:25 0000000004.fid
-rw-r--r-- 1 root root      13 2008-06-26 21:28 0000000005.fid
% ls -l /var/mogdata/dev3/0/000/000/
合計 12
-rw-r--r-- 1 root root 14 2008-06-26 21:24 0000000003.fid
-rw-r--r-- 1 root root 14 2008-06-26 21:25 0000000004.fid
-rw-r--r-- 1 root root 13 2008-06-26 21:28 0000000005.fid
% file /var/mogdata/dev1/0/000/000/0000000002.fid
0000000002.fid: JPEG image data, EXIF standard
% cat /var/mogdata/dev1/0/000/000/0000000003.fid
Hello, world!
% cat /var/mogdata/dev3/0/000/000/0000000005.fid
I'm hungry...

ファイルサイズで判断すると、ちゃんとimportant で指定したファイルが 3つずつ、normal で指定したファイルが 2つずつ生成されていますね。
このファイル名は環境によっては異なってくるかもしれないので、バイナリファイルを cat してしまわないように気をつけてください。

ファイルを読み込むときは get_file_data に key を指定します。

irb(main):012:0> mog.get_file_data "testtext003"
=> "I'm hungry..."
irb(main):013:0> mog.get_file_data "testtext002"
=> "Hello, world!\n"

また、MogileFS::Admin を使ってデバイスや保存されているファイルの情報を取得することもできます。(結果は見やすいように改行しています)

irb(main):037:0> mogadm.get_stats
=> {"fids"=>{"max"=>5, "count"=>0},
    "device"=>[{"status"=>"alive", "files"=>"3",
                "id"=>"1", "host"=>"localhost"},
               {"status"=>"alive", "files"=>"4",
                "id"=>"2", "host"=>"localhost"},
               {"status"=>"alive", "files"=>"3",
                "id"=>"3", "host"=>"localhost"}],
    "replication"=>[{"files"=>"2", "class"=>"important",
                     "devcount"=>"3", "domain"=>"hoge"},
                    {"files"=>"2", "class"=>"normal",
                     "domain"=>"hoge", "devcount"=>"2"}],
    "file"=>[{"files"=>"2", "class"=>"important", "domain"=>"hoge"},
             {"files"=>"2", "class"=>"normal", "domain"=>"hoge"}]}

さて、これで最低限の読み書きはできました。
これだけできればきっと誰かが rails のファイルアップロードプラグイン(attachment_fuとか?)のバックエンドに MogileFS が使えるようにしてくれることでしょう。
楽しみですね。

2008-06-19

CouchDB について Erlang 分散システム勉強会で紹介してきました

はてなブックマーク   livedoor clip

先日、Erlang分散システム勉強会で、最近私が追っている CouchDB というオープンソースのドキュメント指向分散データベースについて紹介してきました。発表資料をおいておきます。

ドキュメント指向データベース CouchDB(PDF)

分散システムでしかも Erlang というニッチっぽい勉強会でしたが、30人の参加者が一瞬で集まり、非常に熱い会でした。私も自分の好きな話を好きなように話してしまい、参加者のみなさんはドン引きだったかもしれません…

これだけでは何なので、ついでに手元の Fedora7 on coLinux に CouchDB の trunk を入れたときの手順と、簡単な couchdb の使い方をご紹介しておきます。

基本的にはオフィシャルwikiにあるとおり、yum でモジュールを入れていけば問題ありません。素の coLinux からの場合、以下のモジュールが必要でした。

sudo yum install automake gcc libtool erlang \
  help2man icu libicu-devel js js-devel

次に svn から最新の trunk を取ってきます。

svn co http://svn.apache.org/repos/asf/incubator/couchdb/trunk couchdb

普通にコンパイルします。最初に ./bootstrap が必要です。

cd couchdb; ./bootstrap; ./configure; make

ちゃんとコンパイルできたら、あとはインストールするだけです。

sudo make install

オフィシャルの説明では couchdb ユーザを作って /usr/local/etc/couchdb/couch.ini を編集するようになっていますが、いろいろいじるときは自分のアカウントで動かした方が楽です。

cd ~mkdir couchdbcd couchdb
mkdir databases
cp /usr/local/etc/couchdb/couch.ini .
vi couch.ini

/usr/local/etc/couchdb/couch.ini が雛形なので、それをコピーし、

  • データベースファイル(.couch)を格納するディレクトリ(DbRootDir)
  • 他のマシンからアクセスするためのIPアドレス(BindAddress)
  • ログファイルの位置(LogFile)
  • ログレベル(LogLevel)

を書きかえます。ログレベルは debug にしておく方が、いろいろ情報が出てわかりやすくなります。

; etc/couchdb/couch.ini.tpl.  Generated from couch.ini.tpl.in by configure.

[Couch]

ConsoleStartupMsg=Apache CouchDB is starting.

DbRootDir=/home/yohei/couchdb/databases

Port=5984

BindAddress=192.168.0.2

DocumentRoot=/usr/local/share/couchdb/www

LogFile=/home/yohei/couchdb/couch.log

UtilDriverDir=/usr/local/lib/couchdb/erlang/lib/couch-0.8.0-incubating/priv/lib

LogLevel=debug

[Couch Query Servers]

javascript=/usr/local/bin/couchjs /usr/local/share/couchdb/server/main.js

あとは -c オプションで設定ファイルを指定して couchdb を起動するだけです。

% /usr/local/bin/couchdb -c couch.ini
Apache CouchDB 0.8.0-incubating (LogLevel=debug)
Apache CouchDB is starting.

Apache CouchDB has started. Time to relax.
[debug] [<0.1.0>] Config Info /home/yohei/couchdb/couch.ini:
        CurrentWorkingDir=/home/yohei/couchdb
        DbRootDir=/home/yohei/couchdb/databases
        BindAddress="192.168.0.2"
        Port="5984"
        DocumentRoot=/usr/local/share/couchdb/www
        LogFile=/home/yohei/couchdb/couch.log
        UtilDriverDir=/usr/local/lib/couchdb/erlang/lib/couch-0.8.0-incubating/priv/lib
        DbUpdateNotificationProcesses=
        FullTextSearchQueryServer=
        javascript=/usr/local/bin/couchjs /usr/local/share/couchdb/server/main.js

このようなログが流れれば起動は成功です。

curl でアクセスしてみましょう(curl が入っていない場合は yum で入れてください)。

colinux% curl -v http://192.168.0.2:5984
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Date: Thu, 19 Jun 2008 05:42:35 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 50
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"couchdb":"Welcome","version":"0.8.0-incubating"}

ルートにアクセスすると Welcome メッセージとバージョン番号が入った JSON ドキュメントが取得できます。

データベースは PUT で作成できるので、PUT /test というリクエストを送ってみます。

colinux% curl -v -X PUT http://192.168.0.2:5984/test
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> PUT /test HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
>
< HTTP/1.1 201 Created
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Date: Thu, 19 Jun 2008 05:44:58 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 11
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"ok":true}

ちゃんと 201 Created が返ってきましたね。今度は ドキュメントを追加してみます。ドキュメントの名前(id)がURIに入るので、PUTでドキュメントを作成できます。

colinux% curl -v -X PUT -H "Content-Type: application/json" \
--data "{\"hoge\": \"fuga\"}" http://192.168.0.2:5984/test/testdoc
* About to connect() to 192.168.0.2 port 5984 (#0)
*   Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> PUT /test/testdoc HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
< HTTP/1.1 201 Created
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Etag: "1623090219"
< Date: Thu, 19 Jun 2008 05:55:33 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 45
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"ok":true,"id":"testdoc","rev":"1623090219"}

ドキュメントの追加はデータベースURIへの POST でもできます。この場合はドキュメント名を指定する必要はありません。サーバ側で適当な名前を付けてくれます。

colinux% curl -v -X POST -H "Content-Type: application/json" \
--data "{\"hoge\": \"piyo\"}" http://192.168.0.2:5984/test;
* About to connect() to 192.168.0.2 port 5984 (#0)
*   Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> POST /test HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
< HTTP/1.1 201 Created
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Date: Thu, 19 Jun 2008 05:57:47 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 70
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"ok":true,"id":"2366ffde9e795d8e9c9047f1303cfbcd","rev":"4244254602"}

POST の場合は Location ヘッダが返ってきた方がいいような気もしますが、ありませんね。今ソースを確認したところ、POST の場合でも Location を返さないようです。couchdbのバグっぽいですね。

ドキュメントができたらやっと GET できます。これは簡単です。

colinux% curl -v -X GET http://192.168.0.2:5984/test/testdoc
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> GET /test/testdoc HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Etag: "1623090219"
< Date: Thu, 19 Jun 2008 06:10:04 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 51
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"_id":"testdoc","_rev":"1623090219","hoge":"fuga"}

レスポンスの Content-Type が text/plain なのがちょっと気に入りませんが、これはリクエストの Accept ヘッダに application/json がない場合は text/plain を返すように couchdb が実装されているからです。ブラウザなんかで見るときは、text/plain の方がなにかとありがたいからでしょう。Accept ヘッダを付けた場合の例も示しておきます。

colinux% curl -v -X GET -H "Accept: application/json" http://192.168.0.2:5984/test/testdoc
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> GET /test/testdoc HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: application/json
>
< HTTP/1.1 200 OK
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Etag: "1623090219"
< Date: Thu, 19 Jun 2008 06:11:48 GMT
< Content-Type: application/json
< Content-Length: 51
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"_id":"testdoc","_rev":"1623090219","hoge":"fuga"}

こんな感じで、curl のような HTTP クライアントがあれば、すぐに CouchDB で遊んでみることができます。各言語用のライブラリもいろいろ出てきていますので、それを使うのもいいでしょう。HTTP ライブラリさえあれば、ラッパーを作るのは簡単なのでぜひお試しください。

2008-06-13

MogileFS を Feodra7 on coLinux に yum で入れてみた

はてなブックマーク   livedoor clip

日野原です。

今、分散ファイルシステムが熱いです。負荷分散とか冗長化とかを考えていると、当然ファイルシステムも分散させたくなるのです。…なりますよね?

というわけで手元の Fedora7 on coLinux に分散ファイルシステムの一つの実装である MogileFS を入れてみました。

ただ、CPAN を使える人向けの情報はこのページ(Six Apart – Tech Talk Blog: MogileFS のインストールと初期設定)にすでにあるので、今回は perl をちゃんと使ったことがなくてもできるやり方でインストールしてみました。正確に言うと私が CPAN を使って入れようとしてできなかったので回避しただけなんですけど…

というわけでインストールの手順は独自ですが、その後の初期設定などは前述のページで説明されているやり方とほとんど同じです。

前提となる環境は Fedora7 (coLinux) で yum と vi と svn、make が使える状態です。

まず、必要とされているパッケージをインストールします。先ほども言ったように CPAN は使わずに yum でインストールします。とある CPAN Author に言わせると「yum で perl のモジュールを入れる感覚が受け付けない」そうですが、私は perl はまともに使ったことがないので違和感なしです。まぁ、私も yum で ActiveRecord とかをインストールされるとしょんぼりするので同じようなものなのでしょう。

% sudo yum install perl-Net-Netmask perl-Danga-Socket perl-IO-AIO \
Perlbal mysql-server

次に MogileFS も yum で提供されているので入れてしまいます。
そういえば、上で入れた yum は MogileFS を入れるときに依存関係で勝手に入ったかもしれないですね…

% sudo yum install perl-MogileFS-Client perl-MogileFS-Utils

で、これだけだとMogileFSのリポジトリのサブディレクトリの api と utilities に相当する部分しか入らないので、server の部分は自分でコンパイルします。

% svn co http://code.sixapart.com/svn/mogilefs/trunk mogilefs
% cd mogilefs/server
% perl Makefile.PL

ここで ExtUtils/MakeMaker.pm がないと言われるので入れます。

% sudo yum install perl-ExtUtils-MakeMaker
% perl Makefile.PL
Checking if your kit is complete...
Looks good
Warning: prerequisite Gearman::Client 1.07 not found.
Warning: prerequisite Gearman::Client::Async 0.93 not found.
Warning: prerequisite Gearman::Server 1.08 not found.
Writing Makefile for mogilefs-server

問題ないらしいですが、せっかくなのであった方がいいと言われている(らしい) Gearman も入れてしまいましょう。

% sudo yum install perl-Gearman perl-Gearman-Client-Async \
perl-Gearman-Server
% perl Makefile.PL
Writing Makefile for mogilefs-server

問題なさそうです。これでインストールしてしまいます。

% make
% sudo make install

これでインストールは完了です。ここから初期設定に入ります。

まずは mysql の起動とパスワードの設定

% sudo /etc/init.d/mysqld start
% mysqladmin -u root password 'rootpass'

次に MogileFS の DB スキーマを作成します。

% mogdbsetup --dbrootpass=rootpass --dbpass=mogpass

いろいろ聞かれても yes でいいです。面倒なら –yes オプションをつけるといいらしい。

ここ以降は前述のページの説明とほとんど一緒ですが、一応書いておきます。

ここからは tracker の設定です。
まずは mogilefsd 用のユーザを作ります。

% sudo /usr/sbin/useradd -s /sbin/nologin mogile

次に設定ファイルを。

% sudo mkdir /etc/mogilefs
% sudo cp conf/mogilefsd.conf /etc/mogilefs
% sudo vim /etc/mogilefs/mogilefsd.conf

変更点は daemonize の行のコメント解除と db_user、db_pass の設定です。

daemonize = 1
db_dsn = DBI:mysql:mogilefs:host=127.0.0.1
db_user = mogile
db_pass = mogpass
listen = 127.0.0.1:7001
conf_port = 7001
listener_jobs = 10
delete_jobs = 1
replicate_jobs = 5
mog_root = /mnt/mogilefs
reaper_jobs = 1

で、mogilefsd を起動します。

% sudo -u mogile mogilefsd

次は mogstored です。

リポジトリに入っていた mogstored の config ファイルは古い形式らしくて使えないので、新しく作成します。内容は3行だけです。

% cat /etc/mogilefs/mogstored.conf
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /var/mogdata

で、docroot に指定したディレクトリを作成し、起動します。

% sudo mkdir /var/mogdata
% sudo mogstored -d

後は件のサイトの説明に従い使えるようにしていきます。

% mogadm host add localhost --port=7500
% sudo mkdir /var/mogdata/dev1
% sudo mkdir /var/mogdata/dev2
% sudo mkdir /var/mogdata/dev3
% mogadm device add localhost 1
% mogadm device add localhost 2
% mogadm device add localhost 3
% mogadm host mark localhost alive
% mogadm check
Checking trackers...
127.0.0.1:7001 ... OK

Checking hosts...
[ 1] localhost ... OK

Checking devices...
host device         size(G)    used(G)    free(G)   use%   ob state   I/O%
---- ------------ ---------- ---------- ---------- ------ ---------- -----
[ 1] dev1             3.777      1.257      2.520  33.28%  writeable   0.0
[ 1] dev2             3.777      1.257      2.520  33.28%  writeable   0.0
[ 1] dev3             3.777      1.257      2.520  33.28%  writeable   0.0
---- ------------ ---------- ---------- ---------- ------
total:    11.331      3.771      7.559  33.28%

ここまでで、とうとう ruby の mogilefs-client からさわれるようになりました。

しかし長くなってしまったので、ruby からさわるのは次回にします。
お楽しみに。

補足として、別の環境でやってはまったときの解決策も書いておきます。

mogstored を実行したときに

Weak references are not implemented in the version of perl …

というエラーが出てしまった場合、Scalar::Util を入れ直すと直ります。perl 使いの間では有名なエラーだそうです。

あと、MySQL を独自にビルドしていて socket の位置が異なる場合、
/usr/lib/perl5/site_perl/5.8.8/MogileFS/Store/MySQL.pm
の15行目(私の環境のパスです)を

return "DBI:mysql:$dbname;host=$host;mysql_socket=/tmp/mysql.sock"
               . ($port ? ";port=$port" : "");

と書き換えれば(/tmp/mysql.sockの部分はsocketの位置にしてください)とりあえず動きます。けど本当にとりあえずなのでオススメしません。自分しか困らない開発環境でだけやってください。

2008-06-06

仮想化の使い道

はてなブックマーク   livedoor clip

日野原です。

最近いろいろなところで仮想化と言う言葉を聞くようになってきました。
私も開発環境ではいろいろなところで仮想化技術のお世話になっていますが、ricollab のような場所では仮想化技術は役立つのでしょうか。

よく耳にする仮想化技術の導入事例のほとんどは、「たくさんあるレガシーなサーバを仮想化技術を使うことで集約し、コストを削減した」と言うものです。しかしこれではこれから Web 上のサービスとやっていこうという我々の心には届きません。

ではどういう使い方だとうれしいでしょうか。

まず、開発環境としての使い方では、Windows マシン上で VMWare や coLinux を使って開発している人は多いと思います。

また、実験環境を作るときには仮想マシンが活躍します。
我々の例でいうと、実運用環境は DB やアプリ、ロードバランサなど何台ものサーバで構成されているのですが、社内ネットワークにある実験環境では同じ台数のサーバを準備するのはもったいないので xen を使って2台のマシンで同等の環境を構成しています。当然一台あたりに割り当てられるメモリや CPU の資源は少なくなるのでパフォーマンステストなどはできませんが、一台が停止してもサービス全体は止めないとか、アプリケーションのデプロイのテストなどはこの環境で十分です。

それでは、実運用環境ではどうでしょう。

まず一つ、実サーバを用意せずに Amazon EC2 を利用すると仮想化技術の恩恵にあずかることになりますね。
ただ、これでは「自分で仮想化している!」という実感がわきません。私だけ?
今後は必要になってくることだとは思っていますが、今のところはちょっとおいておきます。

次に考えたのは、実サーバ上には仮想マシンのホストとなる最低限の環境だけ用意し、アプリや DB と言った役割のサーバはすべて仮想マシンで提供するといった形態です。そして、故障対策として予備機を仮想マシンのホストだけインストールした状態で置いておきます。

これだと、一台のサーバが壊れて代替機を準備するとき、空いている予備機にイメージをコピーするだけでいいと言うメリットがあります。
でもこれは kickstart などの設定をちゃんとしてインストールを自動化おけばたいして変わらないですね。それにその方が仮想化によるパフォーマンスの劣化も気にしなくていいのでわざわざ仮想化するメリットがあまり感じられません。

では仮想マシンのイメージを実サーバに2つ以上おけるサイズにしておいて、一台が壊れたときに同じ役割のイメージを他の稼働しているサーバ上で動かすようにすればどうでしょう。

これならば予備機をもし切らしている場合でも代わりが作れるし、よさそうですね。ただ、たとえば一つの実サーバ上に DB サーバ用の仮想マシンが2台載ってしまうと HDD アクセスなどが大変なことになりそうなので、CPU を主に使うアプリサーバとメモリとディスク容量を主に使う DB サーバを一緒にするなど、載せるイメージをうまく配分する必要はありそうです。

などといろいろ考えて楽しんでいるのですが、実はそんなことよりも先に ricollab の単一故障点をなくさないといけないのです…