Использование O_DIRECT в Linux

24

Если этот вопрос слишком ориентирован на программиста, дайте мне знать. Интересно, есть ли люди, знакомые с флагом O_DIRECT для системного вызова open () в Linux 2.6? Linus не одобряет его использование, однако высокая эффективность записи файлов, кажется, указывает на его использование. Я хотел бы узнать о любом реальном опыте и рекомендациях.

Дополнительная информация: Приложение, которое я использую , поддерживает свой собственный кэш, и при этом скорость его работы возрастает в среднем в 5 или более раз. При записи в файл содержимое кэша должно быть записано в кэш файловой системы, что представляется избыточным и вызывает проблемы с производительностью.

casualunixer
источник

Ответы:

17

Хорошо, вы спрашиваете об опыте, это делает вопрос немного субъективным и спорным, но сносным.

Линус сказал, что в отношении использования, которое люди обычно приписывают O_DIRECT, и для этих применений, IMO Linus в основном правильно. Даже если вы выполняете прямой ввод-вывод, вы не можете передавать данные на / с устройств напрямую в операторы вашей программы, вам нужен буфер, который заполняется (программой или устройством) и передается через системный вызов на другой конец. Кроме того, чтобы сделать его более эффективным, вы не захотите перечитывать то, что только что прочитали, на случай, если оно вам понадобится снова. Так что вам нужен какой-то кеш ... и это именно то, что ядро ​​предоставляет без O_DIRECT, кеша страниц! Почему бы не использовать это? Это также дает преимущества, если больше процессов хотят одновременно обращаться к одному и тому же файлу, с O_DIRECT было бы катастрофой.

Сказав это, O_DIRECT имеет свое применение: если по какой-то причине вам необходимо получать данные непосредственно с блочного устройства. Это не имеет ничего общего с производительностью.

Люди, использующие O_DIRECT для производительности, обычно приходят из систем с плохими алгоритмами кэширования страниц или без механизмов рекомендаций POSIX, или даже с людьми, бездумно повторяющими то, что говорили другие люди. Чтобы избежать этих проблем, O_DIRECT был решением. Linux, OTOH, придерживается философии, согласно которой вы должны исправить реальную проблему, а основной проблемой были ОС, которые плохо справились с кэшированием страниц.

Я использовал O_DIRECT для простой реализации cat, чтобы найти ошибку памяти на моей машине. Это одно допустимое использование для O_DIRECT. Это не имеет ничего общего с производительностью.

Жулиано
источник
Спасибо за информацию, это ценится. Я обновил свой вопрос с конкретными условиями приложения, которое вызвало этот вопрос. Если у вас есть более подробная информация о механизмах рекомендаций POSIX для записи файлов, это также будет полезно.
casualunixer
4
o_direct также может быть полезен в системе, где разработчик хочет предоставить механизм кэширования на уровне приложений (например, базы данных).
Jmoney38
Это не имеет ничего общего с производительностью. Это не всегда так, особенно для доступа к высокоскоростному устройству, где IO оценивает конкурирующую пропускную способность памяти или даже значительный процент пропускной способности памяти. В этом случае пропуск дополнительной копии в / из кэша страниц может значительно повысить производительность.
Эндрю Хенле
14

На самом деле, O_DIRECT это необходимо , чтобы избежать любого из

  • загрязнение кэша - иногда вы знаете, что нет никакого смысла в накладных расходах на кэширование, например, при работе с действительно большими файлами, скажем, 64 ГБ, когда ОЗУ всего 2 ГБ. Torrent-файл размером 32 ГиБ, который пользователь решил проверить, не является хорошим кандидатом для кеширования. Это просто дополнительная активность со своими накладными расходами. И это может привести к удалению из кеша действительно полезных данных.
  • двойное кеширование - например, для некоторых СУБД (упомяну MySQL) можно определить собственный кеш. Базы данных, якобы, лучше знают, как кешировать и что, чем виртуальная память ядра, которая ничего не знает о планировании SQL и так далее.

- что нехорошо, как кажется. И O_DIRECTне значит быть быстрее, часто это не так .

poige
источник
10
posix_fadviseможет позаботиться о проблеме загрязнения кэша.
psusi
Я не думаю, что виртуальная память имеет к этому какое-либо отношение, она просто отображает адрес памяти. Buffer Cache / Page Cache - это то, что вы имеете в виду.
АрекБульски
Кэширование / кэширование является частью подсистемы виртуальных машин в UNIX, насколько я могу судить, поэтому я использовал этот термин. Спасибо за редактирование. :)
poige
6

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

Питер Айзентраут
источник
1
В отчете об ошибке фактически обсуждается использование файловых систем с включенной опцией journal = data. Этот параметр прямо противоположен действующему флагу O_DIRECT. В большинстве файловых систем ext3 и ext4 этот флаг не установлен, и, если он установлен, его отключение позволит открыть файл с помощью O_DIRECT.
casualunixer
3

Это во многом связано с производительностью.

Интересный пример в mongodb с использованием движка mmap. O_DIRECT лучше всего использовать, как уже говорили другие, где данные вряд ли будут считаны в течение некоторого времени. В mongodb журнал базы данных записывается с использованием O_DIRECT, а записи данных и индексов обрабатываются механизмом кэширования страниц (pdflush), поскольку, хотя O_DIRECT предлагает меньшую пропускную способность, это также означает меньшую задержку и, следовательно, уменьшает потерю данных в случае неожиданное отключение (паника ядра, сбой диска или питания). Обратите внимание, что буферизация еще до того, как запись O_DIRECT будет передана в энергонезависимое хранилище, это просто уменьшает потерю данных.

Еще одной важной особенностью O_DIRECT является то, что он обеспечивает больший контроль над последовательностью записи. Опять же, это не гарантирует порядок записи (если у вас нет энергонезависимого контроллера кэширующего диска и вы используете планировщик fifo, но у них есть свои сложности). Следовательно, хотя mysql использует O_DIRECT для своих данных / индексов, а также для журналирования, он может ожидать, что последний обычно будет зафиксирован первым.

Но важно помнить, что O_DIRECT нарушает справедливость в распределении ресурсов. Одна из причин, по которой ваше приложение ускоряется, заключается в том, что оно замедляет работу других приложений.

symcbean
источник
Вы говорите, что это во многом связано с производительностью, но вы привели пример, где он используется либо для уменьшения задержки, либо для порядка записи. Но я согласен, что это влияет на производительность. Честная точка зрения о справедливости.
АрекБульски
Можете ли вы предоставить больше ссылок, объясняющих, когда это несправедливо?
ACyclic
3

Относительно того, что @Juliano уже сказал.

Оформить заказ, posix_fadviseесли реальная проблема заключается в неправильном поведении алгоритма кэширования базовой файловой системы, вы можете попробовать дать ему совет, как вы собираетесь использовать файловую систему. Для хорошо реализованного fs, это должно повысить производительность. (Вот ссылка на другую тему, касающуюся аналогичных соображений /programming//a/3755818/544721 )

Гжегож Вежовецкий
источник
1
Похоже, что posix_fadvise изменяет алгоритмы чтения, используемые ядром. Критическим фактором с кодом в вопросе является производительность записи. Проблема в том, что запись буфера сначала заполняет кеши Linux, которые ядро ​​затем должно выгружать, когда ему не хватает памяти. Это пустая трата усилий, выход в этом случае должен быть минимально буферизован на пути к диску.
casualunixer