有没有办法在页面Blob的azure存储中原子地写入数据和元数据?
考虑一个包含多个编写器的页面blob。
我看到建议将元数据用于记录计数,序列号,blob数据的一般结构等事项。但是,如果两个编写器写入数据然后必须更新元数据,那么每个写入并没有竞争,并通过读取当前计数然后更新来尝试更新记录计数。读取0和写入1都有,但实际上有2个。
同样适用于元数据写入未被该特定内容键入的任何情况(例如,每次写入然后将 新 名称 - 值对写入元数据)。
以下建议对我来说似乎不起作用。
// 512 byte aligned stream with my data
Stream toWrite = PageAlignedStreamManager.Write(data);
long whereToWrite = this.MetaData.TotalWrittenSizeInBytes;
this.MetaData.TotalWrittenSizeInBytes += toWrite.Length;
await this.Blob.FetchAttributesAsync();
if (this.MetaData.TotalWrittenSizeInBytes > this.Blob.Properties.Length)
{
await this.Blob.ResizeAsync(PageAlignedMemoryStreamManager.PagesRequired(this.MetaData.TotalWrittenSizeInBytes) * PageAlignedMemoryStreamManager.PageSizeBytes * 2);
}
this.MetaData.RevisionNumber++;
this.Blob.Metadata[STREAM_METADATA_KEY] = JsonConvert.SerializeObject(this.MetaData);
// TODO: the below two lines should happen atomically
await this.Blob.WritePagesAsync(toWrite, whereToWrite, null, AccessCondition.GenerateLeaseCondition(this.BlobLeaseId), null, null);
await this.Blob.SetMetadataAsync(AccessCondition.GenerateLeaseCondition(this.BlobLeaseId), null, null);
toWrite.Dispose();
如果我没有显式调用SetMetaData作为下一个动作,则它不会被设置:(
答案 0 :(得分:4)
有没有办法在天蓝色存储中原子地写入数据和元数据?
是。您可以尝试以这种方式原子更新数据和元数据。当我们使用以下代码片段设置/更新blob元数据时,它将存储在当前的blob对象中。目前,没有进行网络通话。
blockBlob.Metadata["docType"] = "textDocuments";
当我们使用以下代码更新blob时,它实际上会调用设置blob内容和元数据。如果上载失败,则不会更新blob内容和元数据。
blockBlob.UploadText("new content");
但是,如果两个编写者写入数据然后必须更新元数据,那么每个编写器都没有竞争,并且通过读取当前计数然后更新来尝试更新记录计数。读取0和写入1都有,但实际上有2个。
Azure存储支持这三个数据concurrency strategies(乐观并发,悲观并发和最后一个作者获胜),我们可以通过 ETag 属性使用乐观并发控制,或者通过悲观的并发控制使用租约,这可以帮助我们保证数据的一致性。