Как стать автором
Обновить

Комментарии 66

Процессоры i386 и подобные не умеют размеры блока, не соответствующие размеру страницы памяти, а она ровно 4к.

Что-то здесь не так:

$ uname -a
Linux athlon 4.15.0-51-generic #55-Ubuntu SMP Wed May 15 14:27:21 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ man mkfs.ext2

OPTIONS
-b block-size
Specify the size of blocks in bytes. Valid block-size values are 1024, 2048 and 4096 bytes per block. If omitted, block-size is heuristically determined by the filesystem size and the expected usage of the filesystem (see the -T option). If block-size is preceded by a negative sign ('-'), then mke2fs will use heuristics to determine the appropriate block size, with the constraint that the block size will be at least block-size bytes. This is useful for certain hardware devices which require that the blocksize be a multiple of 2k.

30 секунд… многовато будет. Причем основное время уходит на обработку файлов в user space, а вовсе не на работу ядра.

Но решение есть:

Проблема с ls в том, что оно сортирует список перед выводом на экран, что приводит к тормозам на чахлом процессоре. Очевидное решение — отключить сортировку, и оно работает немного быстрее, чем трюк с find:

$ time ls largedir >/dev/null

real	0m2,199s
user	0m1,695s
sys	0m0,302s
$ time find largedir >/dev/null

real	0m0,848s
user	0m0,526s
sys	0m0,257s
$ time ls -U largedir >/dev/null

real	0m0,499s
user	0m0,261s
sys	0m0,229s

Соглашусь, я сам пробовал больше 4096 и была проблема, и решил, что должно быть ровно 4096, а на самом деле должно быть меньше, но не обязательно ровно. Но 1024 и 2048 не выставлял :)
НЛО прилетело и опубликовало эту надпись здесь
Зависит от конкретной ситуации. Когда система с файлами уже есть, то намного проще перепаковать в zip, чем городить абсолютно новую систему с базой. В каких-то случаях база вполне оправдана, особенно если решение проектируется с нуля.
Загнав файлы (как блобы) в бд, вы обретёте массу граблей, по которым впоследствии будете с удовольствием прыгать.
Загнал 56 миллионов файлов как блобы в БД, брат жив. Единственной печалью была некоторая неготовность драйвера к БД для Go вынимать их оттуда с частотой несколько тысяч раз в секунду, через что gc там случался чуть ли не каждые 0.3 с. Но даже это было значительно лучше вороха файлов на ФС.

Не проще было для такой задачи использовать объектное хранилище, вроде того же minio? Гораздо проще масштабировать, удобное управление доступом, меньше оверхед на метаданные и файлы можно прям оттуда раздавать

Это сильно зависит от размера файлов. Сами авторы пишут, что хороший минимальный средний размер файла в районе 100 КБ. Если файлы будут сильно меньше, то лучше рассмотреть что-то другое.
Управление доступом, кстати, удобное только пока простое. Потом оно либо становится неудобным, либо в принципе недостаточно гибким. Есть такой пример: если сделать доступными файлы из какого-то бакета по префиксу доступными на чтение (через WebUI или консольный клиент), то стандартный WebUI позволял просматривать их список без авторизации. Решалось только применением кастомных политик. Возможно, сейчас исправлено.

Если вам никогда не надо посмотреть, что на самом деле воон в том файле, или, не дай бог, срочно заменить неправильный на правильный, и уж точно никогда не надо восстанавливать бекап прошлогодней базы — могу только порадоваться за вас.

Первые две задачи делаются штатным клиентом СУБД довольно удобно (хотя если возникают часто — то с просто файлами не сравнятся, конечно же).


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

Не знаю, каким клиентом это делается удобно. SMSS и жаба не умеют удобно это делать.
Есть способ получать эти данные напрямую из nginx? Не будет ли это решение медленней, чем описанное в посте?
Обычно в таких случаях создают вложенные каталоги, по первым буквам имени файла или по каким-либо другим параметрам, например, по датам, в большинстве случаев это спасает.

Однако если вдруг однажды потребуется обход по всем файлам (например, чтобы сделать бэкап или rsync), то он будет нереально долгим. Сейчас попробовал сделать простой find -type f по одному такому своему каталогу (55 тысяч файлов, заботливо рассованных по подкаталогам) — заняло целых три минуты (и это я даже не пытался читать само содержимое файлов). Перенёс всё в один-единственный каталог без вложенки — и даже ls с выдачей размера, сортировкой по имени и прочими радостями жизни отработал меньше чем за секунду (линуксовый кэш предварительно чистил, если что)


