Azure VM上的SSD磁盘性能较慢

Azure VM上的SSD磁盘性能较慢,azure,azure-virtual-machine,Azure,Azure Virtual Machine,我正在D2实例(新的SSD实例)上使用一个带有Windows Server 2012数据中心的Windows Azure虚拟机来解压缩一个1.8 GB的zip文件,其中包含一个51 GB的XML文件。不用说,使用快速磁盘可以加快这个过程,这就是我测试D2实例的原因 但是,我获得的磁盘性能并不令人印象深刻,也没有达到SSD磁盘的性能预期,因为我的平均写入速度只有20-30 MB/s左右 我用来解压文件的程序是一个定制的.NET控制台应用程序,专门为此开发。源代码如下: static void Ma

我正在D2实例(新的SSD实例)上使用一个带有Windows Server 2012数据中心的Windows Azure虚拟机来解压缩一个1.8 GB的zip文件,其中包含一个51 GB的XML文件。不用说,使用快速磁盘可以加快这个过程,这就是我测试D2实例的原因

但是,我获得的磁盘性能并不令人印象深刻,也没有达到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();
}
static void Main(字符串[]args)
{
if(args.Count()<1)
{
WriteLine(“缺少文件参数”);
返回;
}
字符串zipFilePath=args.First();
如果(!File.Exists(zipFilePath))
{
WriteLine(“文件不存在”);
返回;
}
字符串targetPath=Path.GetDirectoryName(zipFilePath);
var start=DateTime.Now;
Console.WriteLine(“开始提取(“+start.ToLongTimeString()+”));
var zipFile=新的zipFile(zipFilePath);
zipFile.UseZip64=UseZip64.On;
foreach(Zippentry Zippentry in zipFile)
{
byte[]buffer=新字节[4096];//4K是最佳值
流zipStream=zipFile.GetInputStream(zipEntry);
String entryFileName=zipEntry.Name;
WriteLine(“提取”+entryFileName+”);
字符串fullZipToPath=Path.Combine(targetPath,entryFileName);
字符串directoryName=Path.GetDirectoryName(fullZipToPath);
如果(directoryName.Length>0)
{
Directory.CreateDirectory(directoryName);
}
//以缓冲块的形式解压文件。这与解压到完全大小的缓冲区一样快
//但不会浪费内存。
//即使发生异常,“using”也将关闭流。
长数据写入=0;
长DataWriteTensInclastOutput=0;
const long dataOutputThreshold=100*1024*1024;//100 mb
var timer=System.Diagnostics.Stopwatch.StartNew();
使用(filestreamstreamwriter=File.Create(fullZipToPath))
{
bool moreDataAvailable=true;
while(更多数据可用)
{
int count=zipStream.Read(buffer,0,buffer.Length);
如果(计数>0)
{
streamWriter.Write(缓冲区,0,计数);
数据写入+=计数;
DataWrittensInclastOutput+=计数;
如果(dataWrittenSinceLastOutput>dataOutputThreshold)
{
timer.Stop();
double megabytesPerSecond=(DataWriteTensInclastOutput/timer.Appeased.TotalSeconds)/1024/1024;
Console.WriteLine(数据写入的.ToString(“#,0”)+”字节写入(“+megabytesPerSecond.ToString(“#,0.##”)+“MB/s”);
DataWrittensInclastOutput=0;
timer.Restart();
}
}
其他的
{
streamWriter.Flush();
moreDataAvailable=false;
}
}
Console.WriteLine(datawrited.ToString(“#,0”)+”字节写入);
}
}
zipFile.IsStreamOwner=true;//关闭并关闭底层流
zipFile.Close();//确保释放资源
WriteLine(“完成(所用时间:+(DateTime.Now-start).ToString()+”);
Console.ReadKey();
}
使用SSD磁盘在我自己的机器上本地运行此应用程序时,在整个解压缩过程中,我的性能始终保持在180-200 MB/s。但当我在Azure VM上运行它时,大约在前10秒我就获得了良好的性能(100-150 MB/s),然后它下降到20 MB/s左右并保持不变,并定期进一步下降到8-9 MB/s。这并没有改善。在Azure VM上,整个解压缩过程大约需要42分钟,而我的本地机器大约需要10分钟

这是怎么回事?为什么磁盘性能这么差?是我的应用程序出错了吗

本地和Azure VM上,zip文件都放在SSD磁盘上,并将文件解压缩到同一SSD磁盘。(在Azure VM上,我使用的是临时存储驱动器,因为它是SSD)

以下是从Azure VM提取文件的屏幕截图:

请注意,性能在开始时非常出色,但随后突然下降,并没有恢复。我的猜测是,有一些缓存正在进行,当缓存丢失时,性能会下降

以下是从我的本地计算机提取文件的屏幕截图:

性能略有不同,但仍保持在160 MB/s以上

这是我在两台机器上使用的同一个二进制文件,它是为x64(而不是任何CPU)编译的。 我机器中的SSD磁盘大约有1,5年的历史,所以它不是什么新的或特殊的东西。 我也不认为这是内存问题,因为D2实例有大约7GB的RAM,而我的本地机器有12GB。但是7GB应该足够了,不是吗

有人知道发生了什么事吗

非常感谢你的帮助

已添加
我尝试在提取过程中监控内存使用情况,我注意到,当应用程序启动时,修改的内存量爆炸式增长。虽然这样做了,但我的应用程序报告的性能非常好(100+MB/s)。然后修改后的内存开始收缩(据我所知,这意味着内存正在刷新到磁盘),性能立即下降到20-30 MB/s。有几次,性能实际上得到了提高,我可以看到,当性能得到提高时,修改后的内存使用量增加了。妈妈