Когда я должен использовать /dev/shm/ и когда я должен использовать /tmp/?
Когда я должен использовать /dev/shm/
и когда я должен использовать /tmp/
? Могу ли я всегда полагаться на то, что они оба находятся в Unices?
Когда я должен использовать /dev/shm/
и когда я должен использовать /tmp/
? Могу ли я всегда полагаться на то, что они оба находятся в Unices?
В порядке убывания tmpfs
вероятность:
┌───────────┬──────────────┬────────────────┐
│ /dev/shm │ always tmpfs │ Linux specific │
├───────────┼──────────────┼────────────────┤
│ /tmp │ can be tmpfs │ FHS 1.0 │
├───────────┼──────────────┼────────────────┤
│ /var/tmp │ never tmpfs │ FHS 1.0 │
└───────────┴──────────────┴────────────────┘
Так как вы спрашиваете о точке монтирования tmpfs, специфичной для Linux, в сравнении с каталогом, определяемым портом, который may be tmpfs (в зависимости от вашего системного администратора и того, что по умолчанию используется в вашем дистрибутиве), ваш вопрос имеет два аспекта, на которые в других ответах были сделаны другие отличные акценты:
Консервативное издание (смесь конвенций из FHS и общего пользования):
/tmp
. /var/tmp
для больших данных, которые могут нелегко поместиться в таран. /var/tmp
для данных, которые полезно хранить при перезагрузках (например, кэш). /dev/shm
как побочный эффект вызова shm_open()
. Целевая аудитория - ограниченные буферы, которые бесконечно перезаписываются. То есть это для давно существующих файлов, содержимое которых нестабильно и не страшно велико. mktemp
чтит переменную окружения TMPDIR
. Прагматичная редакция:
Используйте /dev/shm
, когда важно использовать tmpfs, /var/tmp
, когда важно не использовать, иначе /tmp
.
fsync
- это no-op на tmpfs. Этот syscall - враг номер один в производительности (IO) (и флэш-долголетия, если вас это волнует), хотя если вы используете tmpfs (или eatmydata ) только для того, чтобы победить fsync, то вы (или какой-нибудь другой разработчик в цепочке) делаете что-то не так. Это означает, что транзакции к запоминающему устройству неоправданно мелкозернистые для вашей цели - вы явно готовы пропустить некоторые точки сохранения для повышения производительности, как вы сейчас пошли на крайний случай, саботируя их все - редко лучший компромисс. Кроме того, именно здесь, в стране транзакционной производительности, есть одни из самых больших преимуществ SSD - любой приличный SSD будет работать вне этого мира по сравнению с тем, что может занять вращающийся диск (7200 об/мин = 120 Гц, если к нему нет доступа), не говоря уже о картах флэш-памяти, которые сильно отличаются по этому показателю (не в последнюю очередь потому, что это компромисс с последовательной производительностью, которую они оценивают, например, по классу карты SD). Так что будьте осторожны, разработчики с молниеносно быстрыми SSD, не заставляйте своих пользователей использовать их в таком случае!
Хотите услышать нелепую историю? Мой первый урок fsync
: У меня была работа, которая заключалась в рутинной “модернизации” кучки баз данных Sqlite (хранящихся в виде тестовых примеров) до постоянно меняющегося текущего формата. Обновление" фреймворка выполняло кучу скриптов, делая как минимум по одной транзакции каждый, чтобы обновить одну базу данных. Конечно, я обновлял свои базы данных параллельно (8 параллельно, так как я был благословлен могучим 8-ядерным процессором). Но, как я выяснил, никакого ускорения распараллеливания не было (скорее небольшое hit), так как процесс был полностью связан с IO. К сожалению, обертывание фреймворка обновления в скрипт, который копировал каждую базу данных в /dev/shm
, обновлял ее там и копировал обратно на диск, было примерно в 100 раз быстрее (все еще с 8 параллельными). В качестве бонуса, при обновлении баз данных ПК тоже был usable.
Надлежащее использование tmpfs позволяет избежать ненужной записи волатильных данных. Эффективное отключение writeback, например, установка /proc/sys/vm/dirty_writeback_centisecs
на бесконечность в обычной файловой системе.
Это очень мало связано с производительностью, а неудача - это гораздо меньшая проблема, чем злоупотребление fsync: Таймаут обратной записи определяет, как лениво обновляется содержимое диска после обновления содержимого страниц в кэше, а по умолчанию 5 секунд - это длительное время для компьютера - приложение может перезаписывать файл так часто, как оно хочет, в кэше страниц, но содержимое на диске обновляется только примерно раз в 5 секунд. Если только приложение не проталкивает его с помощью fsync, то есть. Подумайте, сколько раз приложение может вывести небольшой файл за это время, и вы поймете, почему синхронизация каждого файла будет гораздо большей проблемой.
fsync
. Хранение данных cold. Вы можете подумать, что обслуживание файлов из подкачки так же эффективно, как и обычная файловая система, но есть пара причин, почему это не так:
Ладно, вот реальность.
И tmpfs, и обычная файловая система - это кэш памяти на диске.
tmpfs использует память и пространство подкачки, так как при резервном хранении файловая система использует определенную область диска, ни то, ни другое не ограничено размером файловой системы, вполне возможно иметь 200 ГБ tmpfs на машине с менее чем гигабайтом тарана, если у вас достаточно пространства подкачки.
Разница заключается в том, когда данные записываются на диск. Для tmpfs данные записываются ТОЛЬКО тогда, когда память переполняется или данные вряд ли будут использованы в ближайшее время. OTOH большинство обычных файловых систем Linux спроектированы так, чтобы всегда иметь более или менее последовательный набор данных на диске, так что если пользователь выдернет вилку, он не потеряет все.
Лично я привык к тому, что операционные системы не выходят из строя, и системы ИБП (например, батареи ноутбуков), поэтому я думаю, что файловые системы ext2/3 слишком параноидальны с их интервалом в 5-10 секунд. Файловая система ext4 лучше с 10-минутной контрольной точкой, за исключением того, что она рассматривает данные пользователя как данные второго класса и не защищает их. (ext3 то же самое, но вы этого не замечаете из-за 5-ти секундной контрольной точки)
Эта частая проверка означает, что ненужные данные постоянно записываются на диск, даже для /tmp.
В результате вам нужно создать пространство подкачки размером с /tmp (даже если вам нужно создать файл подкачки) и использовать это пространство для монтирования tmpfs нужного размера в /tmp.
НИКОГДА не используйте /dev/shm.
Если только вы не используете его для очень маленьких (возможно mmap’d) IPC файлов, и вы уверены, что он существует (это не стандарт) и на машине более чем достаточно памяти + подкачки.
Используйте /tmp/ для временных файлов. Используйте /dev/shm/, когда вам нужна разделяемая память (т.е. межпроцессное взаимодействие через файлы).
Вы можете положиться на /tmp/, но /dev/shm/ - это относительно недавняя версия Linux.
Другой раз, когда вы должны использовать /dev/shm (для Linux 2.6 и выше), это когда вам нужна гарантированная файловая система tmpfs, потому что вы не знаете, можете ли вы can записать на диск.
Мониторинговая система, с которой я знаком, должна записывать временные файлы во время сборки отчета для отправки на центральный сервер. На практике гораздо более вероятно, что что-то помешает записи в файловую систему (либо из дискового пространства, либо отказ основного RAID заставил систему работать в режиме “только для чтения”), но вы все равно сможете прихрамывать, чтобы предупредить об этом, чем если бы что-то закрутило всю доступную память так, что tmpfs был бы непригоден для использования (и коробка не была бы мертва). В таких случаях система мониторинга предпочитает записывать в оперативную память, чтобы иметь возможность послать предупреждение о полном диске или о мертвом/умирающем оборудовании.
/dev/shm используется для драйверов устройств и программ, специфичных для общих виртуальных систем памяти.
Если вы создаете программу, требующую кучу виртуальной памяти, которая должна быть отображена в виртуальную память. Это удваивается, так что если вам нужно несколько процессов или потоков, чтобы иметь безопасный доступ к этой памяти.
Дело в том, что только потому, что драйвер использует для этого специальную версию tmpfs, не означает, что вы должны использовать ее в качестве общего раздела tmpfs. Вместо этого, вы должны просто создать еще один раздел tmpfs, если вы хотите создать его для своего временного каталога.
В PERL, имея минимум 8 ГБ на любой машине (все под управлением Linux Mint), я считаю хорошей привычкой делать DB_File-based (структура данных в файле) сложные алгоритмы с миллионами чтений и записей, используя /dev/shm
На других языках, не имея повсюду гигатера, чтобы избежать стартов и остановок при сетевой передаче (работая локально на файле, который находится на сервере в атмосфере клиент-сервер), используя пакетный файл какого-то типа, я скопирую весь (300-900MB) файл сразу в /dev/shm, запущу программу с выводом в /dev/shm, запишу результаты обратно на сервер, и удалю из /dev/shm
Естественно, если бы у меня было меньше оперативной памяти, я бы этого не делал. Обычно файловая система in-memory /dev/shm читается размером в половину от имеющейся у вас оперативной памяти. Однако, обычное использование оперативной памяти является постоянным. Так что вы действительно не могли бы сделать это на устройстве с 2 ГБ или меньше. Чтобы превратить перефразировку в гиперболе, в оперативной памяти часто встречаются вещи, о которых даже система не сообщает хорошо.