我试图使用新的Azure附加blobs和Azure Storage 6.0.0为Azure中的应用程序创建一个记录器。因此,我创建了一个快速测试应用程序,以更好地理解附加的blobs及其性能特性。
我的测试程序简单地循环了100次,并将一行文本附加到附加的blob中。但是,如果我使用同步AppendText()方法,一切都可以正常工作,它似乎仅限于每秒编写5-6个附加文件。因此,我尝试使用异步AppendTextAsync()方法;然而,当我使用该方法时,循环运行速度要快得多(正如预期的那样),但是追加的blob没有抛出任何异常,大约丢失了98%的附加文本。
如果我在每个附加操作之间添加一个Thread.Sleep并睡眠100毫秒,我将得到大约50%的数据。睡1秒,我就会得到所有的数据。
这似乎类似于在v5.0.0中发现的问题,但在v5.0.2中解决了这个问题:https://github.com/Azure/azure-storage-net/releases/tag/v5.0.2
这是我的测试代码,如果您想要重现这个问题的话:
static void Main(string[] args)
{
var accountName = "<account-name>";
var accountKey = "<account-key>;
var credentials = new StorageCredentials(accountName, accountKey);
var account = new CloudStorageAccount(credentials, true);
var client = account.CreateCloudBlobClient();
var container = client.GetContainerReference("<container-name>");
container.CreateIfNotExists();
var blob = container.GetAppendBlobReference("append-blob.txt");
blob.CreateOrReplace();
for (int i = 0; i < 100; i++)
blob.AppendTextAsync(string.Format("Appending log number {0} to an append blob.\r\n", i));
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}有没有人知道我在试图将文本添加到附加的blob时做错了什么?否则,你知道为什么这只会丢失数据而不会抛出某种异常吗?
我真的很想开始使用它作为我的应用程序日志的存储库(因为它主要是为此目的创建的)。但是,如果日志丢失而没有警告的话,如果日志记录速度超过每秒5-6个日志,那将是非常不可靠的。
如有任何想法或反馈,将不胜感激。
发布于 2015-10-13 18:09:42
我现在有一个工作解决方案,基于@肇星路-微软提供的信息。根据API文档,AppendTextAsync()方法只应在单写入器场景中使用,因为API内部使用附加偏移条件标头以避免重复块,而这些块在多作者场景中不能工作。
下面是通过设计指定此行为的文档:https://msdn.microsoft.com/en-us/library/azure/mt423049.aspx
因此,解决方案是使用AppendBlockAsync()方法。以下实现似乎正确工作:
for (int i = 0; i < 100; i++)
{
var message = string.Format("Appending log number {0} to an append blob.\r\n", i);
var bytes = Encoding.UTF8.GetBytes(message);
var stream = new MemoryStream(bytes);
tasks[i] = blob.AppendBlockAsync(stream);
}
Task.WaitAll(tasks);请注意,在本例中,我没有显式地释放内存流,因为该解决方案将导致在using块内包含一个带有异步/等待的using块,以便在处理内存流之前等待异步附加操作完成.但这导致了一个完全不相关的问题。
发布于 2015-10-13 00:40:09
您使用的async方法不正确。blob.AppendTextAsync()是非阻塞的,但它返回时并没有真正完成。在退出进程之前,您应该等待所有的async任务。
以下代码是正确的用法:
var tasks = new Task[100];
for (int i = 0; i < 100; i++)
tasks[i] = blob.AppendTextAsync(string.Format("Appending log number {0} to an append blob.\r\n", i));
Task.WaitAll(tasks);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();https://stackoverflow.com/questions/33088964
复制相似问题