BLOB Storage顧名思義,是專門用來儲存二進位檔案使用的儲存服務,基本上檔案的格式沒有任何的限制,只要是可以轉換成二進位資料(binary data)的檔案都可以儲存,也就是我們常說的非結構化(unstructured)資料,舉凡一般的文字檔案到大型的影音檔案都可以使用。
BLOB Storage的概念和檔案系統非常類似,每個儲存帳戶都有獨立的URL命名空間,而命名空間下則是容器(container),資料則存放在容器內,容器的概念就像是資料夾一樣,所以一個儲存在BLOB中的檔案的URL會是:
http://[storagename].blob.core.windows.net/[container name]/[blob name]
在BLOB Storage中支援兩種不同類型的資料,一種是劃分為資料塊(data block)的BLOB格式,檔案由固定大小的資料塊組成,用戶端在操作此類型的BLOB時,可將資料劃分成數個資料塊後分批上傳,最後再使用API將這些資料塊組織成一個完整的檔案,Storage在處理資料塊時會使用兩階段認可程序(Two-phrase Commit),每個資料塊在上傳時都要經過服務認可才算成功,也就是說如果有資料塊傳輸失敗時,服務會要求用戶端重傳,直到全部傳輸完成後,再將所有的資料塊認可成一個完整的檔案。一個使用資料塊保存的BLOB檔案最多可擁有50,000個區塊,而一個區塊最大的長度為4MB,所以等於最大可以存放200GB的資料量。另一個BLOB格式則是分頁型(page)的BLOB,這個格式很類似於電腦中的記憶體,它是由連續位址組合而成的,用戶端可以自由的決定要寫入哪一段位址,服務也不會特別去檢查是否完成就會直接認可,在速度上分頁型的BLOB會比資料塊型的BLOB要來的快,可用大小也比資料塊的大,最高可用到1TB的資料量,適合需要連續寫入資料的需求,而Windows Azure Drive也是使用這個類型的BLOB來實作的。
不論是Block或是Page BLOB,對外都是以REST API來開放功能,對於.NET開發人員來說更幸褔了,因為Windows Azure SDK內建了StorageClient組件,封裝了REST API,開發人員只要使用物件即可操作BLOB的資料。若要開發使用BLOB Storage的應用程式,請在專案中加入Microsoft.WindowsAzure.StorageClient.dll的參考,然後在程式中引用Microsoft.WindowsAzure.StorageClient命名空間。
BLOB服務的入口由CloudBlobClient類別提供,透過CloudStorageAccount.CreateCloudBlobClient()擴充方法可取得它,然後使用GetContainerReference() 取得CloudBlobContainer物件,這個物件代表BLOB的容器,裡面即有列舉內部的檔案的方法可使用,可參照下列程式碼:
private void InitializeBlobStorage()
{
CloudStorageAccount storageAccount =
CloudStorageAccount.FromConfigurationSetting("FileDataSource");
this._blobClient = storageAccount.CreateCloudBlobClient();
}
private void LoadBlobContainers()
{
this.tvContainerView.Nodes.Clear();
CloudBlobContainer rootContainer = this._blobClient.GetContainerReference("/");
TreeNode node = new TreeNode("根目錄");
node.Value = rootContainer.Uri.ToString();
IEnumerable<CloudBlobContainer> containers = this._blobClient.ListContainers();
foreach (CloudBlobContainer container in containers)
{
TreeNode containerNode = new TreeNode(container.Name);
containerNode.Value = container.Uri.ToString();
node.ChildNodes.Add(containerNode);
}
this.tvContainerView.Nodes.Add(node);
this.cmdAddContainer.Enabled = (string.IsNullOrEmpty(this.tvContainerView.SelectedValue));
this.cmdUpload.Enabled = (!string.IsNullOrEmpty(this.tvContainerView.SelectedValue));
}
private void LoadBlobs()
{
if (string.IsNullOrEmpty(this.tvContainerView.SelectedValue))
return;
CloudBlobContainer container =
this._blobClient.GetContainerReference(this.tvContainerView.SelectedValue);
IEnumerable<IListBlobItem> blobs = container.ListBlobs(
new BlobRequestOptions() { UseFlatBlobListing = true });
this.gvBlobList.DataSource = blobs;
this.gvBlobList.DataBind();
}
而若要處理BLOB檔案,則可以使用CloudBlockBlob物件,透過GetBlockBlobReference()可取得它的參考,再利用它的UploadByteArray()或UploadFile()或UploadStream()等方法上傳資料,如下列程式碼:
protected void cmdUpload_Click(object sender, EventArgs e)
{
string blobName = null;
if (string.IsNullOrEmpty(this.txtBlobName.Text))
blobName = this.fuFile.FileName;
else
blobName = this.txtBlobName.Text;
CloudBlobContainer container =
this._blobClient.GetContainerReference(this.tvContainerView.SelectedValue);
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
blob.UploadByteArray(this.fuFile.FileBytes);
blob = null;
this.LoadBlobs();
}
BLOB服務除了可以儲存檔案外,它也可以將檔案分享給應用程式以外的用戶端,每個BLOB檔案都有一個URL,只要擁有這個URL就可以取得檔案,但如果檔案需要做存取控制的話,則可以透過Shared Access Signature來限制,利用Container本身的開放限制以及檔案本身的授權戳記限制,可以達到控制檔案存取範圍的需求。Shared Access Signature本身很複雜難懂,但.NET開發人員只要利用StorageClient組件中的功能,即可很輕鬆的取得帶有Shared Access Signature的URL,例如下列程式碼:
CloudBlobContainer container = this._blobClient.GetContainerReference(this.txtContainerName.Text);
container.CreateIfNotExist();
BlobContainerPermissions blobPermission = new BlobContainerPermissions();
blobPermission.PublicAccess = BlobContainerPublicAccessType.Container;
blobPermission.SharedAccessPolicies.Add("TimePolicy", new SharedAccessPolicy()
{
Permissions = SharedAccessPermissions.List | SharedAccessPermissions.Read,
SharedAccessStartTime = DateTime.Now,
SharedAccessExpiryTime = DateTime.Now.AddDays(10)
});
container.SetPermissions(blobPermission);
container = null;
當然,BLOB如果只能記錄檔案,那麼似乎也太少了,如果想要增加一些描述性的資料的話,若還要依賴Table Storage,那兩邊的同步性似乎問題就不小,但還好的是,BLOB storage允許每個檔案擁有自己的描述性資料,稱為Metadata,只要在加入或更新BLOB資料時,都可以寫入Metadata 資料,讓檔案的描述資訊更加完整。Metadata是由鍵值對 (name-value pair)來組成,BLOB Storage要求Metadata的鍵值名稱必須要是符合C# identifier規範,否則會在serialize階段擲出例外而失敗。
由於篇幅限制,BLOB功能無法非常完整的交代,有興趣的讀者可參考MSDN邊做邊學的Windows Azure Platform系列文章,市面上也有兩本中文書可以參考,也可以上網下載Windows Azure Training Kit,裡面有很多範例程式與Hands-on Labs可以體驗。
最後要說明的是,BLOB使用上會有些許限制:
- BLOB組成的字串中不可以有URL路徑不允許的字元出現,否則系統會回傳HTTP 400(Bad Request)的錯誤。
- 容器的名稱可以是英文半型與數字,以及『-』字元組成的名稱,但『-』字元不可以出現在第一個或最後一個字元,同時長度必須在3至63個字元之間,而且全部都要是小寫(不可以出現大寫字元)。
- 由於BLOB儲存服務以及容器等,都是Flat階層(即沒有明確的階層化),所以可以用『/』來當BLOB資料的名稱的一部份,以模擬出有資料夾的URL(例如可以用『a/mydata/mydata.txt』作為BLOB資料的名稱),同時也最好不要使用『.』來結尾,這有可能會讓一些URL解析器失效(例如.NET的Uri物件)。
Reference: