Александр Щербинин,
компания "Ай-Теко"
sherbinin@i-teco.ru

Уже долгое время не утихают споры по вопросу, какой величины кэш-память необходима дисковому массиву для эффективной работы. Споры эти порождены главным образом следующими обстоятельствами. Первое - это наследие эпохи мэйнфреймов, когда архитектура дисковых массивов была основана на использовании большой кэш-памяти (так называемые архитектуры cache-centric). Огромная кэш-память дисковых массивов была совершенно необходима для работы мэйнфреймов: по статистике, корректно настроенные приложения обеспечивали при этом 90% попаданий в кэш (cache hits). Сегодня же открытые архитектуры дают возможность использовать системную память для кэширования запросов к данным [1, 2].

Второй момент - наличие большого объема кэш-памяти в современных дисковых массивах класса high-end (несколько десятков гигабайт). Причина в том, что эти массивы разрабатывались в условиях жесткой конкуренции с системами EMC Symmetrix, которые изначально были нацелены на рынок мэйнфреймов и имели кэш соответствующего размера [1].

И наконец, играет роль желание пользователей иметь побольше кэш-памяти в своих дисковых массивах - по принципу "запас карман не тянет", несмотря на то, что модули памяти недешевы. В большинстве случаев такие требования к объему кэш-памяти сильно и необоснованно завышены, что приводит к заметному увеличению стоимости решения.

