В Linux завершенное выполнение команды, такой как cp
или dd
не означает, что данные были записаны на устройство. Например, необходимо вызвать sync
или вызвать функцию «Безопасное извлечение» или «Извлечь» на диске.
Какая философия стоит за таким подходом? Почему данные не записываются сразу? Нет ли опасности, что запись не удастся из-за ошибки ввода-вывода?
kernel
drivers
io
unix-philosophy
marmistrz
источник
источник
Ответы:
Эффективность (лучшее использование характеристик диска) и производительность (позволяет приложению продолжать работу сразу после записи).
Основное преимущество заключается в том, что ОС может свободно переупорядочивать и объединять непрерывные операции записи, чтобы улучшить использование полосы пропускания (меньше операций и меньше операций поиска). Жесткие диски работают лучше, когда запрашивается небольшое количество больших операций, в то время как приложения, как правило, требуют большого количества небольших операций. Другая очевидная оптимизация заключается в том, что ОС может также удалить все записи, кроме последней, когда один и тот же блок записывается несколько раз за короткий промежуток времени, или даже удалить все записи вместе, если за это время удаленный файл был удален.
Эти асинхронные операции записи выполняются после
write
того, как системный вызов возвращается. Это второе и наиболее заметное для пользователя преимущество. Асинхронная запись ускоряет работу приложений, поскольку они могут продолжать работу, не дожидаясь, пока данные действительно окажутся на диске. Тот же самый тип буферизации / кэширования также реализован для операций чтения, когда недавно или часто блоки чтения сохраняются в памяти вместо повторного чтения с диска.Не обязательно. Это зависит от используемой файловой системы и имеющейся избыточности. Ошибка ввода-вывода может быть безвредной, если данные могут быть сохранены в другом месте. Современные файловые системы, такие как ZFS, самостоятельно исцеляют плохие блоки дисков. Также обратите внимание, что ошибки ввода-вывода не приводят к сбою современных ОС. Если они происходят во время доступа к данным, они просто сообщаются уязвимому приложению. Если они происходят во время доступа к структурным метаданным и подвергают файловую систему риску, она может быть перемонтирована только для чтения или недоступна.
Существует также небольшой риск потери данных в случае сбоя ОС, сбоя питания или аппаратного сбоя. По этой причине приложения, которые должны быть на 100% уверены, что данные находятся на диске (например, базы данных / финансовые приложения), выполняют менее эффективные, но более безопасные синхронные записи. Чтобы уменьшить влияние на производительность, многие приложения по-прежнему используют асинхронные записи, но в конечном итоге синхронизируют их, когда пользователь явно сохраняет файл (например, vim, текстовые процессоры).
С другой стороны, подавляющее большинство пользователей и приложений не нуждаются и не заботятся о безопасности, которую обеспечивают синхронные записи. В случае сбоя или перебоя в питании единственным риском часто является потеря в худшем случае последних 30 секунд данных. Если не происходит финансовых транзакций или чего-то подобного, что подразумевает затраты, значительно превышающие 30 секунд их времени, огромный выигрыш в производительности (который не является иллюзией, но вполне реальным) позволяет асинхронным операциям записи значительно превосходить риск.
Наконец, синхронных записей недостаточно для защиты записанных данных. Если ваше приложение действительно должно быть уверено, что его данные не могут быть потеряны, что бы ни происходило, необходимо установить репликацию данных на нескольких дисках и в нескольких географических точках, чтобы противостоять таким стихийным бедствиям, как пожар, наводнения и т. Д.
источник
Это просто дает иллюзию скорости программам, которым на самом деле не нужно ждать завершения записи. Смонтируйте ваши файловые системы в режиме синхронизации (который дает вам мгновенную запись) и посмотрите, насколько все медленно.
Иногда файлы существуют только временно ... программа выполняет некоторую часть работы и удаляет файл сразу после завершения работы. Если вы отложите эти записи, вы можете избежать того, что вообще не написали их.
О, абсолютно. В таком случае, как правило, вся файловая система переходит в режим только для чтения, и все ужасно. Но это случается редко, нет смысла терять преимущества в производительности в целом.
источник
Асинхронный буферизованный ввод / вывод использовался до Linux и даже до Unix. У Unix было это, и у всех его ответвлений.
Вот что написали Ричи и Томпсон в своей статье CACM «Система разделения времени UNIX» :
В своем вопросе вы также написали:
Да, запись может завершиться неудачно, и программа может даже не узнать об этом. Хотя это и не очень хорошо, последствия этого можно минимизировать в тех случаях, когда ошибка ввода-вывода вызывает системную панику (в некоторых ОС это настраивается - вместо паники система может продолжать работать, но уязвимая файловая система не монтируется или монтируется только для чтения). Затем пользователи могут быть уведомлены о том, что данные в этой файловой системе являются подозрительными. Кроме того, можно активно отслеживать дисковод, чтобы увидеть, быстро ли растет его увеличенный список дефектов , что свидетельствует о его неисправности.
BSD добавил
fsync
системный вызов, чтобы программа могла быть уверена, что ее файловые данные были полностью записаны на диск перед продолжением, и последующие системы Unix предоставили опции для синхронной записи. GNU dd имеет опцию,conv=fsync
чтобы убедиться, что все данные были записаны до выхода из команды. Это удобно при записи на медленные съемные флэш-накопители, где для записи буферизованных данных может потребоваться несколько минут.Другим источником повреждения файлов является внезапное отключение системы, например, из-за потери питания. Практически все современные системы поддерживают флаг clean / dirty в своих файловых системах. Флаг устанавливается на очистку, когда больше нет данных для записи и файловая система собирается отключиться, как правило, во время завершения работы системы или путем ручного вызова
umount
. Системы обычно запускаютсяfsck
после перезагрузки, если обнаружат, что файловые системы не были закрыты корректно.источник
Много хороших ответов, но позвольте мне добавить еще одну вещь ... Помните, что Unix является многопроцессорной и многопользовательской системой, поэтому потенциально многие пользователи будут пытаться выполнять файловые операции (особенно записи) в (почти) то же время. Со старыми медленными жесткими дисками - возможно, установленными по сети - это не только займет время (для которого программы будут в основном блокироваться, и пользователям придется ждать), но и вызовет много перемещения головки чтения / записи. диск туда и обратно.
Таким образом, вместо этого файлы, ожидающие записи, некоторое время оставались в памяти и сортировались после того, как они должны были оказаться на диске ... и когда буфер был заполнен - или демон синхронизации диска ожидал требуемое количество секунд (я думаю, что обычно это было около 30 секунд) - весь буфер был записан на диск «по порядку», причем головке записи нужно было только сделать одно непрерывное движение, записывая файлы на диск как это пошло ... вместо того, чтобы прыгать повсюду.
Конечно, с современными быстрыми дисками - не говоря уже о твердотельных устройствах - выигрыш намного меньше ... особенно в домашней linux-системе, где одновременно работает только один пользователь и только с несколькими программами.
В любом случае, сочетание ожидаемого чтения с чтением (в кэш / буфер) больше, чем было запрошено - и сортировка данных, ожидающих записи, чтобы их можно было записать «одним движением» - на самом деле была очень хорошей идеей для время, особенно в системах с большим количеством чтения и записи многими пользователями.
источник
Он не специфичен для Linux и называется кешем страниц (что у Linux довольно хорошо). Смотрите также http://linuxatemyram.com/ ; поэтому, если файл записан, то через несколько секунд прочитайте снова, очень часто не требуется дисковый ввод-вывод.
Основным преимуществом является то, что во многих системах имеется много оперативной памяти, и некоторые из них могут использоваться ядром в качестве кэша. Поэтому некоторые операции с файлами могут извлечь выгоду из этого кэширования. Кроме того, время дискового ввода-вывода намного медленнее (обычно в тысячи раз для SDD и почти в миллион раз медленнее для механических жестких дисков), чем для оперативной памяти.
Код приложения может дать подсказки относительно этого кэширования: см., Например, posix_fadvise (2) и madvise (2)
источник
Вращающиеся пластины работают медленнее, чем RAM. Мы используем кэширование операций чтения / записи, чтобы «скрыть» этот факт.
Полезная вещь в записи IO заключается в том, что она не требует немедленного ввода-вывода диска - в отличие от чтения, когда вы не можете вернуть данные пользователю, пока чтение не завершится на диске.
Таким образом, записи выполняются в мягких временных рамках - пока наша поддерживаемая пропускная способность не превышает пропускную способность нашего диска, мы можем скрыть много потерь производительности в кэше записи.
И нам нужно писать в кеш - вращающиеся диски сравнительно медленные. Но так что современные типы RAID имеют существенные неудобства для работы.
Например, RAID 6, чтобы выполнить один ввод-вывод, должен:
Таким образом, каждая запись - это фактически 6 операций ввода-вывода - и особенно если у вас медленные диски, такие как большие диски SATA, это становится чрезвычайно дорогим.
Но есть хорошее простое решение - напиши коалесценцию. Если вы можете создать запись с полной полосой в буфере, вам не нужно считывать информацию о четности с вашего диска - вы можете вычислить ее на основе того, что у вас есть в памяти.
Это очень желательно сделать, потому что тогда у вас больше не будет усиления записи. В самом деле, вы можете получить более низкий штраф за запись, чем RAID 1 + 0.
Рассмотреть возможность:
RAID 6, 8 + 2 - 10 шпинделей.
8 последовательных блоков данных для записи - вычислить четность в кеше и записать один блок на каждый диск. 10 записей на 8 означает штраф за запись 1,25. 10 дисков RAID 1 + 0 по-прежнему имеют штраф на запись 2 (потому что вы должны записывать в каждое подзеркало). Таким образом, в этом сценарии вы можете заставить RAID 6 работать лучше, чем RAID1 + 0. В реальном мире вы получаете немного больше смешанного профиля ввода-вывода.
Таким образом, кэширование записи имеет огромное значение для воспринимаемой производительности RAID-наборов - вы получаете возможность записи со скоростью ОЗУ и получаете низкий штраф за запись - улучшая вашу устойчивую пропускную способность, если вы это делаете.
А если нет, то вы страдаете от медленной производительности SATA, но умножаете ее на 6 и добавляете некоторую конкуренцию. Ваш 10-канальный SATA RAID-6 без кэширования записи будет немного быстрее, чем один диск без RAID ... но не намного.
Вы рискуете, хотя, как вы заметили, потеря питания означает потерю данных. Вы можете уменьшить это путем циклов очистки кэша, резервного копирования батареи вашего кеша или использования SSD или других энергонезависимых кешей.
источник
Ни в одном из других ответов не упоминается задержка распределения . XFS, ext4, BTRFS и ZFS все используют его. XFS использует его еще до появления ext4, поэтому я буду использовать его в качестве примера:
XFS даже не решает, куда поместить данные до выписки. Задержка-распределение дает распределителю гораздо больше информации для принятия решений. Когда файл впервые записывается, нет способа узнать, будет ли это файл 4k или файл 1G и все еще растущий. Если где-то есть 10G смежного свободного места, поместить файл 4k в начало не имеет смысла. Размещение большого файла в начале большого свободного пространства уменьшает фрагментацию.
источник
Все остальные ответы здесь, как минимум, в основном правильны для обычного случая, и я бы рекомендовал прочитать любой из них перед моим, но вы упомянули, что dd и dd имеют типичный вариант использования, который может не включать кэширование записи. Кэширование записи в основном реализовано на уровне файловой системы. Необработанные устройства обычно не выполняют кэширование при записи (различные драйверы устройств, такие как raid или lvm, являются еще одним шариком воска). Поскольку dd часто используется с необработанными блочными устройствами, он предоставляет параметры bs и связанные с ними параметры, позволяющие выполнять большие записи для повышения производительности на необработанных устройствах. Это не так полезно, когда обе конечные точки являются обычными файлами (хотя при больших операциях записи в этом случае используется меньше системных вызовов). Другое распространенное место, где это особенно заметно, - это пакет mtools, являющийся реализацией файловой системы в пользовательском пространстве. использование mtools с флоппи-дисководом всегда кажется невероятно медленным, поскольку инструменты полностью синхронизированы, а флоппи-дисководы невероятно медленны. Монтирование дискеты и использование файловой системы с толстым ядром намного более отзывчивы, за исключением размонтирования, которое является синхронным (и очень важно, чтобы он предотвращал потерю данных, особенно для съемных устройств, таких как дискеты). Есть только несколько других программ, которые, как мне известно, регулярно используются с необработанными устройствами, такими как специально настроенные базы данных (которые реализуют их собственное кэширование записи), tar и специальные инструменты для устройств и файловых систем, такие как chdsk, mkfs и mt. Монтирование дискеты и использование файловой системы с толстым ядром намного более отзывчивы, за исключением размонтирования, которое является синхронным (и очень важно, чтобы он предотвращал потерю данных, особенно для съемных устройств, таких как дискеты). Есть только несколько других программ, которые, как мне известно, регулярно используются с необработанными устройствами, такими как специально настроенные базы данных (которые реализуют их собственное кэширование записи), tar и специальные инструменты для устройств и файловых систем, такие как chdsk, mkfs и mt. Монтирование дискеты и использование файловой системы с толстым ядром намного более отзывчивы, за исключением размонтирования, которое является синхронным (и очень важно, чтобы он предотвращал потерю данных, особенно для съемных устройств, таких как дискеты). Есть только несколько других программ, которые, как мне известно, регулярно используются с необработанными устройствами, такими как специально настроенные базы данных (которые реализуют их собственное кэширование записи), tar и специальные инструменты для устройств и файловых систем, такие как chdsk, mkfs и mt.
источник
O_DIRECT
если вы хотите обойти кеш.dd oflag=direct
, IIRC, некоторые устройства по умолчанию направляют ввод / вывод на блочных устройствах. (И требуют чтения / записи выровненных блоков, чего нет в Linux, потому что в любом случае это просто запись кэша страниц.)Философия небезопасна по умолчанию.
Возможны две разумные и очевидные стратегии: немедленная запись на диск или задержка записи. UNIX исторически выбрал последнее. Так что получите безопасность, вам нужно позвонить
fsync
потом.Однако вы можете указать безопасность заранее, подключив устройство с опцией
sync
, или для каждого файла, открыв их с помощьюO_SYNC
.Помните, что UNIX был разработан для компьютерных экспертов. «Безопасный по умолчанию» не рассматривался. Безопасность означает более медленный ввод-вывод, и эти ранние системы действительно имели медленный ввод-вывод, что делает цену более высокой. К сожалению, ни UNIX, ни Linux не переключились на safe-be-default, хотя это и является непреложным изменением.
источник
Он обменивает небольшую надежность на значительное увеличение пропускной способности.
Предположим, например, программа сжатия видео. С отложенной записью («обратная запись»):
Против
Вторая версия появляется в два раза быстрее, потому что она может использовать процессор и диск одновременно, в то время как первая версия всегда ожидает одну или другую.
Обычно требуется обратная запись для потоковых операций и массовых файловых операций, а также сквозная запись для баз данных и приложений, подобных базам данных.
источник
Во многих приложениях запоминающие устройства будут периодически заняты чтением данных. Если система всегда может отложить запись до того момента, когда устройство хранения не будет занято чтением данных, то с точки зрения приложения для записи будет нулевое время для завершения. Единственные ситуации, в которых записи не были бы мгновенными, были бы когда:
Буферы записи заполняются до такой степени, что никакие запросы отложенной записи не могут быть приняты до тех пор, пока запись не завершится.
Необходимо выключить или удалить устройство, для которого ожидают записи.
Приложение специально запрашивает подтверждение того, что запись фактически завершена.
На самом деле, только из-за вышеупомянутых требований, которые когда-либо должны быть выполнены, на самом деле они должны выполняться. С другой стороны, как правило, нет причин не выполнять какие-либо ожидающие записи в те моменты, когда устройство в противном случае находилось бы в режиме ожидания, поэтому многие системы выполняют их тогда.
источник
Существует также это:
Напишите «Привет, Джо Мо»
быстрее, чем:
Напишите «Привет»,
напишите «Джо»
Напишите «Мо»
А также:
Напиши "Привет, как дела?"
быстрее чем:
напиши "Привет, как дела?"
Удалить это
Написать "Привет, как дела?"
Удалить это
Написать "Привет, как дела?"
Модификации и агрегирование лучше выполнять в оперативной памяти, чем на диске. Пакетная запись дисков освобождает разработчиков приложений от таких забот.
источник