PerlでAmazon S3の操作をする方法
今日はPerlとS3についてです。
EC2上で稼働しているベターホームレシピ(http://bhmb.jp/)では
サーバ側の細かい運用ツールにPerlを使っているケースが多いです。
また、静的コンテンツの公開やログデータのバックアップなどには
Amazon S3を使っています。
s3syncなどS3を使うツールはありますが、プログラム経由で操作したい
ケースもそれなりにあり、Perlのモジュールを使ってAPI経由で
S3を操作し、各種運用をしています。その方法について簡単に紹介します。
[モジュールの選定]
PerlでS3を使うには
・Net::Amazon::S3
・Amazon::S3
あたりのモジュールが代表的なようです。この2つで検討しました。
Net::Amazon::S3の方がドキュメント、機能、パフォーマンスはよさそうすが、
「依存モジュールが少ないこと。インストールしやすいこと。」
を重視したいので、Amazon::S3の方が私たちのケースではよさそうでした。
Net::Amazon::S3はAmazon::S3の3倍くらい依存モジュールがあり、XML::LibXMLやMooseなど
ブツブツいうほどでもないですが、ちょっとインストールが面倒なケースがあったり、重量級モジュール
だったり、と「お手軽感」という点では少しマイナスかな、と思いました。
ドキュメントみたら、やっぱりNet::Amazon::S3よりポータブルにするという思想があるみたいですね。
http://search.cpan.org/~tima/Amazon-S3-0.45/lib/Amazon/S3.pm
XML::LibXMLを使わないなどパフォーマンス面は少し劣るようですが、「ポータブルな実装」っていうのは
Goodです。パフォーマンスはとりあえず、気にしないことにしました。
ただ、Amazon::S3はちょいとドキュメントがゆるいというのが欠点はあります・・・。
まあ、中身を読んだりすれば何とかなるだろう、ということで、
よしあしはありますが、私のケースではAmazon::S3に決定して、
ベターホームレシピではPerlでS3の操作をしています。
では、簡単ですが、使い方サンプルを。
[インストール]
最近はもっぱらcpanminusでモジュールインストールです。
cpanm Amazon::S3
とかでOKです。
以下あたりを参考にすると、cpanminusの簡単な使い方が書いてあります。
http://www.omakase.org/perl/cpanm.html
[S3への接続]
まず、接続編。以下のようにAmazon::S3クラスのコンストラクタを
アクセスキー、秘密キーを指定して呼び出せば、S3を操作するオブジェクトを
取得できます。
#!/usr/bin/perl
use strict;
use warnings;
use Amazon::S3;
# S3のアクセスキーの指定
my $aws_access_key_id = 'それぞれの環境ごとに指定してください。';
# S3の秘密キーの指定
my $aws_secret_access_key = 'それぞれの環境ごとに指定してください。';
my $s3 = Amazon::S3->new(
{
aws_access_key_id => $aws_access_key_id,
aws_secret_access_key => $aws_secret_access_key
}
);
my $res = $s3->buckets;
# 成功していればownwer_idなどが取得できます
print $res->{owner_id} . "\n";
print $res->{owner_displayname} . "\n";
[S3のバケット一覧の取得]
ドキュメントに記載されていないように見えましたが、
取得したS3オブジェクトを使ってバケット名一覧を取得できるみたいです。
my @buckets = @{$s3->buckets->{buckets}};
for my $bucket ( @buckets ) {
print $bucket->bucket . "\n";
}
[S3のバケット作成]
これはドキュメントにサンプルがあるとおりですが、バケット作成は
こんな感じみたいです。バケット名を指定すればOKですね。
my $new_buekct = $s3->add_bucket( { bucket => 'flect_test_buekct' } )
or die $s3->err . ": " . $s3->errstr;
[S3へのデータのアップロード]
データをアップロードするだけならば、サンプルにもあるとおり
以下のような感じです。
# バケットオブジェクト( Amazon::S3::Bucketのオブジェクト )を取得
my $bucket = $s3->bucket('flect_test_buekct');
# キーを指定
my $keyname = 'test.txt';
# 値を指定
my $value = 'T';
$bucket->add_key(
$keyname,
$value,
{
content_type => 'text/plain' # コンテンツタイプなど設定を指定
}
);
ローカルディスクにあるファイルを指定してアップする場合は以下のように
add_key_filenameを使います。
my $filepath = './testfile.txt';
$bucket->add_key_filename( 'testfile.txt', $filepath )
or die $s3->err . ':' . $s3->errstr;
ファイル指定してアップロードというユースケースもけっこうあるので
よく使います。
[S3の指定したバケット内のキーリストを取得]
ファイルをアップしたりすれば、当然取得したくなります。
これもサンプルどおりですが、一応書いておきます。
# バケットオブジェクト( Amazon::S3::Bucketのオブジェクト )を取得
my $bucket = $s3->bucket('flect_test_buekct');
# キーリストを取得。
my $res = $bucket->list
or die $s3->err . ": " . $s3->errstr;
# キーリストを表示
for my $key (@{ $res->{keys} }) {
print $key->{key} . "\n";
}
[S3のバケット内に指定したキーが存在するかの確認]
既に同一キーでオブジェクトがアップされていないか、など確認したくなる
ケースがあります。そんな場合は以下のような感じで。
# バケットオブジェクト( Amazon::S3::Bucketのオブジェクト )を取得
my $bucket = $s3->bucket('flect_test_buekct');
# head_keyでキーの存在確認ができます。
if ( $bucket->head_key("testfile.txt") ) {
print "key is found\n";
} else {
print "key is not found\n";
}
[S3からデータのダウンロード]
S3に退避しておいて、別の場所でダウンロードしたい、なんてことありますよね。
ベターホームレシピではログファイルをEC2からS3にアップし、社内のデータ解析用サーバに
ダウンロードしていろいろ処理しています。
データをダウンロードし、その値をPerl内でごにょごにょ処理したい場合は
以下のように。
# バケットオブジェクト( Amazon::S3::Bucketのオブジェクト )を取得
my $bucket = $s3->bucket('flect_test_buekct');
# キーを指定してPerlの変数に取得。
my $data = $bucket->get_key('testfile.txt');
# 値を表示。valueを指定。
print $data->{value} . "\n";
データをローカルのファイルシステムに保存したい場合は以下のように。
# バケットオブジェクト( Amazon::S3::Bucketのオブジェクト )を取得
my $bucket = $s3->bucket('flect_test_buekct');
# 最後の引数にダウンロードするパスを書く。
$bucket->get_key_filename( 'testfile.txt', 'GET', './donload_file.txt' )
or die $s3->err . ':' . $s3->errstr;
[S3からキーを削除]
アップしてあるデータを削除するには
my $bucket = $s3->bucket('flect_test_buekct');
$bucket->delete_key('testfile.txt')
みたいにしましょう。簡単です。
[最後に]
アクセス権制御や、各種メタデータの格納などは今回はカバーしていませんが、
次回以降、どこかでまたまとめて書きたいと思います。
Google Storageなど対抗のサービスもありますが、S3はいろいろな用途で
大活躍できるので、もっと調査、活用を考えてみたいです。
なお、フレクトではAmazon EC2/S3を利用した開発、案件をこれから
たくさんやっていきます。興味のある方はぜひ中途採用にご連絡ください。
コメント