使用 Amazon S3 服務輕鬆實現存儲

Amazon Simple Storage Service (S3) 是一個公開的服務,Web 應用程序開發人員可以使用它存儲數字資產,包括圖片、視頻、音樂和文檔。 S3 提供一個 RESTful API 以編程方式實現與該服務的交互。通過本文,您將瞭解如何使用開源的 JetS3t 庫利用 Amazon 的 S3 雲服務存儲和檢索數據。 
簡介 

雲是一個抽象的概念,表示鬆散連接在一起的計算機組,這些計算機共同執行某項任務或者服務,就像是使用一個單獨的實體完成一樣。此概念背後的架構也很抽象:每個雲提供者都可以根據各自情況隨意設計它的產品。軟件即服務(Software as a Service,SaaS)是一個與雲相關的概念,表示雲向用戶提供某種服務。雲模型可以降低用戶成本,因爲他們無需購買軟件和硬件也可以運行 — 服務提供者已經爲用戶提供了必要的組件。 

雲計算簡介 

儘管雲計算這一術語並不新鮮(Amazon 在 2006 年就開始提供它的雲服務),但從 2008 年起它纔開始真正成爲流行詞,這期間,Google 和 Amazon 的雲服務逐漸獲得了公衆的關注。 Google 的 App Engine 使用戶能夠在 Google 基礎設施上構建和託管 Web 應用程序。連同 S3,Amazon Web Services 還包括 Elastic Cloud Compute (EC2) 計算 Web 服務,該服務可以在 Amazon 的基礎設施上託管應用程序。其他公司也開始蠢蠢欲動,準備與 Amazon 和 Google 一決高下,其中就包括 Microsoft®的 Azure,甚至 Sun Microsystems(其雲計算還沒有正式推向市場)也想分一杯羹。 IBM® 最近宣佈,它將提供 某些產品 供開發人員在 Amazon EC2 環境中使用。 


以 Amazon 的 S3 產品爲例。顧名思義,這是一個公開的服務,使 Web 開發人員能夠存儲數字資產(如圖片、視頻、音樂和文檔等),以便在應用程序中使用。使用 S3 時,它就像一個位於 Internet 的機器,有一個包含數字資產的硬盤驅動。實際上,它涉及到許多機器(位於各個地理位置),其中包含數字資產(或者數字資產的某些部分)。 Amazon 還處理所有複雜的服務請求,可以存儲數據並檢索數據。您只需要付少量的費用(大約每月 15 美分 /GB)就可以在 Amazon 的服務器上存儲數據,1 美元即可通過 Amazon 服務器傳輸數據。 

Amazon 的 S3 服務沒有重複開發,它公開了 RESTful API,使您能夠使用任何支持 HTTP 通信的語言訪問 S3 。 JetS3t 項目是一個開源 Java 庫,可以抽象出使用 S3 的 RESTful API 的細節,將 API 公開爲常見的 Java 方法和類。編寫的代碼越少越好,難道不是嗎?充分利用其他人的成果也是不錯的。在本文中您將看到,JetS3t 使 S3 和 Java 語言的工作變得更加簡單,從根本上提高了效率。 





S3 概述 

理論上,S3 是一個全球存儲區域網絡 (SAN),它表現爲一個超大的硬盤,您可以在其中存儲和檢索數字資產。但是,從技術上講,Amazon 的架構有一些不同。您通過 S3 存儲和檢索的資產被稱爲對象。對象存儲在存儲段(bucket)中。您可以用硬盤進行類比:對象就像是文件,存儲段就像是文件夾(或目錄)。與硬盤一樣,對象和存儲段也可以通過統一資源標識符(Uniform Resource Identifier,URI)查找。 

