從Perl來用Amazon S3

對於任何的線上資源來說資料管理是一個關鍵且具挑戰的層面, 隨著豐富媒體成指數成長的資料量跟普及,即使是小的線上資源也必須有效地管理跟分散大量資料,另外,對每一個參與的人來說跟異地資料儲存有關的內心平靜是無價的。

SundayMorningRides.com,我們管理一個成長中的GPS庫存以及給直接用戶的一般的GIS(地理資訊系統)資料和網頁內容(文字、影像、視訊等),除此之外,我們還必須有效地管理日常的網站快照、備份以及網站和支援軟體的多個開發版本,對於任何小型組織,這些工作將顯著地增加成本,不僅僅是最初的貨幣投資,還包括持續的管理和維護人力成本。
Simple Storage Service(簡稱S3)就針對為解決上述線上資源的資料管理問題而應運而生,其目標是提供「可靠、快速、廉價的資料存儲架構」– Amazon就是用S3來支援它全球站點的運行,「 S3提供的網路服務介面允許開發者存儲和讀取任意大小的資料,S3對於SundayMorningRides之類的公司具有相當的吸引力,因為它使我們從前期成本和購買、管理、維護以及伺服器擴充的持續性成本這兩個問題獲得解決。」
這篇文章涉及到 、REST模組以及Amazon REST模組,整個過程透過開發一組在Unix命令列環境下執行的Perl工具與Amazon S3進行互動來實做,我另外會展示如何設定存取權限,以便於你可以直接從站點引用存儲在Amazon S3上的影像和其他資料服務。

網路服務簡介

網絡服務() 已經成為一種發佈資訊的重要渠道(method of exposing information ),或者說是建立在Web上的一種服務( services via the Web)。本質上說,Web服務提供了兩個連接網路之間資源的溝通。Amazon S3 可以透過Simple Object Access Protocol(簡單物件存取協定,SOAP)和representational state transfer (表象化狀態轉變)來存取。
SOAP 介面透過組合各種特性(organizes features )生成定製操作(custom-built operations),跟使用Java Remote Methond Invocation和Common Object Resource Broker Architecture (CORBA)一樣,遠程對物件(Objects)進行操作。不同於RMI和CORBA,SOAP使用HTTP請求中嵌入的XML作為應用程序的通訊協定。
和SOAP類似,REST同樣使用HTTP協定進行傳輸。不同於SOAP,REST的操作遵循HTTP標準操作—GET、POST、PUT和 DELETE。我想把REST的操作用跟關聯資料庫相關的CRUD與一來措詞:POST是新增(Create)、GET是讀取(Retrieve)、PUT是更新 (Update),而DELETE是刪除。※ok!※

關於Internet存貯

Amazon S3 用三個核心概念來闡述資料空間:物件(objects)、容器(buckets)、關鍵字(keys) 。
• 物件(objects)是在Amazon S3中最基礎的實體單位,他們由物件(objects)資料和中介資料(metadata)組成,這裡的中介資料就是一組已經定義在HTTP標頭文件內的屬性值(name-attribute pairs)。
• 容器(buckets)內包含多種物件(objects),容器(buckets)內沒有物件數量的限制,但是每個開發者最多只能擁有100個容器(buckets)。
• 關鍵字(keys)是識別物件(objects)的唯一標誌。

為了避免在以上各種概念中糾纏不清,我比較喜歡這樣的類比:容器(buckets)等同於資料夾、物件(objects)對應於檔案而關鍵字(keys)看作是檔名,這個抽象概念的目的就是要為每個物件創建一個獨特的HTTP命名空間。
我假定你已經在Amazon S3中註冊,並且收到了Access Key ID和Secret Access Key,如果還沒有,那請完成這些工作。
請注意:S3::*模組並不是唯一可以連接Amazon S3的perl模組,特別的是,Net::Amazon::S3模組隱藏了S3服務中的大部分細節,現在,我將使用一個相對簡單的模組來解釋S3內部是如何工作的。

連接、創建、顯示容器(buckets)