Впрочем, 55 тысяч это таки далеко не 55 миллионов. Буду надеяться, что полный обход по 55 миллионам файлов мне никогда не придётся делать)

55 тысяч файлов, заботливо рассованных по подкаталогам) — заняло целых три минуты

time find . -type f|wc -l
914621

real    1m24,456s
user    0m0,864s
sys     0m9,412s

По NFS вообще.
мониторит файловую систему на предмет изменений с использованием inotify

Вроде можно случайно упереться в ядрёные лимиты типа fs.inotify.max_user_watches?

Я могу ошибаться, но даже если в каталоге файлов много, а нам нужно отслеживать создание — то достаточно мониторить сам каталог, а не все файлы в нем. В нашем кейсе файл создается и больше никогда не меняется, поэтому отслеживать изменения самих файлов не нужно. Если же мониторить все файлы — то это явно не то решение, которое подойдет в данном случае.
Проблема шестая: как понять, кто грузит диски

fatrace

А подскажите пожалуйста про складирование мелких файлов в zip и отдачу через nginx, а сколько тыс файлов разумно ложить в архив или какого макс размера желателен размер архива чтобы отдача была максимально быстрой? Спасибо.
Мы не проводили бенчмарки на максимальный размер файла, у нас файлы складываются поминутно в каталог, и этот каталог жмется в архив, примерно по 1000 файлов в архиве, 25-30 мегабайт архив получается. Каких-то затруднений не испытывали, но опять же тут зависит от Вашей схемы использования, сколько вам надо отдавать в единицу времени, размер самих файлов и кучи других параметров. На Вашем месте я бы попробовал разные варианты, померял скорость и потом уже решал, что и как именно использовать.
Простите, у вас там ext4 чтоли? И как на вашем объеме fschk?
С fanotify, т.е с lsyncd, тоже будут проблемы. Изменения в фс могут произойти до того, как успеют подвеситься все вотчеры фанотифая. Если задержка не критична, то это решается периодическим полным rsync. Но это уже совсем не live, конечно.
Еще он капризный и совсем недавно были фиксы в ядре www.opennet.ru/opennews/art.shtml?num=50631
Мы не очень доверяем lsyncd. Вцелом такую схему мы используем для бэкапа, так что в нашем конкретном случае не критично, если один файлик потеряется по пути. Периодически раз в день делаем полный rsync.
Вообще, задача интересная, я такие лю :)
Очевидно, штатные фс и подходы вам будут жать. Вероятно, вам не нужна фс как таковая, скорее всего более подходящим будет тот или иной object storage. Из простого — монгодб (gridfs), посложнее — ceph.
Если оставаться все же в рамках фс, то я бы глянул на zfs. Она требует вдумчивости, но например вы могли бы выделить память и ссд только под кэширование метаданных, соотв уйдут тормоза с поиском файла (после прогрева кэша). Да, штатный pagecache тоже кэширует, но будет вымываться чтением данных.
Если у вас там файлы жмутся хорошо — получите прозрачное сжатие.
Главное! Не. Включайте. Дедупликацию. :)
А, а насчет синхронизации, там есть родной zfs send.
Мы поэкспериментировали с прозрачным сжатием на zfs: на SSD положили mysql базу. Пока радуемся жизни, все стало в разы быстрее, чем на обычных HDD, и при это влезло на SSD (размер базы сейчас порядка 1.3 Тб). С файлстораджем так не экспериментировали, но почему бы и нет.
Ну вот насчет класть на ZFS БД — не уверен. Мускуль же журналируемый(?), а ZFS — copy-on-write, получается двойная избыточность. Если не ошибаюсь, то уважаемый amarao резко отрицательно высказывался о таких конфигурациях.
Кстати, с ZFS на SSD вы заодно получите работающий trim, чего на железных RAID вы не имеете. Только если будете ставить ZFS в продакшене — не подключайте диски через железный RAID, ну на крайняк в RAW режиме (адаптек умеет, LSI — не умеет).

Насчет сжатия на zfs — это скорее приятное дополнение к остальным фичам, но совсем не основное. Если у вас более-менее серьезные объемы и кол-во файлов — нужна соответствующая ФС. Увы, из бесплатного есть только ZFS и XFS. Хотя сравнивать их безусловно нельзя.