例如,在我的硬盤中,我有一個名爲 whitepaper.pdf 的文件,它位於主目錄中名爲 documents 的文件夾中。相應的,該 pdf 文件的 URI 爲 /home/aglover/documents/whitepaper.pdf 。在 S3 中,URI 有一點不同。首先,存儲段只能是頂級的 — 無法像嵌套硬盤中的文件夾(或目錄)一樣進行嵌套。其次,存儲段必須遵循 Internet 命名法則;句點旁邊沒有斜槓,名稱不包括下劃線等等。最後,由於存儲段名稱已經是 Amazon 域內的 (s3.amazonaws.com) 公共 URI 的一部分,存儲段名稱必須在所有 S3 中是惟一的。(好消息是每個帳戶只能包含 100 個存儲段,因此不用擔心別人佔用了所有的好名字)。 

DNS 魔術 

不用擔心 S3 資產的 URL 。通過 Domain Name System (DNS) 和 CNAME(canonical name的縮寫)記錄,您可以將自定義程度更高的 URL 映射到 S3 的 URL 。這樣一來,您就隱藏了您(或您的應用程序)依賴 S3 的事實! 


存儲段在 S3 中是 URI 的根。也就是說,存儲段的名稱將是指向 S3 中某個對象的 URI 的一部分。例如,如果我有一個名爲 agdocs 的存儲段以及一個名爲 whitepaper.pdf 的對象,URI 將是:http://agdocs.s3.amazonaws.com/whitepaper.pdf 。 

S3 還提供了指定存儲段和對象的所有者和權限的能力,就像對待硬件的文件和文件夾一樣。在 S3 中定義對象或存儲段時,您可以指定一個訪問控制策略,註明誰可以訪問您的 S3 資產以及如何訪問(例如,讀和寫權限)。相應地,您可以通過許多方式提供對您的對象的訪問,使用 RESTful API 只是其中一種。 



開始使用 S3 和 JetS3t 

要開始使用 S3,您需要一個帳戶。 S3 不是免費的,因此在創建帳戶時您必須向 Amazon 提供一種支付手段(比如信用卡號碼)。不用擔心 — 不收初裝費;您只需要爲使用付費。對於本文的示例,只需要支付不到 1 美元的費用。 

在創建帳戶的過程中,您還需要創建憑據:訪問密鑰和祕密密鑰(就像用戶名和密碼)。(您還可以獲取 x.509 證書;但是,只有在使用 Amazon 的 SOAP API 時才需要使用該證書)。和任何訪問信息一樣,都必須保管好您的祕密密鑰。因爲任何人使用您的憑據訪問 S3 時,您都將爲此付費。因此,每當創建存儲段或對象時,默認的行爲是讓所有內容都私有;您必須顯式獲取對外部世界的訪問。 

有了訪問密鑰和祕密密鑰,您可以下載 JetS3t並使用它通過 RESTful API 與 S3 交互。 

使用編程手段通過 JetS3t 登錄 S3 可以分爲兩步。首先,必須創建一個 AWSCredentials 對象,然後將它傳遞到 S3Service 對象。AWSCredentials 對象非常簡單。它將訪問密鑰和祕密密鑰視爲 String。S3Service 對象實際上是一個接口類型。因爲 S3 同時提供 RESTful API 和一個 SOAP API,JetS3t 庫可以提供兩種實現類型:RestS3Service 和 SoapS3Service。就本文而言(包括大部分 S3 事務),RESTful API 的簡潔性讓它成爲一個很好的選擇。 

創建一個連接的 RestS3Service 實例很簡單,如清單 1 所示: 


清單 1. 創建一個 JetS3t 的 RestS3Service 實例 

def awsAccessKey = "blahblah" 
def awsSecretKey = "blah-blah" 
def awsCredentials = new AWSCredentials(awsAccessKey, awsSecretKey) 

def s3Service = new RestS3Service(awsCredentials) 


現在可以執行一些有趣的操作了:例如,創建存儲段、添加一個影片,然後獲取一個有時間限制的 URL 。實際上,這聽起來像一個業務流程,不是嗎?這是一個與發佈有限資產(比如影片)有關的業務流程。 

創建存儲段 