Для того, чтобы понять, "сколько вешать в граммах", надо уяснить, для чего и как служит кэш-память в дисковых массивах. Свой ответ на этот вопрос дают специалисты компании НР (http://www.hp.ru) - разработчика технологии виртуализации ресурсов хранения Versastor, реализованной в дисковых массивах Enterprise Virtual Array (EVA). Контроллеры HSV-1x0, используемые в EVA, имеют "всего лишь" 2 Гбайт кэш-памяти - по современным меркам это вовсе не много. Однако известно, что контроллеры HSG-80, использовавшиеся в предшествующей линейке дисковых массивов ЕМА, имели 1 Гбайт кэш-памяти, но по производительности превосходили конкурирующие устройства с объемом кэш-памяти 8 и даже 16 Гбайт. Контроллеры же HSV-1x0 обладают значительно лучшими характеристиками по сравнению с HSG-80. Подтверждением служат результаты тестирования массивов EVA, опубликованные на сайте http://www.storageperformance.org. Значит, дело не в объеме кэш-памяти, а в эффективности алгоритмов ее использования. В этой статье мы постараемся разобраться, почему небольшой кэш может работать весьма эффективно.

Кэш-память в открытых системах

Основное назначение кэш-памяти - "маскирование" обращений к медленно действующей дисковой памяти. Низкое быстродействие жестких дисков обусловлено задержками при механическом способе доступа к данным, размещенным на них. В случае же кэш-памяти среднее время доступа к размещенным в ней данным составляет порядка 200 мс, т. е. в 30-40 раз меньше. Поэтому один из важнейших способов повышения производительности современных дисковых массивов - оптимизация алгоритмов использования кэш-памяти.

Существуют следующие типы обращений (запросов) к кэш-памяти: случайное чтение, последовательное чтение, случайная запись, последовательная запись [3]. Очевидно, что все эти типы имеют специфический характер, и потому алгоритмы их обработки должны быть различными. Упрощение алгоритмов с высокой вероятностью приведет к необходимости увеличения кэш-памяти. По этой причине объем кэш-памяти, необходимый для эффективного выполнения конкретных операций, в первую очередь определяется качеством алгоритмов, выполняющих их обработку. Рассмотрим особенности реализации алгоритмов работы кэш-памяти в контроллерах дисковых массивов EVA.

Случайные чтения данных

Значительную часть всех обращений к данным в современных СУБД составляют случайные запросы на чтение данных. При их обработке в кэш-память помещаются наиболее часто запрашиваемые блоки данных, что снижает время доступа к ним. Основная предпосылка такого подхода состоит в том, что помещаемые в кэш блоки данных должны быть востребованы при следующих обращениях. Однако на практике эта предпосылка часто оказывается неверной по ряду причин.

Во-первых, случайные запросы на чтение имеют крайне низкую вероятность повторения и соответственно попадания в кэш-память (cache hits). В идеале размер кэша должен быть не меньше, чем у файла данных, к которому выполняются обращения. Так, если размер файла равен 1 Тбайт, то и объем кэш-памяти должен быть не менее 1 Тбайт. А если файлов базы данных несколько? Большинство приложений в открытых системах реализуют случайный (OLTP) характер запросов к данным. Известно, что чем более "случаен" характер запросов, тем меньше вероятность повторного попадания данных в кэш. Если допустить, что все обращения абсолютно случайны, то можно было бы, наверное, вовсе обойтись без кэш-памяти в дисковых массивах (и такие решения на рынке есть). Эффективность использования кэш-памяти при обработке запросов на случайное чтение данных можно упрощенно оценить на следующем примере: пусть дисковый массив имеет емкость 64 Тбайт и кэш 64 Гбайт (это значения для реальной системы). В таком случае - в предположении равномерного распределения запросов на ввод-вывод между всеми дисками массива - вероятность попадания в кэш составила бы 0,05 (с учетом того, что кэш на чтение составляет половину общего объема кэш-памяти). Этот показатель не слишком впечатляет. К счастью, на практике запросы на выборку данных в определенной степени детерминированы, и величина попаданий в кэш не столь низка. Тем не менее большая кэш-память оказывается практически бесполезной для рабочих нагрузок с преобладанием случайных выборок из памяти.

Во-вторых, не стоит забывать, что наиболее часто запрашиваемые данные требуется не только поместить в кэш-память, но и своевременно удалить из нее, чтобы разместить другие блоки данных, частота обращений к которым также велика. Операции очистки кэш-памяти приводят к дополнительной загрузке контроллера и увеличению времени задержки. Кроме того, необходимость периодической очистки кэш-памяти дополнительно снижает вероятность попадания "нужных" данных в кэш.

В-третьих, современные серверы имеют свой собственный кэш, измеряемый десятками гигабайт. Средства кэширования запросов в СУБД размещают часто запрашиваемые данные в памяти серверов, которая по объему порой значительно превосходит кэш-память контроллера дискового массива. Поэтому запросы на ввод-вывод могут вообще миновать контроллер, и большой объем его кэш-памяти окажется невостребованным.

Вместе с тем в некоторых случаях кэш на выборку случайных данных может оказаться весьма полезным, например, для устранения проблемы "перегретых" дисков, т. е. когда частота запросов к определенному блоку данных на диске очень велика. Пример такого блока - индексная таблица базы данных. Несмотря на то, что в данном случае можно обеспечить определенный выигрыш путем перемещения данного блока в кэш-память, этим проблема до конца не решается. Дело в том, что индексная таблица - не единственный "горячий" блок данных, и конфликт за "место под солнцем" может привести к тому, что один или несколько "горячих" блоков окажутся вне кэша. Наиболее простой способ избежать подобной ситуации - просто увеличить объем кэш-памяти. Понятно, что это будет крайне неэффективно в силу сложности предсказания соотношения "горячих" запросов и необходимости использовать десятки гигабайт дорогостоящей кэш-памяти для размещения сотен, а то и десятков мегабайт "горячих" блоков данных.

Другой способ повышения эффективности использования кэш-памяти - запрет на ее использование для выделенных томов, имеющих заведомо наименьшую вероятность "попадания" в кэш. С одной стороны, это позволит разгрузить кэш-память, но с другой - потребует обязательного участия администратора в мониторинге и управлении. Но самое неприятное здесь то, что "отключенные" тома могут на определенный период стать "горячими", но не получить доступа к кэш-памяти.

Разработчики дисковых массивов EVA пошли по другому пути - повышения эффективности алгоритмов управления кэш-памятью. Специальное ПО контролирует уровень "попаданий" и, если для конкретного логического тома (LUN) он становится ниже определенной границы, исключает данный LUN из списка "допущенных" для чтения из кэш-памяти. В результате случайный поток запросов не пересылается напрямую в кэш, а предварительно анализируется на предмет возможных конфликтов с данными, находящимися в кэш-памяти. Мониторинг использования выделенных блоков данных в массивах EVA ведется непрерывно: если частота использования возрастает, этот блок снова помещается в кэш. Такой способ динамической балансировки загрузки кэша позволяет обходиться кэш-памятью небольшого размера для выполнения операций случайной выборки.

Последовательное чтение данных

Обработка запросов на последовательное чтение данных в большинстве практических ситуаций выполняется одновременно с обработкой случайных запросов на чтение. Наибольшую "опасность" представляют запросы на последовательное чтение небольших объемов данных. Традиционный способ оптимизации таких запросов - априорное их расширение и перемещение в кэш (prefetch) прогнозируемой области запрашиваемых при каждом запросе данных в предположении, что следующие считываемые блоки окажутся в этой области. Тем самым упреждается последующий запрос. Однако такой подход скрывает две ошибки. Во-первых, лишь очень небольшая часть запросов относится к последовательным по своей природе, поэтому задержки, связанные с чтением дополнительных объемов данных, снижают общую производительность, в том числе при обработке случайных запросов на чтение. Во-вторых, хранение избыточных данных в кэш-памяти не оставляет места для других данных. Этот конфликт, как правило, устраняется путем увеличения объема кэш-памяти.

В контроллерах EVA используются запатентованные алгоритмы предсказания (prefetch) последовательных запросов на чтение данных, с помощью которых проводится мониторинг запросов ввода-вывода на выявление типовых последовательностей. Цепочки последовательных запросов можно выявить даже при наличии большого количества случайных запросов. Например, если происходит обращение к блокам 100, 2367, 17621, 48, 101, 17, 2, 15, 102, то с помощью данного ПО удается "распознать" цепочку последовательных запросов, включающую блоки 100, 101 и 102, и выполнить упреждающее размещение запрашиваемых данных в кэш-памяти. Разработанное ПО обеспечивает анализ до 512 одновременных последовательных запросов к разным областям разных логических томов. Благодаря этому контроллеры EVA позволяют не только обрабатывать множественные потоки запросов, генерируемые разными приложениями в гетерогенном серверном окружении, но также инициализировать параллельные операции упреждающего чтения для требуемого числа LUN.

После детектирования потока последовательных запросов, упреждающего чтения и пересылки требуемых данных активному приложению контроллер инициализирует запрос на чтение дополнительных данных из LUN. При этом сравниваются времена получения данных приложением и упреждающего чтения дополнительных блоков данных. Если упреждающее чтение выполняется быстрее получения запрошенных данных приложением, то делается вывод о соответствии скорости упреждающего чтения и работы приложения, и тогда после очередного запроса данных приложением выполняется следующее упреждающее чтение. Если же данные запрашиваются приложением быстрее, чем контроллер отрабатывает упреждающее чтение, то динамически увеличивается область упреждающего чтения. Таким образом, идет адаптивная балансировка скорости упреждающего чтения для минимизации задержки работы приложения.

После того, как приложение получит данные, кэш-память немедленно очищается, поскольку вероятность повторения последовательного запроса крайне низка. Таким образом, даже при небольшом (несколько сотен килобайт) объеме кэш-памяти, оптимизировав выполнение операций упреждающего чтения и очистки памяти, можно считывать целые тома данных, обеспечивая 100%-ное попадание в кэш. Не снижается и эффективность случайных запросов на чтение: циклы упреждающего чтения последовательных запросов генерируются динамически, а размер области чтения адаптивен. На практике 1 Гбайт кэш-памяти, отведенного для чтения, более чем достаточно для одновременной обработки случайных и последовательных запросов на чтение данных.

Случайные операции записи

Кэш для записи выполняет функции буфера, согласующего скорость обмена данными с дисковой подсистемой. Роль его очень важна, особенно при выполнении RAID-операций записи данных. Кэш позволяет минимизировать задержки записи данных на диски, посылая приложению подтверждение о завершении операции сразу после помещения данных в кэш. Однако в этом случае существует опасность переполнения кэш-памяти. Инженеры НР предложили алгоритм, реализованный в контроллерах EVA, который обеспечивает плавный "сброс" данных на диски в фоновом режиме по мере заполнения кэш-памяти. Преимущества виртуализованной архитектуры EVA позволяют свести к минимуму влияние данных операций на работу приложений и производительность массива.

Установлено [1], что объема в несколько сотен мегабайт вполне достаточно для эффективной работы кэш-памяти при обработке случайных запросов на запись данных. Пока частота обращений не превышает скорости перемещения данных из кэш-памяти на диски, приложение вообще не замечает кэширования запросов. Если же скорость потока запросов на запись достигает такой величины, что кэш-память не успевает сбрасывать данные на диски и начинает переполняться, то в этом случае, какого бы размера ни была память, она все равно заполнится, и скорость обработки запросов сравняется со скоростью дисковой подсистемы.

По этой причине неоптимальные алгоритмы кэширования приводят к значительным задержкам операций ввода-вывода в силу переполнения кэш-памяти и необходимости ожидания сброса данных на диски для ее освобождения. Эта тенденция выявляется в результате нагрузочного тестирования [2].

На практике кэш-память должна иметь некоторый избыточный объем, позволяющий "парировать" всплески повышенной активности случайных запросов ввода-вывода, которые не должны приводить к ее переполнению. При этом в типовых условиях работы какая-то часть кэш-памяти по сути останется незадействованной, поскольку никогда не заполнится данными. С другой стороны, даже значительный объем кэш-памяти будет малоэффективен при темпе поступления данных, превышающем скорость их сброса на диски. Таким образом, и в этом случае решающая роль отводится эффективным алгоритмам управления ресурсами кэш-памяти.

Последовательные запросы на запись данных

На практике потоки последовательных запросов на запись - одни из самых критичных с точки зрения производительности системы. Такие операции, как правило, выполняются блоками по 8 или 16 Кбайт, что крайне неэффективно с точки зрения расхода ресурсов хранения. Более того, на практике они выполняются одновременно с внутренними процедурами СУБД для проверки целостности данных, что приводит к резкому повышению числа обрабатываемых запросов ввода-вывода.

ПО контроллеров массива EVA позволяет детектировать последовательности запросов на запись данных. Отдельные блоки накапливаются в кэш-памяти, формируя один агрегированный блок, который по достижении определенного объема сбрасывается на диски. Преимущества такого подхода очевидны - снижение числа запросов ввода-вывода и повышение скорости обмена данными.

Размер агрегированного блока задается исходя из размеров "стрипа" - блока минимального размера, на которые поделены диски массива. Массивы EVA используют стрипы по 512 Кбайт [1], размер которых выбран с учетом особенностей технологии виртуализации ресурсов, применяемой в EVA. Такой размер стрипов позволяет задействовать для записи все диски группы Vraid 5, обеспечивая тем самым выполнение операций проверки четности (parity) "на лету", исключая типовую цепочку чтения/модификации/записи. Использование такого алгоритма записи обеспечивает производительность Vraid 5, сопоставимую с Vraid 1, для которых агрегированные данные также записываются блоками по 512 Кбайт. Таким образом, в массивах EVA реализуется гомогенная среда обмена данными, обеспечивающая наивысшую производительность путем распараллеливания операций записи на диски независимо от того, какие уровни Vraid используются логическими томами. Размер агрегированного блока выбран оптимальным, поэтому его увеличение не приводит к дальнейшему росту производительности операций ввода-вывода. Следовательно, применение в массивах EVA политики агрегирования последовательных запросов на запись позволяет оптимизировать не только скорость обмена данными, но и процедуру освобождения кэш-памяти, тем самым снизив до минимума требования к ее объему. По мнению специалистов НР, 1 Гбайт кэш-памяти на контроллер (512 Мбайт с учетом зеркалирования) в дисковых массивах EVA вполне достаточно для того, чтобы обеспечить требуемую эффективность выполнения операций как случайной, так и последовательной записи данных.

Когда необходим большой кэш

В массивах EVA компания НР реализовала сбалансированный подход к размеру кэша, позволяющий заказчикам сэкономить немалые средства, получив при этом современную дисковую систему хранения. Тем не менее на практике пользователи в силу тех или иных причин часто предпочитают избыточную кэш-память; причины такого решения обсуждаются ниже.

Субъективные предпочтения заказчика. Ситуации, когда пользователь не может корректно обосновать необходимость большого кэша, но имеет возможность его купить, встречаются довольно часто. Это стратегия "наибольшего оптимизма", приносящая заказчику чувство уверенности в дисковом массиве.

Желание поместить структуры данных и программный код в кэш-память для повышения производительности. С одной стороны, это правильно, но с другой - приводит к избыточному "расходу" дорогой кэш-памяти. Эффективный путь решения этой проблемы предложили разработчики EVA: структуры данных и программный код размещаются в "частной" памяти, обеспечивающей требуемые характеристики производительности [2].

Возможность резидентно разместить выделенный LUN в кэш-памяти (LUN binding intelligence). Это, пожалуй, единственный случай, оправдывающий использование кэш-памяти большого объема. Однако использование этой возможности требует корректного обоснования, что в большинстве случаев затруднительно для заказчика.

Желание производителя "замаскировать" слабые алгоритмы контроллера (например, использование блоков данных по 64 Кбайт для выполнения операций упреждающего чтения и т. д.).

Наконец, при выборе размеров кэш-памяти дискового массива не стоит забывать и азбучные истины: большой кэш - большое энергопотребление и емкость батарей резервного питания, длительное время поиска, задержки при зеркалировании данных и т. д.

Выводы специалистов НР подтверждаются результатами независимых исследований, выполненных специалистами Университета шт. Цинциннати (США) в марте 2002 г. [4]. Для ответа на вопрос, может ли большой кэш повысить производительность системы, специалисты университета провели детальный анализ влияния величины собственной кэш-памяти (буфера) жесткого диска на производительность системы, оцениваемого временем отклика файловой системы. Суть полученных ими результатов заключается в следующем.

Объем внутреннего буфера в современных жестких дисках достигает нескольких мегабайт (обычно 2 Мбайт для IDE/ATA- и до 16 Мбайт - для SCSI-дисков). По мнению исследователей, основная "движущая сила", подталкивающая производителей жестких дисков увеличивать объем буфера, - это желание пользователей иметь "запас", чтобы обеспечить резерв производительности системы. Положение усугубляется практически полным отсутствием материалов анализа результатов эксплуатации или тестирования дисковых массивов, которые показали бы реальные преимущества большой кэш-памяти. Авторы исследования утверждают, что увеличение собственной кэш-памяти дисковой системы не приводит к заметному повышению производительности системы в целом. Причина в том, что все современные операционные системы используют большие выделенные области системной памяти (несколько гигабайт) для кэширования операций ввода-вывода. В таком случае увеличение кэш-памяти жестких дисков теряет смысл.

Тестирование жестких дисков выполнялось в условиях, приближенных к реальным, создаваемым с помощью нескольких типовых тестов. Обобщая полученные результаты, исследователи заключают, что, начиная со значения в 512 Кбайт, размер внутреннего кэша практически не оказывает влияния на производительность системы. При величине системной кэш-памяти в 16 Мбайт увеличение объема собственного кэша дисков с 512 Кбайт до 16 Мбайт повышает производительность системы лишь на 1,1-4,1%. При дальнейшем увеличении сиcтемной памяти до 128 Мбайт обеспечивается дополнительный прирост производительности лишь на 0,3-1,4%. Отмечено также, что с увеличением системной кэш-памяти с 16 до 128 Мбайт вероятность попадания запросов в собственный кэш дисковой подсистемы снижается. Вместе с тем зависимость производительности от величины системной кэш-памяти значительно более ощутима: время отклика файловой системы уменьшается на 25-30% с ростом объема памяти с 16 до 128 Мбайт.

Исследования в Университете Цинциннати подтвердили целесообразность реализации алгоритма упреждающего чтения (prefetch) при выполнении последовательного чтения данных. По мнению авторов, эффективность алгоритма зависит от многих факторов, среди которых количество сегментов кэш-памяти, число одновременно обрабатываемых запросов на чтение данных, размер запрашиваемых данных. Результаты, полученные при последовательном чтении девяти файлов по 64 Кбайт, показали, что время отклика файловой системы с увеличением числа сегментов с 5 до 9 уменьшается на 15-50% (в зависимости от размера запрашиваемых данных). С увеличением размера блока запрашиваемых данных с 1 до 16 Кбайт время отклика системы возрастает в 2-6 раз.

Таким образом, исследования независимых экспертов и специалистов НР показали нецелесообразность большой собственной кэш-памяти дисковой системы; предпочтительнее наращивать системную память для кэширования операций обращения к дискам. Подтверждена эффективность использования применяемых в дисковых массивах EVA алгоритмов упреждающего чтения данных при обработке последовательных запросов. Оптимизация алгоритмов работы кэш-памяти позволяет обеспечить требуемую эффективность при меньшем объеме дисковой кэш-памяти. Эффективные алгоритмы управления ресурсами кэш-памяти позволяют также уменьшить стоимость владения и сохранить средства заказчика.

Компания "Ай-Теко" использует системы хранения НР StorageWorks при создании ИТ-инфраструктур высокой доступности, консолидированных хранилищ и сетей хранения данных (SAN), имея опыт построения катастрофоустойчивых SAN-решений, высокопроизводительных систем хранения, высоконадежных систем резервного копирования и восстановления данных, образующих фундамент корпоративных инфраструктур любого масштаба.

Источники дополнительной информации

  1. EVA Cache. Why a small size works so well. Материалы компании Нewlett-Packard.
  2. The EVA in the High-End. Материалы компании Нewlett-Packard.
  3. Neil J. Guther. The Practical Performance Analyst. McGraw-Hill, 1998.
  4. Y. Zhu, Y. Hu. Can Large Disk Built-in Caches Really Improve System Performance? Technical Report. University of Cincinnati, March 2002.