Setting Virtual Disk QoS in Hyper-V

article #1042, updated 2541 days ago

Disclaimer: this text is an draft combining references cited at the bottom with experiences. It is not authoritative.

Getting to the Settings

  1. In Hyper-V, enter Settings for a VM, click on a disk image under a controller, open the plus sign, and you’ll see Advanced Features.
  2. Click on that, and you’ll see a checkbox, “Enable Quality of Service management”.
  3. If you check that box, you can enter minimum and maximum IOPS numbers.
  4. If either number is zero, the configuration is inoperative, it reverts to automatic.
  5. It is a separate setting for each disk image of the guest.

Determining Good Values for the Settings

  1. In an administrative powershell on the virtual host, do this, just once forever:
    get-VM | Enable-VMResourceMetering
  2. Run Iometer on the virtual guest.
    • Choose one disk under Disk targets. Set Write IO Data Pattern “Pseudo random”. Set “Test Connection Rate” to 10.
    • Under Access Specifications, scroll to the bottom, choose All in one, and click Add.
    • If you want interesting GUI displays of the I/O readouts, make changes under Results Display.
    • Under Test Setup, open the Cycling Options dropdown and choose carefully. You’ll probably want to Cycle, but which other setting you want depends on the architecture of the guest and possibly the host.
    • Click the green flag button. The chosen disk image is now under load. You may want to try higher numbers for “Test Connection Rate”, but do realize this sets how hard we are trying to stress the server, and if we try too hard bad things can happen :-)
  3. While the disk image is under load, in administrative PowerShell, do this, where GUESTNAME is the name of the virtual guest:
    measure-VM GUESTNAME | fl
  4. You’ll see a number next to AggregatedAverageNormalizedIOPS. If your guest has just one disk image, this is the number you need to study (but do not just plug it into the setting!). If your guest has more than one, you’ll need to split them with the code below.
  5. Splitting the AggregatedAverageNormalizedIOPS number
    Paste the below into your PowerShell on the host, where GUESTNAME is the name of the guest. It will give you separate numbers, including IOPS Averages for every disk image in production.
enable-VMresourcemetering -VMName $VMName 
$VMReport = measure-VM $VMName 
$DiskInfo = $VMReport.HardDiskMetrics
write-Host "IOPS info VM $VMName" -ForegroundColor Green
$count = 1
foreach ($Disk in $DiskInfo)
Write-Host "Virtual hard disk $count information" -ForegroundColor cyan
$Disk.VirtualHardDisk | fl  *
Write-Host "Normalized IOPS for this virtual hard disk" -ForegroundColor cyan
$count = $Count +1 
  1. Once you have your Average Normalized IOPS number for the virtual disk, we need to think about it a bit.
    • On one particular setup with two virtuals having one disk image each, where the number showed at 20,000, I set Maximums all to 7000, and Minimums to 1000. This leaves the hypervisor with lots of headroom for its own maintenance, and causes the hypervisor to keep minimum reservation far from zero, to minimize latency. Obviously the Minimum will be much lower if the RAID on the host is less powerful, and just as obviously if load patterns become evident, maximum will be reduced or increased.
    • More variation will need to be employed, depending on observed numerical and practical performance, changes, and miscellaneous needs. A huge and heavily-used volume should deserve to be bumped up some. Early inspection has already shown that there are virtual hosts out there, otherwise nicely fledged servers, lacking in RAID throughput, where the reported average comes to less than 1,100! All of this has to come into consideration.