對於虛構的電影業務,我將創建一個稱爲 bc50i 的存儲段。藉助 JetS3t,該流程很簡單。通過 S3Service 類型,您有幾個選項。我更喜歡使用 getOrCreateBucket 調用,如清單 2 所示。顧名思義,調用該方法可能返回一個存儲段實例(表示爲 S3Bucket 類型的實例)或在 S3 中創建代碼段。 


清單 2. 在 S3 服務器上創建存儲段 

def bucket = s3Service.getOrCreateBucket("bc50i") 


不要被我這個簡單的代碼示例所矇蔽。 JetS3t 庫的擴展性非常強。例如,您可以快速確定擁有多少存儲段 —— 只需通過 listAllBuckets 調用請求一個 S3Service 實例即可。該方法返回一個 S3Bucket 實例數組。對於任何存儲段實例,您可以詢問它的名稱和創建日期。更重要的是,您可以通過 JetS3t 的 AccessControlList 類型控制與之相關的權限。例如,我可以獲取 bc50i 存儲段實例,並允許任何人可以公開讀取和編寫,如清單 3 所示: 


清單 3. 修改存儲段的訪問控制列表 

def bucket.acl = AccessControlList.REST_CANNED_PUBLIC_READ_WRITE 


當然,通過 API,您也可以隨意刪除存儲段。 Amazon 甚至允許您指定創建存儲段的地理位置。 Amazon 簡化了存儲實際數據的複雜性,但是您可以告訴 Amazon 要將存儲段(及其內部所有的對象)放在美國或歐洲(當前可用選項)。 

向存儲段添加對象 

使用 JetS3t 的 API 創建 S3 對象就像操作存儲段一樣簡單。 JetS3t 庫也很智能,可以負責處理與 S3 存儲段內文件相關的內容類型。例如,我想向 S3 上傳一段影片 nerfwars2.mp4,以便用戶能夠在有限的時間內觀看。創建一個 S3 對象與創建常見的 java.io.File 類型一樣簡單,並能將 S3Object 類型與存儲段關聯,如清單 4 所示: 


清單 4. 創建一個 S3 對象 

def s3obj = new S3Object(bucket, new File("/path/to/nerfwars2.mp4")) 


使用文件和存儲段初始化 S3Object 之後,要做的所有事情就是通過 putObject 方法上傳,如清單 5 所示: 


清單 5. 上傳影片 

s3Service.putObject(bucket, s3obj) 


使用清單 5 可以完成上傳。現在影片位於 Amazon 服務器了,影片的鍵就是它的名稱。當然,您可以根據需要重寫該名稱以調用其他對象。實際上,JetS3t API(以及 Amazon S3 RESTful API)公開了許多信息,供您創建對象時使用。我們知道,您還可以提供訪問控制列表。 S3 中的任何對象都可以保存 API 允許您創建的其他元數據。之後可以通過該元數據的 S3 API(以及派生的 JetS3t)查詢任何對象。 



創建對象的 URL 

到現在爲止,我的 S3 實例有一個包含影片的存儲段。實際上,我的影片可以通過以下 URI 獲取:http://bc50i.s3.amazonaws.com/nerfwars2.mp4 。但是,只有我才能獲取。(在本例中,我只能通過編程方式訪問它,因爲與所有內容關聯的默認訪問控制被設置爲拒絕任何未授權訪問)。我的目的是爲選擇的用戶提供一種方式查看新影片(在有限的時間內),直到我開始收取訪問費用(S3 也會提供幫助)。 

