« Amazon EC2/S3, Google AppEngine, Google Appsで開発、運用するモバイルレシピサイト | メイン | CloudFrontのエッジサーバ上にキャッシュされているオブジェクトを更新する »

2010年8月19日 (木)

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を利用した開発、案件をこれから
たくさんやっていきます。興味のある方はぜひ中途採用にご連絡ください。

http://www.flect.co.jp/recruit/index.html

トラックバック

このページのトラックバックURL:
http://bb.lekumo.jp/t/trackback/493401/32345231

PerlでAmazon S3の操作をする方法を参照しているブログ:

コメント

コメントを投稿

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

2024年4月

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
ブログ powered by TypePad