Глубина очереди что это
Глубина очереди что это
Калькулятор IOPS позволяет оценить производительность дисковой подсистемы сервера.
В зависимости от типа контроллера и накопителей, режима кэш, числа накопителей, глубины очереди и характера нагрузки вычисляются производительность, задержка и емкость для массивов RAID 0/10/5/6.
Операция ввода/вывода – операция чтения или записи, выполняемая дисковой подсистемой. Различают операции последовательного и случайного доступа.
Запрос – задание дисковой подсистеме на выполнение операции чтения или записи.
Глубина очереди – количество одновременных запросов на чтение или запись.
Задержка – среднее время выполнения запроса.
Strip – блок данных, который записывается на один диск RAID-массива. Размер этого блока задается при создании RAID-массива.
Stripe – суммарный размер одной записи на всех дисках RAID-массива без учета данных четности.
Калькулятор IOPS поддерживает все типы RAID-контроллеров, которые используются в серверных системах нашей сборки:
Для контроллеров с кэш-памятью возможен выбор режимов Write Through и Write Back.
Выбор контроллера накладывает ограничения на максимальное количество дисков, а также их интерфейс.
Например, для встроенных контроллеров количество дисков ограничено числом портов – 4, 6 или 8. Хотя эти контроллеры могут работать с расширителями портов, на практике это применяется редко.
Для SATA-контроллеров нельзя выбрать диски с интерфейсом SAS. Кроме того, не все контроллеры поддерживают все типы RAID-массивов.
Калькулятор IOPS поддерживает все типы используемых нами в производстве серверов Team современных серверных жестких дисков: 2.5″ и 3.5″ с интерфейсами SAS и SATA и скоростью вращения 7200, 10000 и 15000 оборотов в минуту.
Калькулятор также поддерживает современные твердотельные накопители (SSD) с интерфейсами SATA3 (6Gb/s), SAS3 (12Gb/s), NVMe (4GB/s).
Жесткие диски одного класса, но разных производителей (например, диски SAS 2.5″ со скоростью вращения 7200 оборотов в минуту), могут заметно различаться по производительности. Наличие промежуточной неотключаемой энергонезависимой кэш-памяти в некоторых моделях накопителей позволяет в разы увеличить скорость на операциях случайной записи.
В подавляющем большинстве приложений дисковая подсистема сервера работает в режиме случайного доступа, осуществляя чтение и запись данных, расположенных в массиве произвольным образом.
Когда необходимо оценить производительность последовательного чтения или записи, можно считать, что скорость массива будет кратна количеству дисков в массиве (при условии, что размер блока данных больше размера Stripe). Это справедливо даже для массивов с вычислением четности, поскольку в этом случае выполняется запись целого страйпа и блока четности без предварительного чтения «старых» данных.
Глубина очереди – это количество одновременных запросов на чтение или запись, которые сервер посылает дисковой подсистеме. Если глубина очереди равна единице, то следующий запрос посылается только после получения подтверждения о выполнении предыдущего запроса. Если глубина очереди больше единицы, сервер сразу посылает несколько запросов и в дальнейшем поддерживает заданную глубину очереди по мере их выполнения.
Для начала рассмотрим понятие глубины очереди применительно к одиночному диску.
Чем больше глубина очереди, тем больше запросов жесткий диск может обработать за единицу времени. Это объясняется тем, что диск выстраивает последовательность обработки запросов таким образом, чтобы маршрут движения головок был оптимальным с точки зрения минимизации времени операций. Чем больше глубина очереди, тем больше у диска выбор и тем эффективнее оптимизация.
Диски SATA могут обрабатывать до 32 одновременных запросов, диски SAS – до 64. При максимальной глубине очереди производительность диска увеличивается примерно в три раза по сравнению с одиночными запросами.
Когда мы говорим о глубине очереди применительно к RAID-массиву, картина меняется. При глубине очереди 1 мы не получим выигрыша в производительности по сравнению с одиночным диском, поскольку в массиве будет работать всегда только один диск. А вот если массив получит сразу столько запросов, сколько он имеет дисков в своем составе, мы получим рост производительности, пропорциональный числу дисков.
Правда, следует заметить, что запросы совсем необязательно распределятся равномерно между всеми дисками массива, поэтому реальный рост производительности будет меньше. Например, для массива из двух дисков только в половине возможных случаев запросы будут приходиться на разные диски, поэтому производительность вырастет всего в полтора раза (на самом деле немного больше, поскольку в другой половине случаев на каждый диска придет по два запроса и производительность дисков вырастет за счет оптимизации). Наш Калькулятор IOPS точно учитывает эти моменты для любого количества дисков и любой глубины очереди.
Оптимальным является вариант, когда на каждый диск массива приходится один запрос. При дальнейшем увеличении глубины очереди производительность массива растет гораздо медленнее задержки, которая прямо пропорциональна глубине очереди. Именно поэтому при расчете производительности массива глубина очереди по умолчанию принимается равной количеству дисков. Однако ее можно поменять, чтобы увидеть, как при этом будут меняться производительность и величина задержки.
В массиве RAID 0 чтение будет выполняться параллельно с каждого диска массива, поэтому производительность массива будет равна произведению производительности одного диска на число дисков в массиве.
Для RAID 5 и RAID 6 картина точно такая же. Поскольку данные четности распределены между всеми дисками равномерно, при чтении будут задействованы все диски.
А вот для RAID 10 с аппаратным контроллером производительность будет даже выше, чем у RAID 0, поскольку чтение будет выполняться с того диска зеркальной пары, головки которого ближе к нужному сектору.
Для операций записи ситуация другая, кроме RAID 0. Для RAID 0 производительность по мере увеличения количества дисков в массиве растет так же, как в случае с чтением. RAID 10 медленнее в два раза, поскольку должен записывать одни и те же данные на два диска.
Для массива RAID 5 каждый запрос на запись порождает 4 операции: чтение «старого» блока данных, чтение четности, запись «новых» данных и запись четности. Поэтому теоретически RAID 5 при том же количестве дисков медленнее RAID 0 примерно в 4 раза. Однако на самом деле производительность определяется типом контроллера. Для контроллеров Adaptec реальная производительность неплохо согласуется с теоретической, а вот для контроллеров LSI с увеличением количества дисков производительность не растет, хотя при небольшом количестве дисков они работают быстрее, чем Adaptec. Разница объясняется тем, что LSI максимально оптимизирует свои алгоритмы для работы с массивами с небольшим числом дисков, поскольку не делает контроллеры с количеством портов более 8, в то время как Adaptec ориентируется в том числе и на массивы с большим количеством дисков и предлагает контроллеры и с 16 и с 24 портами.
Все вышесказанное относится и к массивам RAID 6 с той разницей, что для выполнения одного запроса на запись требуется уже шесть операций: три чтения и три записи.
Включение кэша контроллера на запись (режим Write Back) увеличивает производительность массивов любого типа примерно на порядок, поскольку данные записываются сначала в «быструю» память контроллера. Перенос данных из кэша на диски осуществляется в фоновом режиме, при этом контроллер «выжимает» из массива максимально возможную производительность в IOPS за счет оптимизации внутренней очереди запросов, поскольку величина задержки при переносе данных из кэша на диски в этом случае не имеет значения.
В реальных серверных конфигурациях включение режима Write Back рекомендуется только при наличии защиты кэша контроллера от потери питания (батарейной или на базе флэш-модулей). В противном случае велик риск потери большого объема данных.
Все современные жесткие диски имеют некоторый объем «быстрой» кэш-памяти – обычно 64 или 128 MB. Если эта память включена (Disk Cache ON), то данные записываются сначала в эту память и запрос считается выполненным. Затем диск в фоновом режиме переписывает информацию на магнитные пластины. Включение кэш значительно (в разы) увеличивает производительность диска, поскольку диск переписывает содержимое кэш на пластины, оптимизируя процесс перемещения головок.
Поскольку кэш-память дисков обычно энергозависима, потеря питания приведет к потере всех данных в кэш диска, поэтому включать ее рекомендуется только при наличии резервирования по питанию.
Одновременное включение кэш-памяти дисков и контроллера не всегда дает прирост производительности по сравнению с включением только кэша контроллера. В отдельных конфигурациях производительность может несколько снизиться. Причина в том, что фоновые процессы дисков могут тормозить работу алгоритмов контроллеров.
Производители жестких дисков и твердотельных накопителей указывают емкость этих устройств в GB (Гигабайтах) или TB (Терабайтах). При этом под одним гигабайтом понимается величина 10 9 байт, а 1 TB – это 10 12 байт.
Емкость RAID-массива обычно указывается тоже в Гигабайтах или Терабайтах, но при этом 1 GB считается равным 1024 3 байт, а 1 TB – 1024 4 байт.
Большое спасибо за предложение! Такая возможность появится в следующей версии калькулятора.
Управление глубиной очереди дисков для достижения лучшей производительности
По материалам статьи Джо Чанг (Joe Chang): I/O Queue Depth Strategy for Peak Performance (IO Queue Depth Strategy)
Перевод: Александр Гладченко
Технический редактор: Ирина Наумова
Литературный редактор: Мария Гладченко
В большинстве случаев для SQL Server применяются незамысловатые модели управления глубиной очередей ввода-вывода. Ниже представлены основанные на практике рекомендации по оптимизации очереди ввода-вывода, при использовании более развитых моделей дисковых подсистем, SSD – дисков и высокопроизводительных систем хранения.
Автор, наконец, нашёл время для тестирования массива твердотельных дисков (SSD), собирая в массивы от нескольких до 20 устройств, управляемых двумя контроллерами с 4×4 портами Serial Attached SCSI (SAS). Во время предварительных тестов, когда глубина очереди обращения к дискам была очень высокой, он наблюдал большую задержку обращения к дискам, которая во время проведения ряда операций для чтения превышала 100ms и достигала более 400ms для операций записи.
Таким образом, возникают следующие вопросы:
Давайте начнём искать ответы на эти вопросы, исследуя принципы использования одиночного диска, после чего необходимо будет проделать все тесты с дисковым массивом под управлением кэширующего RAID контроллера, а затем, уже в конце мы поработаем с полномасштабной системой хранения, подключённой через сеть хранения данных (SAN) и адаптированной для использования SSD дисков. Если обратиться к распространённым рекомендациям по настройке систем хранения, можно увидеть, что они зачастую цитируются без ссылок на соответствующие исследования или явного указания контекста их применимости. Мы же попытаемся проникнуть в самую суть вещей, и понять, почему упрощённая модель организации глубины очереди ввода-вывода, используемая SQL Server для доступа к листовому уровню таблиц, может быть улучшена за счёт более развитых моделей работы с дисками, а также за счёт использования SSD дисков и высокопроизводительных систем хранения данных (СХД).
Теория жёстких дисков (что такое IOPS)
Стандартная теория ввода-вывода подразумевает, что при случайном типе доступа к диску среднее время доступа к данным равно сумме задержек следующих операций:
Для запросов ввода-вывода с маленькими величинами блоков данных существенны только два первых слагаемых. Для дисков с 15000 оборотами на шпинделе (15K) среднее значение «rotational latency» составляет 2 ms, а для типичного 3,5 дюймового диска с 15K среднее число «seek time» около 3,4 ms. Включая эти два наиболее весомых значения и другие, менее значимые составляющие, общее время доступа может достигать в среднем до 5,5 ms. В результате чего можно выделить два ключевых признака:
А очень часто просто забывают упомянуть про эти два ключевых фактора!
В случае если доступ осуществляется к данным, хранящимся на относительно небольшой группе сопредельных цилиндров диска, среднее время поиска будет меньше, а при глубине очереди равной 1 производительность в IOPS-ах окажется выше.
Случайное чтения с жёсткого диска и варьирование глубины очереди – сравнение в IOPS-сах
Давайте теперь обратимся к смыслу второго из упомянутых выше факторов, и попытаемся сопоставить в IOPS-ах случайное чтение и чтение при разной глубине очереди. При более глубокой очереди можно наблюдать множество запросов ввода-вывода к диску, которые обслуживаются вместе, или возможно обслуживание более поздних запросов ввода-вывода до завершения более ранних. Дисковый контроллер может переупорядочить ввод-вывод, стараясь сократить время между отдельными порциями ввода-вывода, что позволяет увеличить IOPS-ы и при этом получить более высокие значения задержек для каждого отдельного запроса ввода-вывода.
Ситуация становится незначительно лучше, если увеличить глубину очереди до 2-х. Можно получить до 200 IOPS, против упомянутых выше 180-ти. Ещё лучше результаты получаются при глубине очереди равной 4 – 240 IOPS. Если продолжить удваивать глубину очереди вплоть до 32-х, можно получить ещё небольшой прирост на каждое приращение, порядка 40-50 IOPS каждое. После этого, до глубины очереди равной 64 увеличение будет совсем незначительное. К слову, диски, выпущенные до 2005 года, могли обслуживать очереди до 64 задач. Современным дискам по плечу очередь глубиной 128. При каждом удвоении глубины очереди также происходит практически удвоение задержки.
На рисунке №1 показано какой эффект оказывает увеличение глубины очереди на производительность в IOPS. На рисунке видно, что при глубине очереди запросов ввода-вывода равной 64-м, когда данные распределены по всему диску, удавалось получить до 400 IOPS. Другой, граничный случай, когда данные занимали 2,8% диска, примечателен повышением производительности относительно других измерений, с меньшими глубинами очереди. Так, например, для глубины очереди 1, удалось достичь почти 300 IOPS.
Рисунок 1: Зависимость производительности в IOPS от глубины очереди при разном объёме данных не диске.
Если грамотно учесть оба фактора, можно поднять производительность до 600 IOPS на диск.
Рисунок 2: Зависимость задержки от глубины очереди при разном объёме данных не диске.
На рисунке №2 показано, как зависит величина задержки доступа от глубины очереди при разном проценте заполнения диска данными. При большой глубине очереди и когда данные занимают весь диск, величины задержек достигают самых больших значений.
Если процент запрашиваемых данных невелик, то потери от задержек будут заметно меньше, даже если глубина очереди велика. Снижение глубины очереди или процента запрашиваемых с диска данных положительно сказывается на производительности жёсткого диска, но когда оба фактора задействованы одновременно, выигрыш поистине впечатляющий. Для характерных OLTP нагрузок время отклика (а, следовательно, и задержка ввода-вывода диска) имеет такое же большое значение, как и такой показатель производительности, как пропускная способность. Именно поэтому, такое большое распространения получило правило поддерживать для OLTP среднюю глубину очереди, которая не превышает двух запросов на диск (шпиндель). Это правило было популярно в то время, когда наибольшее распространение имели диски со скоростью вращение шпинделя 7200 и 5400 об/мин.
При пакетной обработке данных, когда нет пользователей, ожидающих завершения каждой транзакции, правило управления глубиной очереди сводится к увеличению глубины, что может положительно сказаться на производительности и пропускной способности. Однако, при работе с хранилищами данных систем поддержки принятия решений (DSS), принято руководствоваться правилом, которое гласит, что можно задействовать ту часть пропускной способности, которая в данный момент не используется.
Стоит особо подчеркнуть важность перечисленных ключевых факторов, поскольку до сих пор принято было опираться на правило, которое гласит: «глубина очереди одного диска должна быть не выше 2».
RAID – контроллеры и дисковые массивы
В былые времена мы оперировали в основном группами дисков (JBOD). Популярные РСУБД учитывали этот подход, обеспечивая поддержку для баз данных множества файлов и файловых групп. Затем появились light-RAID (не путать с названием книги) и RAID- контроллеры. Все увидели, что RAID позволяет значительно сократить количество “дисков″, которыми приходится управлять на уровнях базы данных и операционной системы. Дисковый массив представляется в последней как один логический диск, а счётчики производительности, обычно, используются те, что предоставляет она, а не система хранения данных (СХД).
Правило, по которому глубина очереди не должна для одного диска превышать 2 (и другие сопутствующие признаки) не соотносятся напрямую с глубиной очереди, определённой по счётчикам производительности операционной системы. Таким образом, получило распространение несколько иное правило, гласящие, что задержки при обращении к диску не должны превышать примерно 10 – 20 ms, что было вычислено из прежнего правила глубины очереди 2 на диск (вероятно, для дисков с 7200/10000 об/мин), причём, без учёта описанных выше дополнительных признаков.
В большинстве случаев задержка доступа к данным ниже 10 ms говорит о том, что время отклика транзакции считается очень хорошим. Задержки в диапазоне 10 – 20 ms говорят о приемлемом времени отклика транзакции. Задержки больше 20 ms говорят о большой загруженности дисковой подсистемы. Важно понимать, что появление кратковременных скачков ввода-вывода может привести к тому, что рассчитанная по задержкам глубина очереди может оказаться высокой, в то время как время отклика будет характеризоваться картиной с острыми пиками значений. Т.е. несмотря на то, что среднее время отклика транзакции можно считать приемлемым, может существовать большое число запросов с очень плохим временем отклика.
Что происходит с глубиной очереди для RAID массива при случайном чтении
Как повлияет на характеристики ввода-вывода использование нескольких дисков, собранных в один RAID – массив? Если происходит чтение с такого логического диска, то это равносильно тому, что ввод-вывод будет направлен только на один диск массива (то есть, глубина очереди = 1), и всего один из дисков обслужит ввод-вывод. Остальные диски будут практически невостребованны, пока активность из расчёта на один диск не превысит 180 IOPS, направленных на эту группу дисков в RAID – массиве. При глубине очереди 2, вероятно, что пара запросов ввода-вывода распределилась бы между разными дисками, таким образом, что два диска будут работать с глубиной очереди 1, а остальные диски останутся неактивными. Очередь к одному диску массива станет больше единицы только тогда, когда нагрузка на массив превысит возможности обслуживания без очередей запросов ко всем дискам, которые сегодня позволяют получать 180 IOPS при 15 K оборотов на шпинделе, и с небольшой корректировкой из-за вероятности неравномерного распределения нагрузки.
Глубина очереди всего массива будет поделена между несколькими очередями к его отдельным дискам и, в зависимости от производительности в IOPS-ах входящего в массив диска, будет определяться зависимость производительности от глубины очереди к RAID – массиву. Тут важным моментом является то, что при глубине очереди 1, запрос ввода-вывода попадёт на один из дисков со своими характеристиками по IOPS, которые будут отличаться от производительности в IOPS-ах всей дисковой группы RAID – массива.
Задержка записи в журнал
В те времена, когда диски подключались напрямую к серверу, распространённой рекомендацией было использовать для файла журнала отдельный массив RAID1, т.е. пара зеркальных дисков рекомендовалась для каждого журнала транзакций базы данных с высокой транзакционной нагрузкой. Об этом редко говорят, но наиболее характерным значением величины задержки для операций записи в журнал (которые имеют характер последовательного ввод-вывода и маленький размер блока запроса) была величина, сопоставимая с 0.3ms, что приблизительно соответствовало 3000-5000 IOPS.
Производители оборудования сетей SAN часто рекомендуют не беспокоиться о выделении отдельных физических дисков для каждого журнала транзакций высокотранзакционной базы. Подразумевается, что внешняя дисковая подсистема, настроенная по рекомендациям вендора, сама прекрасно справится с этой задачей. Однако, такие результаты с очень низкой задержкой записи в журнал, как у напрямую подключённых дисков (которые, к тому же, могут обслуживаться выделенным процессором) для сетей SAN всё ещё недостижимы. Поскольку системы хранения в сетях SAN получают всё большее распространение, Microsoft внёс изменения в ядро хранения SQL Server, чтобы обеспечить возможность многопоточной записи в журнал транзакций (SQL Server 2000 SP4 и 2005 RTM позволяли обслуживать 8 одновременных запросов ввода-вывода в журнал транзакций каждой базы данных). SQL Server 2005 SP1 позволяет одновременное обслуживание 8 запросов ввода-выводов для 32-разрядной редакции SQL Server и 32-х запросов ввода-вывода для 64-разрядной редакции сервера, с предельным размером запроса 480KB. В SQL Server 2008 предельный размер повышен до 3840KB.
Случайная запись на RAID маленькими блоками
В этой статье мы не станем рассматривать те издержки записи, которые происходят внутри RAID. Однако нужно отметить, что правила для RAID5 и RAID10 часто цитируются без учёта описанных выше признаков. Как правило, говорят о производительности операций записи RAID5 и только применительно к случайной записи маленькими блоками. На контроллере без кэширования можно получать производительность ввода-вывода для записи в IOPS близкую к аналогичным характеристикам для чтения. Стоит отдельно отметить, что результаты сравнения могут отличаться для разных уровней RAID, поскольку у них разные издержки, а также на это может влиять специфика выбранной модели контроллера.
Кэширующие RAID – контроллеры и запросы ввода-вывода на чтение
В других статьях блога автор уже объяснял, почему такое кэширование запросов на чтение непродуктивно. В основном это объясняется тем, что ядро базы данных само кэширует данные, и этот кэш намного ближе и менее затратен с точки зрения доступа, чем кэш контроллера СХД. Кроме того, если сервер сконфигурирован в соответствии с рекомендациями, ядро базы данных будет иметь буферный кэш существенно большего размера, чем кэш СХД. Вероятность того, что к данным в кэше СХД будет осуществляться повторный доступ, очень мала. К тому же, издержки на кэширование запросов чтения являются для них весьма существенными, и это важный фактор для тех СХД, которые настраиваются на получение высоких значений IOPS. Издержки кэширования чтения на контроллерах СХД будут потому, что блоки данных в кэше никогда не будут запрашиваться снова, это работа будет бесполезна. У систем, которые используются в эталонных тестах TPC, кэширование чтения обычно отключается, и делается это из соображений, которые были только что перечислены.
Один уважаемый источник утверждал, что использование маленького
2MB (не GB!) кэша чтения для LUN, позволяющего включить упреждающее чтение, является наиболее удачной стратегией. Я же помню, когда-то говорили, что некоторая система с сервером, у которого было 48GB оперативной памяти, показала лучшую производительности ввода-вывода, когда кэш на SAN был увеличен с 80GB до 120GB. Всё это показывает, что подобные результаты можно рассматривать под разными углами.
Кэширующие RAID – контроллеры и запросы ввода-вывода на запись
А теперь давайте обратимся к показателям производительности запросов ввода-вывода для записи, носящих случайный характер и обсуживающихся кэширующим RAID – контроллером. До сих пор, мы только ходили вокруг запросов ввода-вывода на запись, но на это есть своя причина. На Рисунке 3 показана производительность в IOPS для случайных запросов на запись с маленьким блоком, которые обслуживает кэширующий RAID – контроллер. Когда SQL Server или операционная система посылают RAID – контроллеру один или более запросов ввода-вывода для записи, записываемые данные помещаются в кэш контроллера, а серверу отправляется сообщение о завершении операции записи. После этого, становится возможным отправка следующего запроса ввода-вывода. При этом каких либо заметных изменений в производительности СХД в IOPS не произойдёт, хотя глубина очереди будет расти. Будет наблюдаться очень низкая задержка операций записи, пока не будет преодолено наивысшее значение IOPS для возможностей кеширующего контроллера.
Рисунок 3: пример IOPS для случайных запросов записи с маленьким блоком и с кэширующим RAID – контроллером
После преодоления этого порога, когда кэш записи будет заполнен, величина задержки запроса станет высокой, пока сервер не вернётся в исходное состояние, с небольшим объёмом запросов ввода-вывода на запись.
Большие СХД с большими наборами RAID
На протяжении нескольких лет СХД становились всё более мощными, их вычислительные возможности увеличивались на 40% ежегодно. В то же время производительность жёстких дисков в год растёт не так заметно, в среднем меньше чем на 10% (от 7,2K к 10K и к 15K, и это ничто по сравнению с SSD). Этот разрыв в росте вызвал необходимость создания СХД с очень большими количествами дисков. Именно в те времена получили распространение сети SAN, которые придумали специально для больших СХД.
Очень быстро стало понятно, что SAN не могут обеспечить ожидаемую производительность в IOPS, которую может суммарно выдать задействованное число дисков. Первая причина этого заключается в возможностях контроллера адаптера шины Fibre Channel (FC HBA), для которого глубина очереди по умолчанию составляла 32 (на адаптер, а не на порт СХД). Такое ограничение для значения очереди по умолчанию было введено из тех соображений, что доктриной SAN считается следующее: SAN – это поставщик совместно используемого дискового пространства. Ограничение призвано препятствовать тому, чтобы один узел создавал слишком большую нагрузку ввода-вывода. Для ограничения нагрузки, на HBA для глубины очереди устанавливали маленькое значение, в результате чего все узлы могли бы гарантировано получать свою долю от максимально возможного объёма ввода-вывода.
Если измерить зависимость IOPS от установки глубины очереди на HBA для внешнего LUN, состоявшего из большого числа дисков, станет видно, что производительность в IOPS увеличивается с увеличением глубины очереди от минимальных до максимальных значений. Это поведение похоже на то, о котором мы говорили выше, когда обсуждали зависимость производительности RAID массивов в IOPS от глубины очереди.
Если увеличивать глубину очереди с минимума до максимально возможных значений, можно достичь близкую к максимуму пропускную способность, но одновременно получить рост задержек.
Выбор глубины очереди для FC HBA
Важно помнить, что раньше глубина очереди устанавливалась ко всем портам HBA или для каждого оптического порт HBA в отдельности. У последних моделей Emulex FC HBA значением по умолчанию для глубины очереди устанавливается 32 на каждый LUN. Можно настроить глубину для LUN или для всего получателя (target). QLogic использует для этого термина «Execution Throttle» и глубина по умолчанию равна 256. Как то, в одном из отчётов к эталонному тесту TPC-C, в котором использовалась система с сетью хранения SAN, была дана ссылка на зависимость производительности от изменения глубины очереди HBA: глубина менялась от 32 до 254 и без каких-либо дополнительных разъяснений. В системах для TPC-C всегда используются очень большое количество дисковых массивов. Конечно же, для таких систем следует выбрать установку глубины очереди на HBA в максимальное значение. В упомянутом документе об этом было сказано в краткой форме, и рекомендовано изменить глубину очереди HBA с 32 до 254, что соответствует рекомендованным практикам, часто встречающимся в документах Microsoft. Те документы, которые я видел, не содержали в себе объяснения первопричины такого эффекта и в них отсутствовали рекомендации по поддержке данного варианта настроек.
Стоит поговорить о конфигурации SAN с небольшим числом дисковых массивов. Резонен вопрос, нужно ли менять стандартную установку глубины очереди на LUN, если каждый LUN состоит из четырёх дисков? Требуется ли в таком случае увеличивать глубину очереди до 254? Ответ будет зависеть от тех инструкций, которые были даны ранее при обсуждении зависимости производительности в IOPS и задержек от глубины очереди, с учётом поправок на число дисков, которые относятся к LUN. Необходимо взвесить все за и против, и в дальнейшем исходить из того, является ли вашей целью обеспечение высокой скорости отклика, присущей OLTP системам, или вы предпочитаете работать с чистой пакетной/DSS нагрузкой.
Последовательный ввод-вывод
Все разговоры о зависимости IOPS от глубины очереди до сих пор не касались варианта с последовательным дисковым вводом-выводом. Последовательного ввода-вывода с большими блоками и глубиной очереди 1 на каждый LUN может оказаться вполне достаточно, чтобы утилизировать максимальную пропускную способность ввода-вывода, при условии, что эта нагрузка достаточно большая, и её хватало бы для загрузки всех дисков, из которых состоит LUN. Автор склонен полагать, что, следуя теории, размер нагрузки ввода-вывода помноженный на глубину очереди должен быть больше чем число дисков в массиве, помноженное на размер блока RAID – массива (размер сегмента/чанка/блока страйпа). Эта уверенность основывается на том, что у каждого диска будет для обслуживания своя доля ввода-вывода, даже, несмотря на то, что у автора не было возможности проверить эту гипотезу практическими тестами.
Увеличение глубины очереди от минимального значения в попытке достигнуть близкой к максимуму пропускной способности, приведёт только к увеличению задержек. В том случае, когда мы имеем дело со смешанной рабочей нагрузкой, когда обслуживается смесь из запросов с маленьким и большим блоком, можно попробовать более высокую глубину очереди. Для больших блоков это, в принципе, может поднять пропускную способность, но автор это тоже не проверял. Что касательно сетей SAN, то для них существуют некоторые предположения, согласно которым увеличение глубины очереди может помочь достичь максимальной пропускной способности при последовательной нагрузке, когда на одном RAID массиве создано несколько LUN. Сколько-нибудь подробных разъяснения на этот счёт автором найдено не было.
Характеристики ввода-вывода SQL Server
Есть несколько документов Microsoft, которые подробно описывают ввод-вывод SQL Server. Этот список включает:
Синхронный и асинхронный ввод-вывод SQL Server
При случайном доступе с размером запроса 8KB (что характерно для таких операторов Плана исполнения запроса, как Поиск Закладок и LOOP JOIN) SQL Server может переключиться с синхронного ввода-вывода на асинхронный. В этом случае он будет использовать порции приблизительно по 25 строк.
Рассмотрите ситуацию, обычную для транзакционных систем, которые также обслуживают задачи отчётности. Транзакции состоят из нескольких последовательно обслуживаемых запросов ввода-вывода с глубиной очереди 1. Отчёт – это запрос, который может генерировать несколько сотен запросов ввода-вывода, обслуживаемых асинхронно с большой глубиной очереди. Предположим, что для транзакций, которые будут присутствовать в данном случае, средняя глубина очереди на один диск составит 1, а средняя задержка доступа составит 5ms. Допустим, что для транзакции нужно 20 синхронных запросов ввода-вывода, которые по нашим выкладкам завершаться за 100 ms, что является разумным временем отклика. Теперь выполним сценарий отчёта, который генерирует асинхронный ввод-вывод и он достигает значений глубины очереди к диску порядка 8, с задержками около 30 ms. Отчёт выполнится быстро, потому что СХД обеспечивает 350 IOPS на диск. Но зато транзакция с 20 последовательными запросами ввода-вывода теперь отработает за 600ms. Хотя со стороны может показаться, что отчёты имеют более высокий приоритет, чем обслуживание коротких транзакций.
Замечания относительно Tempdb
Часто ввод-вывод SQL Server в системную базу данных tempdb характеризуется большой глубиной очереди. Это происходит потому, что запросы к этой базе характеризуются большими операциями с хэшами или сортировками. Если бы для таких операций нужно было меньше ресурсов, то работа с ними выполнялись только в оперативной памяти. Таким образом, виновниками в нагрузке на tempdb часто становятся слишком большие для данной системы запросы, которые порождают запросы асинхронного ввода-вывода с большой глубиной очереди.
Если руководствоваться только простым правилом что задержки ввода-вывода должны быть ниже 20 ms, то можно сделать вывод о перегрузке выделенных под tempdb дисков, потому что средние значения задержек будут очень большими. На самом же деле SQL Server просто старается держаться в рамках стратегии достижения максимальной производительности, используя для этого метрики, которые ориентированы на пропускную способность. Правильной метрикой в данном случае будет возможность дисков под tempdb обслужить достаточный для поддержания высокой производительности объем запросов ввода-вывода, и не факт, что при этом объём ввода-вывода с tempdb должен быть низким.
При сканировании таблиц ввод-вывод SQL Server организован таким образом, чтобы попытаться склеить упреждающим чтением 1024 страницы для редакции Enterprise Edition, или 128 страниц упреждающего чтения для редакции Standard Edition.
Большая глубина очереди для SQL Server + SSD
Автор наблюдал у запроса с полным сканированием таблицы, в котором не было подсказок оптимизатору уровня изоляции блокировок, глубину очереди запросов ввода-вывода на чтение порядка 1300. Размер запроса ввода-вывода составлял 8KB, а задержки для операций чтения были больше 200 ms, и это несмотря на то, что данные хранились на SSD дисках. Когда указывалась блокировка таблицы, число запросов ввода-вывода составляло приблизительно 500K (вероятно, основная масса в 512K разбавлялась небольшим вводом-выводом с маленьким размером блока), задержка дисковых операций получалась меньше 50 ms, а глубина очереди была приблизительно 40. Для поиска по ключу мы наблюдали ввод-вывод блоками 8 КB c глубиной очереди приблизительно 160, и с задержкой порядка 7 ms. Когда использовалось СХД с приблизительно 20 HDD дисками, глубина очереди была около 160, это приблизительно 8 на один диск, что было вполне приемлемо для производительности ввода-вывода, и результирующие задержки ещё не составляли проблемы.
Marc Bevand в блоге Zorinaq’s указал, что число IOPS при глубине очереди 1 являются по существу мерой задержки. Предположим, что SSD имеет задержку 100 µs, и обеспечивает 30K IOPS для 8 KB IO (30K x 8KB = 240 MB). Получается, что при глубине очереди 1 в IOPS должно получатся 10K (1000000 µs/s/100µs). Таким образом, теория говорит нам о том, что глубина очереди 3 или больше может обеспечить производительность до 30K IOPS. Удержание глубины очереди, близкое к её минимальным значениям, необходимо, чтобы не пострадала максимальная производительность в IOPS для запросов, которые порождают огромные объёмы ввода-вывода, и для того, чтобы обеспечить хорошее время отклика для других, выполняющихся параллельно запросов.
Большая задержка записи при создании кластеризованных индексов
Команда CREATE CLUSTERED INDEX, как показывали наши наблюдения, сопровождалась очень высокой задержкой для записи. Глубина очереди достигала 500, задержка превышала 600 ms, а размер запроса ввода-вывода составлял в среднем 100 KB. Поскольку такие высокие значения задержек нежелательны во время работы пользователей, нужно стараться этого не допускать. В любом случае, принуждение СХД обслуживать такой большой ввод-вывод не имеет никакого смысла. И у кэширующих RAID – контроллеров и у SSD при записи предел пропускной способности ввода-вывода может достигаться даже при значительно меньшей глубине очереди. Увеличение объёма ввода-вывода до такой степени негативно повлияет на доступность системы для других запросов ввода-вывода, отправляемых на обслуживание тем же дискам, обслуживающим большой объём операций.
Влияние на статистику ожиданий асинхронных операций
Перед тем, как подвести черту под нашим обзором всего того, что связано с глубиной очереди ввода-вывода, автор хочет кратко коснуться темы зависимости статистики ожиданий от типа операций ввода-вывода. Сегодня можно часто слышать рекомендации по использованию в качестве базовой метрики оптимизации ввода-вывода данных исключительно о статистике ожиданий. Рассмотрим следующий пример: наша СХД состоит из 100 дисков, запрос генерирует 1 миллион операций ввода-вывода – если используется синхронный ввод-вывод с глубиной очереди 1 на каждый диск, или 100 ко всем дискам системы хранения, то мы получим 200 IOPS на один диск или 20000 IOPS для всей СХД. При этом задержка обращения к диску составит 5 ms. Тогда получается, что время исполнения запроса займёт 50 sec. Суммарное время ожиданий (total wait time) составит 5 ms для одного запроса ввода-вывода или 5000 sec для миллиона операций ввода-вывода.
Теперь рассмотрим асинхронный ввод-вывод, при котором глубина очереди к диску будет 16, при 400 IOPS на диск и с задержкой на 40 ms. Запрос с миллионом операций ввода-вывода теперь завершится за 25 sec, но суммарное время ожиданий составит при этом 40000 sec. Этот пример показывает, что всегда важно опираться в своих оценках на правильные метрики и использовать для принятия решения о способах и методах оптимизации ввода-вывода не только статистику ожиданий, но и показания соответствующих счётчиков производительности.
Резюме обзора глубины очереди ввода-вывода
Мы постарались кратко рассмотреть, на какие ключевые компоненты может воздействовать стратегия выбора глубины очереди ввода-вывода. Можно выделить следующие важные моменты:
По мнению автора статьи, SQL Server придерживается заранее установленной стратегии выбора глубины очереди запросов ввода-вывода, которая зависит только от редакции сервера (Standard или Enterprise). Число дисков, из которых собран любой LUN, стратегией не учитывается; характер нагрузки (OLTP или DW/DSS) не учитывается. Однако оптимизировать производительность операций ввода-вывода могут помочь несколько замечаний к той стратегии, которую вы будете реализовывать для своих приложений:
Некоторые представленные выше рекомендации вполне могут реализоваться автоматически. А другие могут потребовать внесения изменений в параметры глобальной конфигурации, которые меняются с помощью системной процедуры sp_configure. В качестве универсального совета можно выделить одно: вносите такие корректировки, которые позволят учесть особенности пользовательской нагрузки, благодаря чему значительно повысится удобство работы пользователей с SQL Server. Сегодня, существует большое количество возможностей загнать SQL Server в «ступор», заставив его обслуживать массированные дисковые операции и огромные очереди, и тогда не помогут даже хранилища с SSD дисками. Только очень большие, отлично сконфигурированные системы хранения могут быть неуязвимы для таких проблем.