MogileFS を Ruby の mogilefs-client から触ってみた
日野原です。
今回はこの前に引き続いて 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 が使えるようにしてくれることでしょう。
楽しみですね。