И еще. =) В данный момент ZFS лучше поднимать на Freebsd. Пока, в ближайшем будущем (после R12), видимо, разницы с ZoL уже не будет — кодовая база объединяется.

Нет, мне не уняться…
>Пока радуемся жизни
Следите. SSD коварен, если вдруг кончится место для очистки мусора, получите резкую деградацию до уровня десктопного SATA. Если не секрет — какую модель SSD использовали?
Вы же знаете про деградацию скорости записи новых файлов на zfs при заполнении на ~80% и выше?
Zfs перестаёт создавать новые stripes, зато начинает уплотнять старые, производительность неожиданно падает и это обычно неприятный сюрприз.

Любая файловая система деградирует, когда количество свободного места меньше ХХ %. Это не специфично только для ZFS.
Т.е., извините — хотите гарантированную производительность — оставляйте свободное место.
Еще хуже то, что в случае с НТФС — производительность при забитии на 99% падает, а потом, когда место появляется — она не возвращается в норму.

Почему-то именно с zfs встречал реакцию «не может быть, наверное, это баг или железные проблемы», хотя такое поведение описано в мануалах.

Всё не так страшно, но да, она деградирует.
Специфично это не для всех ФС, а для copy-on-write.
На XFS у меня несколько 100+Tb массивов залиты под самое горлышко и всё хорошо.
С ZFS такие шутки могут выйти боком, да.

MySQL с каким хранилищем? А то RocksDB рулит. Движок специально оптимизирован под хранение на SSD. И жмёт хорошо, если настроить. Ну там, конечно, надо подумать над полями и индексами, чтобы оверхед был поменьше, сжатие получше, а работа побыстрее. Ниже я чуть подробнее расписал, как данные хранятся у меня и в виде файлов, и в базе.
Почему бы вам не воспользоваться ReiserFS? Он как раз для большого количества небольших файлов
Я тоже бы советовал приглядеться к этой FS, она спроектирована для мелких файлов, динамически добавляет inodes (причем может делать это в одном блоке вместе с данными) и умеет делить блоки между файлами.

О преимуществах ReiserFS
Benchmark схожего use case

Но естественно, нужно тестить под ваш use case.
Да, и ловить потом кернел паник раз в месяц. Уж не знаю, как так вышло, но инсталляция Ubuntu 14.04 (ещё и с ZoL для другой ФС) с ReiserFS с кучей мелких файлов (Zoneminder) таким образом меня радовала. Полгода ковырялся, в конце психанул и поменял всё железо, и получил то же поведение. Потом прозрел и выбросил труп лошади, и всё стало хорошо. Что-то в кодовой базе ReiserFS уже протухло, по всей видимости.

Файл это нечто больше 64 килобайт, как минимум. Все что меньше это поле в БД.

Простие, а откуда такая классификация?
Спасибо! Очень вовремя!
Ещё добавьте опции монтирования noatime,nodiratime — тогда ещё сможете выиграть IOPs-ов, на большом количестве файлов это бывает заметно.

Как вариант — можете попробовать не ext4, а btrfs/ReiserFS или jfs/xfs — но последние 2 могут развалиться при внезапном отрублении электричества. xfs очень хорошо работает с большим количеством больших файлов на огромных разделах.
Вы не путаете, может это первые две могут развалиться? Вроде, btr умеет разваливаться и сама =)
У меня XFS уже больше 5 лет где-то на 3х десятках хостов, местами разделы по 150Т. Отрубали искричество не раз — пока ни разу не развалилась.
Не путаю, отрубание света для всех FS — это лотерея, журналируемые меньше подвержены сюрпризам, но тоже случается. У меня такое встречалось, один раз fsck.jfs и xfs_repair помог, а один раз ничего не помогло, увы. Бэкапы — наше всё!

Безусловно, сломать можно всё, но повреждения могут быть вызваны битой памятью и/или дисковой системой — в этом случае ничего не спасет, кроме бэкапов, да =)
В частности, та же ZFS очень болезненно относится к битой памяти вплоть до умирания всего пула. А вот диски мы из неё доставали прямо во время работы — всё ок.