連接到Amazon S3很簡單,只要提供你的Access Key ID和Secret Access Key就可以建立一個連接,在這裡我們叫做$conn,接下來講解如何建立容器(buckets),顯示容器(buckets)中的內容以及所有的容器列表。
#!/usr/bin/perl

use S3::AWSAuthConnection;
use S3::QueryStringAuthGenerator;

use Data::Dumper;

my $AWS_ACCESS_KEY_ID = ‘YOUR ACCESS KEY’;
my $AWS_SECRET_ACCESS_KEY = ‘YOUR SECRET KEY’;

my $conn = S3::AWSAuthConnection->new($AWS_ACCESS_KEY_ID,
$AWS_SECRET_ACCESS_KEY);

my $BUCKET = "foo";#注意不要再使用這個名字,ㄚ琪改用achifoo

print "creating bucket $BUCKET \n";
print $conn->create_bucket($BUCKET)->message, "\n";

print "listing bucket $BUCKET \n";
print Dumper @{$conn->list_bucket($BUCKET)->entries}, "\n";

print "listing all my buckets \n";
print Dumper @{$conn->list_all_my_buckets()->entries}, "\n";
因為每個S3的動作都是透過HTTP來產生,所以檢查是否有200回應是很好的作法。
my $response = $conn->create_bucket($BUCKET);
if ($response->http_response->code == 200) {
# Good
} else {
# Not Good
}
正如你在輸出中看到的:結果返回一個hash值。我用 Data::Dumper模組作為顯示Bucket內容的工具。如果你是第一次運行這個,你在Bucket裡面當然什麼也看不到。
listing bucket foo
$VAR1 = {
‘Owner’ => {
‘ID’ => ‘xxxxx’,
‘DisplayName’ => ‘xxxxx’
},
‘Size’ => ‘66810’,
‘ETag’ => ‘"xxxxx"’,
‘StorageClass’ => ‘STANDARD’,
‘Key’ => ‘key’,
‘LastModified’ => ‘2007-12-18T22:08:09.000Z’
};
$VAR4 = ‘
‘;
listing all my buckets
$VAR1 = {
‘CreationDate’ => ‘2007-11-28T17:31:48.000Z’,
‘Name’ => ‘foo’
};
‘;

ㄚ琪的測試結果:

2011-04-14_112810

撰寫物件(objects)

用HTTP PUT方法能快速地撰寫一個物件(objects),不過要注意的是:沒有任何提示或者預防手段可以預防覆蓋一個已經存在的物件(objects),Amazon S3會自動更新那個寫入最頻繁的物件(objects),此外,它目前還不能追加(append)或者修改(modify)單個物件(objects),只能通過替代的方式來達到追加(append)或者修改(modify)的單個物件(objects)。
my %headers = (
‘Content-Type’ => ‘text/plain’
);
$response = $conn->put( $BUCKET, $KEY, S3Object->new("this is a test"),
\%headers);
同樣,你可以從STDIN讀取一個檔案:
my %headers;

FILE: while(1) {
my $n = sysread(STDIN, $data, 1024 * 1024, length($data));
if ($n < 0) {
print STDERR "Error reading input: $!\n";
exit 1;
}
last FILE if $n == 0;
}
$response = $conn->put("$BUCKET", "$KEY", $data, \%headers);
要新增訂製的中介資料,只要新增到S3Object:
S3Object->new("this is a test", { name => "attribute" })
預設情況下,每一個物件在寫入時需要私有權限(private access control),私有權限(private access control)只允許該物件(objects)的所有者讀取,你可以改變這些權限設定,另外,要注意到每一個物件可以擁有最多5GB的資料。
你可能也想知道S3是否也可以透過標準的HTTP POST的方法上傳,那些在Amazon工作的同仁們正在努力達到這個目標—見HTTP POST beta discussioneta discussion)有更多的資訊,在他們完成這個目標之前,我們還只能透過中間服務器進行網頁的形式上傳。

讀取物件(objects)

