Альтернативная технология ввода/вывода, называемая "ввод/вывод напрямую" (Direct I/O), впервые была представлена в AIX 4.3, а затем внедрялась во все последующие версии AIX, включая AIX 5L. В этой технологии не используется менеджер виртуальной памяти (Virtual Memory Manager, VMM), а данные напрямую передаются из диска в пользовательский буфер, и наоборот. Реализация этой технологии для обработки файлов может увеличить производительность используемых приложений.
В дальнейшем любая ссылка на JFS будет подразумевать ссылку на JFS и JFS2. JFS (Journaled File System, журналируемая файловая система) является "родной" файловой системой для платформ POWER. JFS2 (также известная как Enhanced Journaled File System, улучшенная журналируемая файловая система), которая не является "родной" для платформ POWER, тоже доступна на POWER. JFS и JFS2, используемые в AIX, для поддержания своей структурной целостности применяют техники журналирования баз данных. Это позволяет избежать порчи файловой системы при аварийном завершении работы.
В обычной ситуации, когда происходит запрос ввода/вывода к файлу в JFS-системе, процедура чтения/записи выполняется сначала из буфера приложения в менеджер виртуальной памяти (далее - VMM), и затем из VMM в JFS. Если нужная страница файла не находится в памяти в тот момент, когда ее запрашивает приложение, то JFS считывает данные из диска в кэш файлового буфера (file buffer cache), затем копирует данные из кэша файлового буфера в пользовательский буфер. И наоборот, когда приложение делает запрос на запись, данные копируются из пользовательского буфера в кэш файлового буфера. Если запросы записи на диск не могут быть выполнены немедленно, они будут выполнены позднее.
При высоком проценте успешных обращений к кэшу подобная политика кэширования может оказаться очень эффективной для увеличения производительности ввода/вывода JFS-системы. Данный подход максимально использует особенности JFS - упреждающее чтение и обратную запись. Файлы будут записаны в асинхронном режиме, поэтому приложение может продолжать свою работу и не ждать завершения выполнения запросов ввода/вывода. С другой стороны, если частота успешных обращений приложений к кэшу низка или подсистема ввода/вывода очень интенсивно используется, подобная политика кэширования может оказаться неэффективной.
Если известно, что некоторые файлы редко используют кэш, то можно использовать для этих файлов Direct I/O. Подобное действие почти наверняка приведет к увеличению производительности используемых приложений.
Прямой ввод/вывод (Direct I/O) для файлов и неформатированный ввод/вывод (raw I/O) для устройств являются функциональными эквивалентами, но Direct I/O не влияет на производительность неформатированного ввода/вывода. В то же время raw I/O немного превышает по производительности Direct I/O, но Direct I/O позволяет использовать преимущества файловой системы JFS и возможное при этом повышение производительности.
Адаптация приложений для использования Direct I/O
На уровне исходного кода Direct I/O файла обеспечивается флагом O_DIRECT в заголовочном файле fcntl.h. Этот флаг определен в функции open. Чтобы можно было использовать определение флага O_DIRECT, приложения должны компилироваться с флагом _ALL_SOURCE.
Начиная с AIX 5.1D на пользовательском уровне Direct I/O активируется при помощи параметра dio в команде mount, например, mount -odio /xyz, где xyz является файловой системой. Такой подход применим для файловых систем JFS и JFS2. Пока удовлетворяются требования к выравниванию запросов в файловой системе, смонтированной с использованием опции dio, все запросы ввода/вывода будут интерпретироваться как прямой ввод/вывод. Запросы ввода/вывода должны быть выровнены по границам страницы (4 KБ) или быть кратным его размеру, если запрос занимает несколько страниц. Если данные условия ввода/вывода не будут выполнены, то процедура ввода/вывода будет выполняться через буферы ядра, которые будут очищены после выполнения ввода/вывода. Это приведет к снижению производительности. Следовательно, использовать параметр dio в команде mount следует только в том случае, если все приложения, работающие с файлами в файловой системе, имеют удовлетворительное поведение с точки зрения рассмотренных требований.
Как только Direct I/O будет реализован, его работу легко проверить - надо только смонтировать файловую систему при помощи параметра dio и записать число страниц памяти, которые используются, а затем повторить эту процедуру для файловой системы, которая была смонтирована без параметра dio. Заметим, что в файловой системе с Direct I/O для кэширования страниц не будут использоваться страницы памяти, и следовательно, в отличие от обычного ввода/вывода, значение параметра numperm утилиты vmtune не будет увеличиваться.
Правила для использования Direct I/O на уровне API
- Существуют строгие правила использования Direct I/O на уровне API. Буферы для запросов ввода/вывода должны быть длиной в 4 КБ, а размеры запросов ввода/вывода должны быть кратными 4 KБ. Ошибка на уровне API сделает невозможным использование Direct I/O. Обычно базы данных следуют этим правилам, поскольку используют неформатированный логический ввод/вывод.
- Direct I/O не может игнорировать блокировку i-node. Если i-node блокировка служит причиной проблемы с записью, то, скорее всего, эта проблема останется и при использовании Direct I/O.
- У Direct I/O нет буфера, поэтому процедуры записи являются синхронными. Если приложение делает множество буферизированных запросов ввода/вывода, то возможно, что с Direct I/O оно будет работать очень медленно.
- Поскольку Direct I/O не буферизирован, он не реализует возможность упреждающего чтения. Direct I/O может стать причиной снижения производительности, если приложение делает множество последовательных запросов чтения и использует файловую систему, которая преобразует эти запросы в одну большую процедуру физического ввода/вывода.
- Direct I/Oвывод не объединяет последовательные запросы ввода/вывода. Это может стать причиной возможных ошибок для приложений, которые используют
aio,listioилиreadv/writev.
Direct I/O поддерживается только для рабочей памяти программы, т.е. для локальных постоянных файлов. Главное преимущество Direct I/O заключается в уменьшении циклов использования CPU, необходимых для выполнения процедур чтения и записи в файл. Такой результат достигается благодаря тому, что файлы не нужно копировать из файлового кэша VMM в пользовательский буфер (как при обычной работе с кэшэм). Если при обычной работе с кэшем коэффициент удачных выборок низкий, то наиболее часто вызываемые запросы на чтение будут выгружены на диск. Как упоминалось ранее, существуют идеальные ситуации, в которых приложение выиграет от использования Direct I/O. Однако если при обычной работе с кэшем высок процент удачных обращений, то использование Direct I/O уменьшит загрузку процессора. Но в то же время нельзя будет воспользоваться преимуществами алгоритмов упреждающего чтения, которые доступны при обычной работе с кэшэм. В большинстве случаев процедуры записи быстрее при обычном механизме функционирования кэша. Но если файл открыт с флагами O_SYNC или O_DSYNC, то запись будет производиться сразу на диск. Поскольку в этих случаях не выполняется лишняя процедура копирования данных, приложению будет выгоднее использовать Direct I/O.
Другим преимуществом Direct I/O является то, что при его использовании приложения не могут снижать эффективность кэширования других файлов. При чтении файла или записи в него файлы состязаются за пространство в кэше. Данная ситуация может привести к тому, что данные другого файла будут вытеснены из кэша. Если известно, что некоторые файлы неэффективно используют кэш, тогда эти файлы (и только эти) можно открыть с флагом O_DIRECT.
Производительность запросов чтения с Direct I/O
Несмотря на то, что использование Direct I/O может уменьшить число циклов выполнения приложения на CPU, во многих случаях оно может также привести и к ускорению операций. Наиболее характерно это для последовательностей небольших запросов ввода/вывода.
Direct I/O с диска является синхронным, и это может привести к снижению производительности по сравнению с ситуацией, когда данные находятся в памяти, которая обрабатывается согласно стандартной политике кэширования. Так как при Direct I/O не используется VMM, для него недоступны алгоритмы упреждающего чтения менеджера виртуальной памяти. Механизм упреждающего чтения мог бы быть крайне полезным при последовательном доступе к файлам, поскольку VMM может предварительно загрузить страницы в память прежде, чем приложение их запросит. Приложения могут компенсировать потери из-за отсутствия упреждающего чтения, если они будут:
- выполнять большие запросы чтения.
- используя многопоточность, выполнять прямой асинхронный упреждающий ввод/вывод.
- использовать асинхронные методы ввода/вывода:
aio_read()илиlio_listio().
Производительность запросов записи с Direct I/O
Direct I/O выполняется в обход VVM напрямую на диск, что может стать причиной значительного снижения производительности; при стандартной политике кэширования ввода/вывода запросы чтения могут выполняться над данными в памяти, а уже впоследствии сбрасываться на диск. Во время выполнения операции синхронизации (с Direct I/O) данные не копируются в память, следовательно, страницы не надо выгружать из памяти на диск. В таком случае уменьшается количество работы, которую должен был бы выполнить демон syncd.
Пример показателей производительности
В следующем примере измерялась производительность для сервера RS/6000, работающего под управлением AIX 4.3.1. KBPS - пропускная способность в килобайтах в секунду, и %CPU - процент использования CPU (листинг 1).
Листинг 1. Пример производительности
# of 2.2 GB SSA Disks 1 2 4 6 8
# of PCI SSA Adapters 1 1 1 1 1
Sequential read throughput, using normal I/O
KBPS 7108 14170 18725 18519 17892
%CPU 23.9 56.1 92.1 97.0 98.3
Sequential read throughput, using Direct I/O
KBPS 7098 14150 22035 27588 30062
%CPU 4.4 9.1 22.0 39.2 54.4
Sequential read throughput, using raw I/O
KBPS 7258 14499 28504 30946 32165
%CPU 1.6 3.2 10.0 20.9 24.5
|
Конфликт режимов доступа к файлам
Возможно возникновение проблем, связанных с несогласованностью между программами, которые используют прямой ввод/вывод, и программами, использующими обыкновенный кэшированный ввод/вывод. Для устранения этих проблем Direct I/O обычно используется по умолчанию в исключительном режиме доступа. Предположим, что для файла открыто несколько потоков чтения - одновременно и Direct I/O, и стандартная политика кэширования. В таком случае режим доступа к файлу будет стандартным. Только в том случае, если файл открыт в исключительном режиме доступа для программ, которые поддерживают Direct I/O, файл будет переведен в режим прямого ввода/вывода.
Точно так же, если файл выгружен в виртуальную память при помощи системных вызовов shmat() или mmap(), он будет доступен в режиме стандартного кэширования.
JFS или JFS2 будут пытаться изменить режим доступа к файлу на Direct I/O всякий раз при завершении конфликтного (непрямого) доступа (через функции close(), munmap() или shmdt()). Однако изменение режима доступа к файлу с обычного ввод/вывода на Direct I/O может привести к увеличению нагрузки на ресурсы сервера, поскольку потребует выгрузки всех модифицированных страниц на диск и удаления всех страниц из памяти.
Когда надо применять Direct I/O
Для приложений, интенсивно использующих ввод/вывод и не получающих значительной выгоды от стандартной политики кэширования, следует использовать Direct I/O.
Программы, у которых есть ограничение на использование CPU и которые выполняют множество запросов чтения/записи на диск, должны использоваться с Direct I/O. Также подходящими кандидатами на использование Direct I/O являются программы, которые генерируют большие последовательные запросы чтения/записи. Приложения, которые делают большое количество маленьких запросов ввода/вывода, получат лишь проигрыш в производительности от использования Direct I/O, поскольку данный режим работы с диском не поддерживает алгоритмы упреждающего чтения и обратной записи (которые доступны для обычной политики кэширования). Приложения, которые используют распределение данных (stripping, RAID 0) также хорошо подходят для использования Direct I/O.
- Use Direct I/O to improve performance of your AIX applications (EN): оригинал статьи.
- AIX 5L Version 5.1 Performance Management Guide (EN): руководство по управлению производительностью для AIX 5L 5.1.
- Раздел developerWorks AIX и UNIX содержит сотни информативных статей для читателей начальной, средней и высокой квалификации.
- Семинары и обучение на developerWorks Россия.
Шив Дутта (Shiv Dutta) - старший инженер-программист в группе IBM System And Technology Group; он оказывает помощь независимым производителям программного обеспечения в адаптации их программ на платформе System p. Шив был одним из соавторов справочника Красная книга (redbook) AIX 5L Differences Guide Version 5.3 Edition (Новое в AIX 5L версии 5.3). Вы можете связаться с ним по электронной почте sdutta@us.ibm.com.