Windows Azure Drive Storage 算是 Windows Azure Platform 中最特殊的一種儲存服務了,它是基於 BLOB storage 上,將空間模擬成一台磁碟機的服務,而且與硬碟一樣有檔案系統,所以 NTFS API 可以將它當成真正的磁碟存取它。
Drive Storage是Windows Azure SDK特別為.NET的開發人員所準備的一個儲存格式,它只存在於Windows Azure SDK的組件和API中,它並沒有對外的REST APIs,除了使用Windows Azure SDK外,沒有別的方法可以使用,它本身是基於Page-BLOB為主的儲存服務,但將它模擬成一個獨立的磁碟機供應用程式使用,據微軟的官方文件說明,這個磁碟機是VHD(Virtual Hard Drive)格式,就如同附掛在Hyper-V上的VHD一樣,在生成時會格式化為一個NTFS檔案系統的磁碟,然後回傳給應用程式一個磁碟代號,應用程式即可利用這個磁碟代號對它進行存取,舉凡Win32 I/O API或是System.IO命名空間內的檔案API都可以順利執行,等於是將它當成一部實體的磁碟機看待即可。
在使用Drive Storage之前,必須要先將它掛載到虛擬機器的作業系統內,就像是Unix作業系統將一個磁碟掛在作業系統上,此程序稱為Mount,在執行Mount時,Drive APIs會登錄一個抽象層的介面(Drive Emulator APIs),並傳回一個磁碟機代號,所有應用程式的Win32 API即可使用這個磁碟機代號,它會決定資料的存取呼叫是否要傳給已登錄在BLOB儲存服務上的分頁式BLOB儲存區中,亦或是向本機快取(Local Cache)來要求資料。讀取時若發現資料已經有一份在本機快取時,會由本機快取讀取資料,否則會向分頁型BLOB要求資料,同時將該資料的副本寫入到本機快取中。當應用程式將資料寫入Drive Storage時,會寫入兩份資料,一份給分頁式BLOB實體的儲存區,另一份會保存到本機快取區,若舊資料在本地快取區有一份副本時,更新資料的寫入也會一併更新在本地快取的資料,以確保兩邊資料的同步性。所有針對Drive存取的呼叫若需要向分頁型BLOB要求資料時,會由Storage API Redirector來將API呼叫轉換成分頁型BLOB的REST API呼叫,再傳送給BLOB儲存服務。
Drive Storage的功能均來自Windows Azure SDK的Microsoft.WindowsAzure.CloudDrive.dll組件,命名空間一樣是Microsoft.WindowsAzure.StorageClient,而入口則是CloudDrive,我們必須要先在應用程式起始時對Drive Storage初始化以建立Drive Emulator,而這個工作必須要設定Local Storage,所以在使用它之前,要事先在專案的屬性中加入Local Storage的設定才行。
接著,使用CloudBlobContainer.GetPageBlobReference()產生一個新的VHD檔案,代表Page-BLOB的檔案入口,再使用這個CloudPageBlob產生新的CloudDrive,最後再將它Mount起來即可在程式中使用。
public override bool OnStart()
{
// ...
CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("FileDataSource");
LocalResource driveCacheStorage = RoleEnvironment.GetLocalResource("DriveCache");
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("newcontainer");
CloudDrive.InitializeCache(driveCacheStorage.RootPath, driveCacheStorage.MaximumSizeInMegabytes);
CloudPageBlob drivePageBlob = container.GetPageBlobReference("MyTestData.vhd");
try
{
drivePageBlob.Create(driveCacheStorage.MaximumSizeInMegabytes * 1048576);
}
catch (CloudDriveException)
{
// reserved for blob is exist.
}
CloudDrive drive = new CloudDrive(drivePageBlob.Uri, storageAccount.Credentials);
try
{
drive.Create(driveCacheStorage.MaximumSizeInMegabytes);
}
catch (CloudDriveException)
{
// file is exist.
}
drive.Mount(driveCacheStorage.MaximumSizeInMegabytes, DriveMountOptions.None);
return base.OnStart();
}
在程式處理上,除了要透過CloudDrive.GetMonutedDrives()取得已被Mount的磁碟機代號外,其他的就只需要利用System.IO命名空間內的類別,將它當作一般的磁碟機處理即可。
雖然我們說Drive Storage只能被Windows Azure SDK的用戶端程式取用,不過透過一些方法,還是可以在其他開發平台(如PHP)使用,只是要透過IIS掛載一小部份的.NET程式,才可以達成這個目的(欲知詳情可參考Reference的第二項)。
Reference:
http://msdn.microsoft.com/en-us/wazplatformtrainingcourse_exploringwindowsazurestoragevs2010_topic6#_Toc303848603
http://blog.maartenballiauw.be/post/2010/04/09/Using-Windows-Azure-Drive-in-PHP-(or-Ruby).aspx