和創建物件類似,同樣有多種方法可以從Amazon S3中讀取資料,一種方法是生成一個臨時的URL,用你喜歡的客戶端(比如,wget或者Curl)或甚至是一個瀏覽器拜訪這個臨時的URL來顯示和讀取物件(objects)的內容,你要做的全部事情就是生成URL,然後用它來呼叫REST。
my $generator = S3::QueryStringAuthGenerator->new($AWS_ACCESS_KEY_ID,
$AWS_SECRET_ACCESS_KEY);
…然後執行一個簡單的HTTP GET方法請求,如果你想要做的只是暫時查看或驗證資料,這是一個很棒的技巧。
$generator->expires_in(60);
my $url = $generator->get($BUCKET, "$KEY");
print "$url \n";
你也可以用程式從最初的連接直接讀取資料,如果你必須執行額外的處理資料時,這很方便。
my $response = $conn->get("$BUCKET", "$KEY");
my $data = $response->object->data;
另一個酷功能就是可以使用BitTorrent的功能從Amazon S3下載檔案,你可以透過BitTorrent存取任何匿名訪問權限的物件。

刪除物件(Objects)

現在,可能在創建物件(Objects)過程中出錯,或者卡死,那麼你可能需要在某些時候刪除原來建構的物件(Objects)。
$conn->delete("$BUCKET", "$KEY");

設定訪問權限和發佈到網站

如果你已經注意到先前的例子,所有的Amazon S3 物件(objects)都是通過HTTP來存取,這樣的情況使得Amazon S3像線上的文件倉庫一樣特別有用,尤其是它對於管理和服務站點的多媒體方面特別有用,你幾乎可以把Amazon S3服務看做是站點上一個迷你的內容傳遞網路(Content Delivery Network)多媒體,以下的例子說明如何建立一個簡單的從Amazon S3動態引用圖片構成的網頁。
首先,上傳圖片並且設置ACL權限為公開(public)狀態,我已經修改了前面的例子只有一點不同,要使物件能夠被公開讀取,需要把Header中 x-amz-acl設為public-read。
my %headers = (
‘x-amz-acl’ => ‘public-read’,
);
另外ACL的權限還包括:
• 私有(預設) (private)
• 公開讀取(public-read)
• 公開讀寫(public-read-write)
• 授權讀取(authenticated-read)
現在你已經對上述的指令碼嫻熟於胸,通過對這些指令碼的整合,可以編寫一個能夠自動在網頁上顯示所有在容器(Bucket)內的圖片的指令碼。(你可能對格式會有一些美化排版的處理)

my $BUCKET = "foobar";
my $response = $conn->list_bucket("$BUCKET");

for my $entry (@{$response->entries}) {
my $public_url = $generator->get($BUCKET, $entry->{Key});
my ($url, undef) = split (/\?/, $public_url);
$images .= "";
}
($webpage = <<"WEBPAGE");
$images
WEBPAGE
print $q->header();
print $webpage;
如果要向該頁面添加圖片,只需要上傳的圖片到對應的容器(Bucket),之後這些圖片會自動在你下次重新整理頁面的時候顯示。
從網頁引用多媒體文件同樣是易如反掌,如果你觀察這個例子生成的HTML,你會看見Amazon S3 URLs 擁有一個基本的格式:http://bucketname.s3.amazon.com/objectname ,另外,請注意:你的容器(Buckets) 的命名空間(namespace)是和其他Amazon S3 用戶共享的。

結論

Amazon S3是一個強大的工具,它可以透過提供廉價和無限的存儲空間幫助各種規模的組織進行資料管理,對於個人使用來說,它是一個非常好的備份工具(對於組織來說也是)和一般的檔案存貯,它也是一個優秀的協作工具,免去到處群發郵件的麻煩,只需要上傳一個檔案,並且設定合理的存取控制,就能進行有效的協作了。—再也不用糾纏於10MB附件大小之類的限制!
在SundayMorningRides.com ,我們用S3作為我們網站服務架構的一部分,來減少我們提供多媒體服務時候的硬體負載。
當和其他Amazon Web Service,比如SimpleDB(用於結構化的資料查詢),Elastic Compute Cloud(用於資料處理)等等結合的時候,他們的組合往往能為網站提供計算和資料管理的低成本解決方案。

更多的資源和參考
Print Friendly, PDF & Email

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料