圖 1 展示了默認的訪問控制。返回的 XML 文檔(相應地顯示在我的瀏覽器中)告訴我對當前資產的訪問被拒絕(http://bc50i.s3.amazonaws.com/nerfwars2.mp4)。 


圖 1. Amazon 的安全機制 


創建一個公共 URL 是 S3 提供的一個便捷功能;實際上,使用 S3,您可以創建一個公共 URL,但只在一段時間內有效(例如,24 小時內)。對於我剛剛存儲在 S3 服務器上的影片,我將創建一個 48 小時內有效的 URL 。然後我將向選定的用戶提供該 URL,以便他們下載並觀看(假定他們在兩天內下載)。 

要創建一個針對 S3 對象的時間敏感型 URL,您可以使用 JetS3t 的 createSignedGetUrl 方法,這是一個 S3Service 類型的靜態方法。該方法採用一個存儲段名稱、一個對象鍵(在本例中是影片名,還記得嗎?)、一些憑證(以 JetS3t 的 AWSCredentials 對象的形式)、截止日期。如果您瞭解所需的存儲段和對象鍵,則可以通過清單 6 中的 Groovy 代碼快速獲取 URL: 


清單 6. 創建一個時間敏感型 URL 

def now = new Date() 
def url = S3Service.createSignedGetUrl( 
   bucket.getName(), s3obj.key, awsCredentials, now + 2) 


使用 Groovy,我可以通過 + 2 語法輕鬆指定一個 48 小時的限定日期。得到的 URL 如下所示(只有一行): 

https://bc50i.s3.amazonaws.com/nerfwars2.mp4?AWSAccessKeyId= 
   1asd06A5MR2&Expires=1234738280&Signature=rZvk8Gkms%3D 


現在,通過該 URL,可以在瀏覽器中獲得圖 2 所示的內容: 


圖 2. 用於下載的 URL 


這個過程是不是很簡單?通過幾行代碼,我在雲中創建了一個安全資產,該資產只能通過特殊的 URL 下載。 

利用 S3 完成時間敏感型下載 

如果您的帶寬和存儲需求不穩定,則 S3 能提供很多幫助。例如,想想我演示的業務模型 — 影片在一年中特定的時間發佈。在傳統的存儲模型中,您需要在某處機架上購買許多空間(或提供通向它的硬件和管道),很可能下載量很大,但隨後會相對降低。但是,您不能根據需要付費。使用 S3,該模型將根據需要付費 — 公司僅在需要時爲存儲和帶寬付費。更重要的是,S3 的安全特性可以幫助您進一步指定人們何時可以下載視頻,甚至可以指定誰可以下載。 

使用 S3 實現這些需求非常容易。在高水平上,創建一個受限的影片公共下載需要 4 個步驟: 

登錄 S3 。 
創建存儲段。 
向存儲段添加所需的視頻(或對象)。 
創建一個指向該視頻的時間敏感型 URL 。 

就是這樣! 






結束語 

與傳統存儲模型相比,S3 的隨需付費模型有很多明顯的優勢。例如,在自己的硬盤上存儲音樂收藏,我必須預先花 130 美元購買一個 500GB 的存儲單元。我沒有 500GB 的數據可以存儲,因此我爲自己不需要的空間花費了 25 美分 /GB(雖然很便宜)。我還需要維護設備並支付電費。如果我使用 Amazon,我不需要預先爲不重要的資產支付 130 美元。我只需要支付 10 美分 /GB,無需爲管理和維護存儲硬件付費。現在想想在整個企業範圍內實現這些服務的好處。以 Twitter 爲例,在 S3 上爲 100 萬個用戶帳戶存儲圖片。通過按照使用付費的方式,Twitter 不需要花費大量資金購買硬件基礎設施來存儲和提供圖片服務,也不需要支出人力和部件成本來配置和維護圖片。 

雲的好處還不止這些。您還可以實現低延遲和高可用性。假設存儲在 Amazon 雲中的資產遍佈全世界,那麼爲各個位置提供內容的速度將會更快。更重要的是,由於您的資產分佈在各種機器上,您的數據在一些機器(或部分網絡)癱瘓時也能保持高可用性。 

一言以蔽之,Amazon S3 的好處很簡單:低成本、高可用性、安全。除非您是一個 SAN 專家,喜歡維護硬件資產來存儲數據內容,但是 Amazon 可能比您做的更好。在資金緊張的時候,爲什麼還要將自己的資金提前預支在硬件上呢(不要忘了,硬件會隨時間貶值)?

發佈了129 篇原創文章 · 獲贊 8 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章