Слушайте, ну не бывает совсем безглючного софта, тем более в таких сложных штуках, как ФС.
Прочитал ваш тикет — подозрительно, но вам тоже сказали, что это больше похоже на железную проблему. EXT4 вы проверяли на другом сервере, что только больше подтверждает теорию.
8-10 дисков по 10Т — не абы какой объем для xfs, у меня буквально недавно было 4 хоста, в каждом 12 10Тб-ков. Гоняли под нагрузкой, зависания были, но виновником был контроллер. Хотя в итоге всё равно ушли на XFS on FreeBSD. И наступили покой и счастие. =)

Слушайте, ну не бывает совсем безглючного софта, тем более в таких сложных штуках, как ФС.

не находите, что fs — как раз та вещь, от которой хочешь безглючности? чаще всего фичи не важны, если фс не может стабильно работать.

EXT4 вы проверяли на другом сервере, что только больше подтверждает теорию.

разумеется на другом, этот (а точнее пара) стоит в хетцнере и отдаёт контент 24/7 на скорости 0.5-1Гбит/c. поднять рядом ещё один с ext4 и перелить на него — это примерно 400 евро, я не решился столько тратить на эксперииенты

и на другом я получил то же самое — xfs иногда фризится. с ext4 (на том же другом сервере) вопроизвести проблему не удалось.

всё равно ушли на XFS on FreeBSD

вы хотели сказать zfs?
не находите, что fs — как раз та вещь, от которой хочешь безглючности?

Нахожу. Хочу такую. Найдете — расскажите, плиз :)


вы хотели сказать zfs?

да, конечно, zfs


Насчет фризов, согласитесь, если бы был баг, он бы проявлялся не только у вас. Тем не менее, за несколько лет коллег по несчастью не нашлось. Поэтому, увы.
А Хейцнер, это которые ставят б/у шное железо? Были у их, да :)

Мне показалось удобнее использовать монтируемые ФС, а не архивы. Но у меня юзкейс — не только отдача по web, но и обычные файловые операции. В каждую тулзу zip не просунешь, увы… И вот тут внезапно squashfs — если делать архивы посуточно, понедельно и т.д. Получается "тот же zip", но при этом монтируется и даёт произвольный доступ. С другой стороны, много примонтированных архивов тоже не выглядит изящным решением.
Ещё экспериментировал с udf (там ещё и писать можно), но не масштабно.

Как то раз я столкнулся с нехваткой inode на хосте с ZoneMinder (видеорегистратор который хранит поток в виде картинок), перешел на btrfs для таких хостов, чего бы и рекомендовал.
Как заметили выше — рекомендую тоже отключить (опциями монтирования) записи времени чтения и доступа.
Напомню близкую по сути статью 2012 года «Так как же удалить миллионы файлов из одной папки?» от seriyPS.

Статья интересная, но я из заголовка ожидал увидеть советы типа


  1. не использовать ls * и аналогичные баш подстановки. Т.к. когда много файлов, то они взрываются.
  2. использовать find
  3. использовать пайплайнинг и xargs, где это возможно.
    и пр.

По inode — интересно насколько помогла бы тонкая настройка параметров ФС или использование других, более подходящих для мелких файлов (если таковые вообще есть) ФС.


Мораль: или продумывать все кейсы наперед, или не строить из себя супергероя и пользоваться стандартными настройками для домохозяек.

Это когда хочешь сделать что-то идеально, а потом сам себе роешь яму (не зная того) и в нее падаешь в конце-концов.

Он тоже работает через rsync, но дополнительно мониторит файловую систему на предмет изменений с использованием inotify и fsevents и запускает копирование только для тех файлов, которые появились или изменились.

Пишут, что inotify на 100500 файлов — это плохо. Не вызывало ли это проблем?

Почему Load Average=2 Вы считаете «плохим»? Специально сверился со статьей про этот показатель, он показывает общую нагрузку на систему и, как я понял, коррелирует с количеством процессоров.

Согласно указанной Вами статье, «большинство систем будут проседать при нагрузке/соотношении в районе 2.»

Но я исходил из нашего опыта на наших машинах, и в районе 2х более-менее, обычно меньше, 5-6 — это усердное копирование файлов, требует мониторинга админа, ибо чревато скачком, а при 8 уже клиенты ругаются.
LA — такая вещь, что может быть вполне 50 на ненагруженном хосте
для Windows тоже была проблема по синхронизации фотокаталога между серверами (по сути основной и бакап) решил созданием VHD и последующим его монтированием. При бакапе просто отключаем и копируем 1 файл. Работает быстрее.

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

