Azure VM上SSD磁盘性能下降
我正在使用Windows Azure虚拟机和D2实例(新SSD实例)上的Windows Server 2012数据中心解压缩1.8 GB zip文件,该文件包含51 GB XML文件解压缩。不用说,这个过程可以通过快速磁盘加速,这就是我测试D2实例的原因。Azure VM上SSD磁盘性能下降
但是,我得到的磁盘性能并不令人印象深刻,并且不符合SSD磁盘的性能预期,因为平均而言,写入速度只有20-30 MB/s左右。
我用来解压文件的程序是一个为此唯一目的而开发的自定义.NET控制台应用程序。源代码如下:
static void Main(string[] args)
{
if (args.Count() < 1)
{
Console.WriteLine("Missing file parameter.");
return;
}
string zipFilePath = args.First();
if (!File.Exists(zipFilePath))
{
Console.WriteLine("File does not exist.");
return;
}
string targetPath = Path.GetDirectoryName(zipFilePath);
var start = DateTime.Now;
Console.WriteLine("Starting extraction (" + start.ToLongTimeString() + ")");
var zipFile = new ZipFile(zipFilePath);
zipFile.UseZip64 = UseZip64.On;
foreach (ZipEntry zipEntry in zipFile)
{
byte[] buffer = new byte[4096]; // 4K is optimum
Stream zipStream = zipFile.GetInputStream(zipEntry);
String entryFileName = zipEntry.Name;
Console.WriteLine("Extracting " + entryFileName + " ...");
String fullZipToPath = Path.Combine(targetPath, entryFileName);
string directoryName = Path.GetDirectoryName(fullZipToPath);
if (directoryName.Length > 0)
{
Directory.CreateDirectory(directoryName);
}
// Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
// of the file, but does not waste memory.
// The "using" will close the stream even if an exception occurs.
long dataWritten = 0;
long dataWrittenSinceLastOutput = 0;
const long dataOutputThreshold = 100 * 1024 * 1024; // 100 mb
var timer = System.Diagnostics.Stopwatch.StartNew();
using (FileStream streamWriter = File.Create(fullZipToPath))
{
bool moreDataAvailable = true;
while (moreDataAvailable)
{
int count = zipStream.Read(buffer, 0, buffer.Length);
if (count > 0)
{
streamWriter.Write(buffer, 0, count);
dataWritten += count;
dataWrittenSinceLastOutput += count;
if (dataWrittenSinceLastOutput > dataOutputThreshold)
{
timer.Stop();
double megabytesPerSecond = (dataWrittenSinceLastOutput/timer.Elapsed.TotalSeconds)/1024/1024;
Console.WriteLine(dataWritten.ToString("#,0") + " bytes written (" + megabytesPerSecond.ToString("#,0.##") + " MB/s)");
dataWrittenSinceLastOutput = 0;
timer.Restart();
}
}
else
{
streamWriter.Flush();
moreDataAvailable = false;
}
}
Console.WriteLine(dataWritten.ToString("#,0") + " bytes written");
}
}
zipFile.IsStreamOwner = true; // Makes close also shut the underlying stream
zipFile.Close(); // Ensure we release resources
Console.WriteLine("Done. (Time taken: " + (DateTime.Now - start).ToString() +")");
Console.ReadKey();
}
当我自己的机器用SSD磁盘上本地运行此应用程序,我的表现得到180-200 MB/s的持续贯穿整个解压缩过程。但是当我在Azure虚拟机上运行它时,我会在前10秒左右获得良好的性能(100-150 MB/s),然后降至20 MB/s左右并保持在那里,并定期进一步下降到8-9 MB /秒。它没有改善。整个解压缩过程大约需要42分钟,而我的本地计算机可以在10分钟左右完成。
这是怎么回事?为什么磁盘性能如此糟糕?是我的应用程序做错了什么?
本地和Azure虚拟机上的zip文件都放置在SSD磁盘上,并且该文件被提取到同一个SSD磁盘。 (关于Azure的VM,我使用的是临时存储驱动器,因为这是SSD)
下面是来自Azure的VM提取文件截图:
注意性能是如何在大开始,但随后突然下降,并没有恢复。我的猜测是有一些缓存正在进行,然后当缓存未命中时性能下降。
这里是我的本地机器中提取文件截图:
性能变化了一点,但仍高于160 MB /秒。
这是我在两台机器上使用的相同的二进制文件,它是为x64(非AnyCPU)编译的。 我机器中的SSD磁盘大约有1.5年的历史,所以它不是什么新的或特殊的东西。 我不认为这是一个内存问题,因为D2实例有大约7 GB的RAM,而我的本地机器有12 GB。但7 GB应该足够了,不是吗?
有没有人对发生了什么有任何线索?
非常感谢您的帮助。
新增
我试图监视内存的使用情况,而这样做的提取,我注意到的是,当应用程序开始,修改内存量爆炸,只是不停地增长。虽然这样做,我的应用程序报告的性能很好(100+ MB/s)。然后修改后的内存开始缩小(据我所知,这意味着内存正在刷新到磁盘),性能立即下降到20-30 MB/s。有几次,性能实际上有所提高,我可以看到,当它做到时,修改后的内存使用率增加了。过了一会儿,表现再次下降,我可以看到修改后的内存量减少了。所以看起来数据刷新到磁盘导致我的应用程序性能问题。但为什么?我该如何解决这个问题?
新增
好了,所以我想大卫的建议,并运行在一个D14实例的应用程序,而现在我得到了真正优秀的磁盘性能,稳定180-200 + MB /秒。我将继续测试不同大小的实例,看看我可以走多低,仍然可以获得良好的磁盘性能。就像我用D2实例一样,在具有本地SSD磁盘的虚拟机上,我感觉如此糟糕的磁盘性能似乎仍然很奇怪。
该文件位于何处? C:或D: D系列VM仅临时驱动器D是SSD。所有其他磁盘都是普通驱动器。
如果你需要连接磁盘作为其他驱动器,那么你需要去与G系列VM一起预览的高级存储帐户。
感谢, 苏博德
这应该被张贴到ServerFault,而不是计算器。 – 2014-09-25 11:51:34
你可能是对的。我在这里发布它是因为我怀疑是我的应用程序是问题,而不是服务器上的任何硬件或设置。 – 2014-09-25 11:55:49
嗯......我想,如果你的代码在本地工作正常,但在D级虚拟机中运行时却显示速度恶化问题,这是虚拟机特性的特定情况。顺便说一下:在您调查时,请尝试使用最大(D14)虚拟机进行测试,以消除邻居问题。 – 2014-09-25 12:06:22