这样,我们就可以将单独的表格保存到多个Blob里面,而且这些表格可以通过Blob进行平行恢复。
表格恢复
为了从Blob中恢复表格,我们可以获取“表格名称”容器的Blob列表,然后检索每个Blob中的模块列表。在每个模块中,加载xml并检索元件项,为每个添加到文本的元件创建一个BackupEntity实例。一旦把所有的实体数据添加到批次要素中,就可以用Batch选项调用SaveChanges使其执行处理。恢复进程假设它是一个没有实体数据的新表格——因此任何添加进程中的冲突错误都会被忽略。 CloudBlobContainer container = blobClient.GetContainerReference(tableName.ToLower());
CloudBlobDirectory dir = container.GetDirectoryReference(backupIdToRestore);
IEnumerable blobs = dir.ListBlobs();
foreach (IListBlobItem blob in blobs)
{
CloudBlockBlob blockBlob = new CloudBlockBlob(blob.Uri.AbsoluteUri);
blockBlob = container.GetBlockBlobReference(blob.Uri.AbsoluteUri);
TableRestore.RestoreTo(tableClient, blockBlob, tableToRestoreTo);
}
RestoreTo方法获取了模块列表,每个Blob会下载数据。然后它会为每个援引了ExecuteBatch方法的模块和批次要素检索批次要素列表。
static void ExecuteBatch(CloudTableClient tableClient, string tableName, XElement batchNode)
{
TableServiceContext context = tableClient.GetDataServiceContext();
context.WritingEntity += new EventHandler(OnWritingEntity);
// for each entry create a backup entity
IEnumerable entries = batchNode.Elements(AtomNamespace + "entry");
foreach (XElement entryNode in entries)
{
XElement propertiesElem = entryNode.Elements(AtomNamespace + "content")
.Elements(AstoriaMetadataNamespace + "properties")
.FirstOrDefault();
XElement pkElement = propertiesElem.Element(AstoriaDataNamespace + "PartitionKey");
XElement rkElement = propertiesElem.Element(AstoriaDataNamespace + "RowKey");
BackupEntity entity = new BackupEntity()
{
PartitionKey = pkElement.Value,
RowKey = pkElement.Value,
EntryElement = entryNode
};
context.AddObject(tableName, entity);
}
context.BatchWithRetries(TableExtensions.RetryExponential());
}
static void OnWritingEntity(object sender, ReadingWritingEntityEventArgs args)
{
BackupEntity entity = args.Entity as BackupEntity;
XElement content = args.Data.Element(AtomNamespace + "content");
XElement propertiesElem = content.Element(AstoriaMetadataNamespace + "properties");
propertiesElem.Remove();
XElement propertiesElemToUse = entity.EntryElement.Elements(AtomNamespace + "content")
.Elements(AstoriaMetadataNamespace + "properties")
.FirstOrDefault();
content.Add(propertiesElemToUse);
}
以下内容是对上述代码的一点改进:
1. 备份的平行进程和快速备份的恢复。
○对于备份,我们可以通过不同的排列范围或是通过存储账户的每个表格将查询平行化处理。当我们平行处理排列范围时,可以随机选择查询排列范围在正被使用的表格上展开备份加载。
○在恢复方面,我们可以平行处理不同的Blob或模块,如果我们有多个表格需要恢复,可以通过不同备份Blob容器(代表不同表格)实现平行化。
2. 我们可以记住备份运行时的排列范围,而不是将密钥列表作为用户输入的内容,然后要将其作为输入内容知道下一个要被执行的备份。如此一来,我们每次执行备份时,就可以记住密钥排列范围,然后将此信息形成更好的备份排列范围,下一个备份便可以被平行执行。此操作可以数据集更改的基础上继续得到改善。事实上,掌握了以上方法,我们就可以从优先的备份中列出Blob,然后从Blob名称中获取密钥排列范围。在执行下一个平行备份时,可使用此信息形成所需的变化范围。
3. 或许你想以xml形式保存带有Blob的某个版本或其他版本的元数据,以便恢复过程中可以对其加以利用。
4. 或许你希望以压缩格式保持模块。
此文中提供的代码意在创建模块,而并非一个完整的备份或恢复工具。其主旨是应对一些挑战,并提供解决之道。如果你打算在自己的应用中使用这些代码,请先进行测试。
9 7 3 1 2 3 4 5 6 4 8 :
本文来源:不详 作者:佚名