Как знают администраторы систем хранения данных, у различных компонентов SAN-сети есть такой параметр как глубина очереди (Queue Depth). Он есть у HBA-адаптера сервера (на котором, например, работает VMware ESX / ESXi) и у порта Storage Processor'а системы хранения (SP). Глубина очереди определяет сколько операций ввода-вывода (IO) может быть одновременно обработано на устройстве.
Как мы уже писали, если до SP со стороны сервера ESX / ESXi используется один активный путь, то глубина очереди целевого порта массива (T) должна удовлетворять следующему соотношению:
T >= Q*L,
где Q - это глубина очереди на HBA-адаптере, а L - число LUN, обслуживаемых SP системы хранения. Если у нас несколько активных путей к одному SP правую часть неравенства надо еще домножить на P - число путей.
Соответственно, в виртуальной инфраструктуре VMware vSphere у нас несколько хостов имеют доступ к одному LUN через его SP и получается следующее соотношение:
T>= ESX1 (Q*L*P) + ESX2 (Q*L*P)+ и т.д.
Queue Depth на серверах
По умолчанию, для хостов VMware ESX / ESXi значение Queue Depth равно 32, как его изменить, читайте у нас тут и вот тут. Теперь внимание: этот параметр имеет значение только когда у вас только одна виртуальная машина на хост-сервере использует конкретный LUN. Если его используют уже 2 машины, то он игнорируется, а в действие вступает следующая расширенная настройка (Advanced Setting - как его задавать описано тут):
Disk.SchedNumReqOutstanding (DSNRO)
Этот параметр также по умолчанию равен 32. Он глобально определяет, сколько операций ввода-вывода (IOs) может максимально выдать одна виртуальная машина на LUN одновременно. В то же время, он задает это максимальное значение в IOs для всех виртуальных машин на этот LUN. То есть, если задано значение 32, то все машины могут одновременно выжать 32 IOs, это подтверждается в статье Jason Boche, где 3 машины генерируют по 32 одновременных IO к одному LUN, а реально к LUN идут все те же 32, а не 3*32:
Здесь видно, что активно выполняется 30 команд (максимально 32) для параметра DQLEN, а остальные 67 остаются в очереди. То есть параметр определяет максимальную планку в IO как для одной машины на LUN, так и для всех машин на LUN.
Важно, чтобы параметры Queue Depth и DSNRO были установлены в одно и то же значение. Это рекомендация VMware. Так что, если вздумаете изменить один из них - не забудьте и про второй. И помните, что параметр DSNRO для хоста - глобальный, а значит будет применяться ко всем LUN, подключенным к хосту.
Target Port Queue Depth на массивах
Для дискового массива (а точнее, SP) очередь - это то, куда он сладывает SCSI-команды в то время, пока обрабатывается и выполняется пачка предыдущих. Нормальный midrange-массив имеет глубину очереди 2048 и более. Если массив получает в очередь команд IO больше значения Target Port Queue Depth, то он назад выдает команду QFULL, которая означает, что очередь заполнена и хост-серверу нужно с этим что-то делать. VMware ESX / ESXi реагирует на это следующим образом - он уменьшает очередь на LUN и периодически (каждые 2 секунды) проверяет, не исчезло ли QFULL, и если исчезло, то начинает постепенно увеличивать глубину очереди для этого LUN (это может занять до одной минуты). Это и есть причины тормозов, которые часто возникают у пользователей VMware ESX / ESXi.
Как управлять очередью и адаптивный алгоритм VMware
Теперь становится понятным, почему мы сразу не выставляем параметр Disk.SchedNumReqOutstanding на хостах VMware ESX / ESXi в максимальное значение - мы можем вызвать QFULL на SP массива. С другой стороны, уменьшать его тоже нехорошо - мы ограничим количество операций IO с хоста на LUN.
Поэтому здесь нужен гибкий подход и он есть у VMware (adaptive queue depth algorithm). Работает он таким образом: мы его активируем с помощью параметров Disk.QFullSampleSize и Disk.QFullThreshold в Advanced Settings. Они влияют вот на что:
QFullSampleSize - если число число ответов QFULL (оно же BUSY) превысит его, то ESX / ESXi наполовину обрежет глубину очереди (LUN queue depth)
QFullThreshold - если число ответов о том, что QFULL или BUSY больше нет, превысит его, то ESX / ESXi будет постепенно увеличивать LUN queue depth на 1 (вроде бы, каждые 2 секунды).
Но сколько бы не уменьшалось DQLEN - ниже заданного нами значения DSNRO оно не упадет. Это защищает нас от неожиданного провала в производительности. Кстати, эти параметры тоже глобальные - так что если один (например, тормозящий) массив с хоста будет подвергаться такому адаптивному эффекту со стороны ESX / ESXi, то и для другого (например, производительного) тоже будут выполняться такие фокусы.
Теперь, что дополнительно можно почитать на эту тему:
То есть мораль всей басни такова - дефолтные зачения DSNRO и Queue Depth подходят для большинства случаев. Но иногда имеет смысл изменить их. Но в этом случае надо учитывать параметры системы хранения данных, структуру SAN, количество LUN и другие параметры, влияющие на производительность ввода-вывода.