Просто из любопытства, что вы там храните в таком количестве мелких файлов? Квантовую конфигурацию всех атомов во Вселенной? :)

Все объявления о продаже недвижимости, скриншоты, фото и много всего похожего
Вангую, что над файлами еще есть «прослойка» с хранением признаков и атрибутов.
Разумные рекомендации почти все озвучены.
Осталось напомнить, что Berkeley DB еще никто не отменял. А она быстрая.
В разных случаях по-разному, где-то хранятся атрибуты, где-то нет. Если это просто оригинальное объявление о продаже недвижимости — то оно всегда html, никаких атрибутов, но зато есть оно же разобранном виде, и это разобранное уже лежит в базе, причем не в одной. В других случаях хранится мета-инфа: размер картинки, тип данных внутри, оригинальное название…
В нашей практике помогало выставлять nice максимальным (19 — это минимальный приоритет, -20 (минус 20) — максимальный).
Это очень полезный совет, кстати.
Для процесса, который в основном занят вводом/выводом и почти ничего не считает в юзерспейсе, ставить максимальный приоритет (-20) — крайне выгодно. Т.к. этот процесс в основном вызывает syscall-ы ввода-вывода и ждёт результата. Получив квант времени от планировщика, этот процесс вызовет следующий syscall (т.е. немедленно отдаст CPU обратно).

Повышенный приоритет уменьшает время между двумя просыпаниями процесса (т.е. он сможет вызывать syscall-ы чаще), а отнимаемое у других процессов время — не меняется.
По поводу архивации. У меня есть задачка собирать потоки данных и где-то как-то их хранить.

Не так давно искал «идеальный архиватор», его, конечно, не нашёл, но нашёл довольно много интересного и немножко поапгрейдил своё хранилище.

Если надо экономить диск, то LZMA/LZMA2 жмёт в некоторых условиях раза в два лучше, чем GZIP (и заметно лучше, чем BZIP) правда, выше потребление RAM/CPU при паковке. Но это настраивается размерами словаря и прочими ключами. Распаковка чуть медленнее GZip-а. Контейнер Zip не умеет потоки LZMA, но их умеет, разумеется, 7-Zip. Ещё б не умел, если архиватор и алгоритм делал один и тот же человек. Вообще 7-Zip — весьма клёвый архиватор. К нему можно разные сжимательно-разжимательные плагины подключать. Программно можно юзать его через exec/pipe (7z {-si|-so}) или через libarchive. Разжатие через libarchive точно работает (в моём случае в python-скриптах), сжатие не проверял — нет надобности.

Если надо, наоборот, разгрузить проц, то безумно быстрые и при том сравнимые с зипом по сжатию — гугловский Brotli, фейсбучные ZSTD и LZ4. А распаковка у них вовсе реактивная, особенно Brotli.

Есть и другие алгоритмы, но они экзотические и не особо применимы в реальной жизни, в отличие от этих.

На данный момент собираю данные в текстовые логи без сжатия с почасовой ротацией и затем жму их офлайново в LZMA при помощи 7-Zip с плагином Fast LZMA. Он работает быстрее штатного раза в два. Сжатие доходит до 1:200. Да-да, Карл, в 200 раз, это не опечатка. Например, исходный файл 32.742.408 байт жмётся до 167.805. Конечно, так жмутся не все файлы, но это РЕАЛЬНЫЕ данные, а не какие-то там специально сделанные, чтоб мощь архиватора показать.

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

Другая часть данных собирается в базу MySQL RocksDB с промежуточной компрессией LZ4 и финальной ZSTD. Тут компрессия, конечно, поменьше, зато поменьше и RAM+CPU/время отклика
Невозможность создать файл по конкретному имени это баг, и его желательно отрапортовать. Коллизии могут быть всегда, и там предусмотрены механизмы их разрешения; но где-то что-то пошло не так.

Вообще же стремление народа из Linux к NIH-подходу иногда перевешивает здравый смысл — btree сейчас это достаточно банально и позволяет вкусностей больше, чем просто быстрый поиск по точному имени.
Ionice работает только если у дисков планировщик ввода-вывода CFQ или BFQ. Если deadline (стоит по дефолту, например, в RHEL и Ubuntu) или noop — то оно не дает никакого эффекта.

Спасибо, интересное наблюдение.

это не наблюдение, это в FM написано )))
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.