Dateien blockweise im Windows Azure Blob Storage speichern

Lastenträger (Nepal)In letzter Zeit stehe ich regelmäßig vor der Herausforderung größere Dateien, über eine langsame und teilweise instabile Verbindung, in den Windows Azure Blog Storage übertragen zu müssen.
Hierbei kommt es zwangsläufig zu Timeouts, sowie diversen Fehlermeldungen.
Eine Möglichkeit, mit dieser Herausforderung umzugehen, ist es die Dateien blockweise zu übertragen.

Dateien in einem Stück übertragen

Um eine Datei im Windows Azure Blob Storage zu speichern, würde man normalerweise wie folgt vorgehen:

  • Blob Client Objekt erzeugen.
  • Blob Referenz erzeugen und ggf. Meta-Daten angeben, wie z.B. den Content Type.
  • Blob mit der UploadFile Methode speichern.
var storageAccount = CloudStorageAccount
  .FromConfigurationSetting("AzureStorageConnectionString");
var blobClient = storageAccount.CreateCloudBlobClient();

var blob = blobClient.GetBlobReference("container/datei.bin");
blob.Properties.ContentType = "application/octet-stream";

blob.UploadFile(@"C:datei.bin");

 

Dateien Block für Block übertragen

Was mache ich aber, wenn die Datei größer als 64 MB ist,
oder ich nur eine langsame, instabile Verbindung nutzen kann?

Die Lösung heißt Block Blob's

Hier bieten sich die Eigenschaften eines Block Blob's an, da dieser aus einer Sequenz von Blöcken besteht.

Windows Azure Storage - Block Blob

Genauer gesagt:

  • Diese Blöcke können einzeln übertragen werden und unterschiedlich groß sein (Max. 4MB).
  • Mehrere Blöcke können gleichzeitig hochgeladen werden.
  • Einzelne Blöcke können auch mehrfach übertragen werden, wie z.B. bei fehlerhaften Übertragen.
  • Sobald alle Blöcke übertragen wurden, kann der Vorgang durch einen Commit abgeschlossen werden.
  • Dieser Übertragungsvorgang kann jederzeit unterbrochen, und zu einem späteren Zeitpunkt fortgeführt, werden.
    Nach einer Woche werden unbestätigte Blöcke automatisch verworfen.
  • Ein Block Blob kann aus maximal 50.000 bestätigten Blöcken bzw. 100.000 unbestätigten Blöcken bestehen.
  • Jeder dieser Blöcke wird über eine eindeutige, 64 Byte große, Block ID identifiziert.

Bei Dateien, die größer als 200MB und kleiner als 1TB sind, bieten sich Page Blobs an.

 

Datei aufteilen und übertragen

Um eine Datei in Blöcke zu zerteilen und diese einzeln zu übertragen, kann man wie folgt vorgehen:

using (var fileStream = new FileStream(fileName, 
  FileMode.Open, FileAccess.Read))
{
  var blockIdList = new List<string>();
  var blockId = 0;

  while(fileStream.Position < fileStream.Length)
  {
    // Buffergröße anhand der gewünschten Blockgröße (in KB)
    // bzw. anhand der restlichen Datenmenge bestimmen.
    var bufferSize = 
      blockSize * 1024 < fileStream.Length - fileStream.Position
      ? blockSize * 1024
      : fileStream.Length - fileStream.Position;
    var buffer = new byte[bufferSize];

    // Daten in das Bufferarray einlesen
    fileStream.Read(buffer, 0, buffer.Length);

    // Block zum Windows Azure Blob Storage übertragen
    using (var stream = new MemoryStream(buffer))
    {
      // Block ID konvertieren.
      var blockIdBase64 =
        Convert.ToBase64String(
          Encoding.UTF8.GetBytes(
            blockId.ToString(CultureInfo.InvariantCulture)
            .PadLeft(64, '0')));

      // Optional kann bei der PutBlock Methode ein
      // MD5 Hash zur Validierung angegeben werden.
      blob.PutBlock(blockIdBase64, stream, null);
      blockList.Add(blockIdBase64);
      blockId++;
    }
  }
}

 

Blöcke wieder zusammenführen

Nach der erfolgreichen Übertragung aller Blöcke, müssen diese beim Windows Azure Blob Storage als "vollständig" bestätigt werden:

// Hierbei ist die richtige Reihenfolge der Block-ID's entscheidend!
blob.PutBlockList(blockList);

 

Erst jetzt steht der Blob, wie gewohnt, zum Download zur Verfügung.

 

Beispielprojekt

Um das Ganze auch mal Live erleben zu können, habe ich diesem Blog Post ein Beispielprojekt angehängt.

Beispielprojekt - Block Blob Storage Demo 1

Je nach Installationsverzeichnis des Windows Azure SDK, muss der Pfad zum Windows Azure Storage Emulator, in der UploadBlockBlobStorageForm.cs, angepasst werden:

#region Private Felder

private const string WindowsAzureEmulator = 
  @"C:Program FilesWindows Azure Emulatoremulatorcsrun.exe";

#endregion

 


Download Download der Beispielanwendung:

Weitere Informationen


Verwendete Bildquellen:
© Dieter Schütz / PIXELIO

Check Also

Time Machine Backups nach Microsoft Azure

Seit einigen Jahren verwende ich eine Apple Time Capsule, um meine Time Machine Backups an einem zentralen Ort speichern zu können. Bislang hatte das für mich auch vollkommen ausgereicht. Seitdem ich jedoch immer mehr unterwegs bin, habe ich nach einer Lösung gesucht, die ich auch von unterwegs nutzen kann. In diesem Blog Post zeige ich deshalb, wie man Time Machine Backups nach Microsoft Azure machen kann.

One comment

  1. Andy, CloudBerry Lab

    I always enjoy learning what other people think about Microsoft Azure and how they use it. Check out my very own tool CloudBerry Explorer that helps managing Azure Blog Storage . It is a freeware.