Вопрос: Сохранение миллиона изображений в файловой системе


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

Как вы рекомендуете эффективно сохранять эти изображения? (Файловая система NTFS в настоящее время)

Я рассматриваю схему именования ... для запуска всех изображений будет добавочное имя от 1 до Надеюсь, это поможет мне отсортировать их позже, если потребуется, и бросить их в разные папки.

что было бы лучшей схемой именования:

a / b / c / 0 ... z / z / z / 999

или

a / b / c / 000 ... z / z / z / 999

любая идея по этому поводу?


73
2017-12-17 16:52


Источник


Связаны ли они с конкретными пользователями или просто общие? Сгруппированы ли они каким-либо образом?
только общий. кучу образов, созданных некоторым техническим оборудованием. Я назову их инкрементальными от 1 до только, чтобы иметь представление о временном подтверждении. - s.mihai
как они будут использоваться / доступны? через приложение на заказ или что? - dove
Это ты? i46.tinypic.com/1z55k7q.jpg
:)) да ... 1 mil. порно картинки :)) - s.mihai


Ответы:


Я бы рекомендовал использовать обычную файловую систему вместо баз данных. Использование файловой системы проще, чем база данных, вы можете использовать обычные инструменты для доступа к файлам, файловые системы предназначены для такого использования и т. Д. NTFS должна работать отлично, как система хранения.

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

 File path = generatePathFromSequenceNumber(sequenceNumber);

Это легче обрабатывать, если вам нужно каким-то образом изменить структуру каталогов. Возможно, вам нужно переместить изображения в другое место, возможно, у вас закончилось свободное пространство, и вы начнете хранить некоторые изображения на диске A и некоторые на диске B и т. Д. Легче изменить одну функцию, чем изменить пути в базе данных ,

Я бы использовал такой алгоритм для генерации структуры каталогов:

  1. Сначала введите порядковый номер с начальными нулями, пока у вас не будет 12-значной строки. Это имя для вашего файла. Вы можете добавить суффикс:
    • 12345 -> 000000012345.jpg
  2. Затем разделите строку на 2 или 3 символьных блока, где каждый блок обозначает уровень каталога. У вас есть фиксированное количество уровней каталогов (например, 3):
    • 000000012345 -> 000/000/012
  3. Храните файл в сгенерированном каталоге:
    • Таким образом, полный путь и имя файла файла для файла с идентификатором последовательности 123 является 000/000/012/00000000012345.jpg
    • Для файла с идентификатором последовательности 12345678901234 путь был бы 123/456/789/12345678901234.jpg

Некоторые вещи, которые нужно учитывать в структурах каталогов и хранении файлов:

  • Выше алгоритм дает вам систему, в которой каждый каталог листьев имеет не более 1000 файлов (если у вас меньше всего 1 000 000 000 000 файлов)
  • Может быть ограничено количество файлов и подкаталогов, которые может содержать каталог, например файловая система ext3 на Linux имеет ограничение на 31998 подкаталогов на один каталог.
  • Обычные инструменты (WinZip, Windows Explorer, командная строка, оболочка bash и т. Д.) Могут работать не очень хорошо, если у вас есть большое количество файлов в каталоге (> 1000)
  • Сама структура каталогов займет некоторое место на диске, поэтому вам не нужно слишком много каталогов.
  • С вышеуказанной структурой вы всегда можете найти правильный путь к файлу изображения, просто посмотрев на имя файла, если вы случайно испортили свои структуры каталогов.
  • Если вам нужно получить доступ к файлам с нескольких компьютеров, подумайте об обмене файлами через сетевую файловую систему.
  • Вышеупомянутая структура каталогов не будет работать, если вы удалите большое количество файлов. Он оставляет «дыры» в структуре каталогов. Но поскольку вы не удаляете файлы, все должно быть в порядке.

70
2017-12-17 17:32



очень интересно! разбивая имя файла ... Я об этом не думал. Я предполагаю, что это элегантный способ сделать это: -? - s.mihai
Использование хэша (например, MD5) в качестве имени файла, а также распределения каталогов будет работать. Мало того, что целостность файлов будет побочным преимуществом схемы именования (легко проверяется), но у вас будет достаточно равномерное распределение по всей иерархии каталогов. Поэтому, если у вас есть файл с именем «f6a5b1236dbba1647257cc4646308326.jpg», вы сохраните его в «/ f / 6» (или так глубоко, как вам нужно). 2 уровня глубины дают 256 каталогов или чуть менее 4000 файлов в каталоге для начальных 1 м файлов. Также было бы очень легко автоматизировать перераспределение по более глубокой схеме.
+1 Я просто заметил, что этот ответ был похож на тот, который я только что опубликовал. - 3dinfluence
Я определенно соглашаюсь на использование filessystem и создание искусственного идентификатора, чтобы «нарезать» на имена папок. Но вы также должны попытаться получить случайное распределение идентификаторов, т. Е. Не использовать порядковый номер. Это позволит вам иметь более сбалансированное дерево папок. Кроме того, при случайном распределении вы можете более легко разделить дерево на несколько файловых систем. Я бы также использовал SAN с поддержкой ZFS с включенной дефрагментацией и разреженный том для каждой файловой системы. Вы все равно можете использовать NTFS, используя iSCSI для доступа к SAN. - Michael Dillon
Если вы переходите справа налево на шаге 2, файлы распределяются равномерно. Также вам не нужно беспокоиться о том, что вы не заполняете достаточное количество нулей, так как можете неограниченное количество файлов - ropo


Я собираюсь наложить 2 цента на отрицательный совет: не ходите с базой данных.

Я уже много лет работаю с хранилищами для хранения изображений: большие (1 мега-> 1 гигабайт) файлы, часто меняющиеся, несколько версий файла, доступ к которым достаточно часто. Проблемы с базой данных, с которыми вы сталкиваетесь с большими хранящимися файлами, крайне утомительны, проблемы с записью и транзакциями являются узловатыми, и вы сталкиваетесь с проблемами блокировки, которые могут вызвать большой поезд Обломки. У меня больше практики написания сценариев dbcc и восстановления таблиц из резервных копий, чем любой нормальный человек. Когда-либо иметь.

Большинство новых систем, с которыми я работал, подтолкнули хранилище файлов к файловой системе и использовали базы данных не более, чем индексацию. Файловые системы предназначены для такого рода злоупотреблений, их гораздо проще расширить, и вы редко теряете всю файловую систему, если одна запись повреждена.


28
2017-12-17 17:12



да. сделанный примечание! - s.mihai
Вы просмотрели тип данных FILESTREAM SQL 2008? Это кросс между хранилищем базы данных и файловой системы. - NotMe
+1 при прикреплении к файловому серверу, а не к базе данных, поскольку вы выполняете быстрые и нечастые операции ввода-вывода.
Что делать, если вы просто храните несколько сотен документов или фотографий на базе данных - любая недостатка в использовании базы данных для хранения? - Beep beep
+1 ... файловая система вроде бы является «базой данных» в любом случае (ntfs наверняка), поэтому почему это слишком сложно. - akira


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

Так скажите, что у вас есть хэш файла, что-то вроде этого 515d7eab9c29349e0cde90381ee8f810
Вы можете сохранить это в следующем месте, и вы можете использовать, как много раз вам нужно, чтобы количество файлов в каждой папке было низким.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Я видел этот подход много раз. Вам по-прежнему нужна база данных для сопоставления этих хэшей файлов с понятным для пользователя именем и любыми другими метаданными, которые вам нужно хранить. Но этот подход очень хорошо масштабируется b / c, вы можете начать распространять хэш-адресное пространство между несколькими компьютерами и пулами хранения и т. Д.


12
2017-12-17 20:17



Git использует аналогичный подход: git-scm.com/book/en/v2/Git-Internals-Git-Objects (чтобы поддержать этот ответ) - aexl


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

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

Например.,

/ Корень / [0-99] / [0-99] / имя_файла

Заметка, http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx имеет более подробную информацию о настройке NTFS. В частности, «Если вы используете большое количество файлов в папке NTFS (300 000 и более), отключите генерацию имени короткого файла для лучшей производительности, и особенно если первые шесть символов имен длинных файлов похожи».

Вы также должны посмотреть на отключенные функции файловой системы, которые вам не нужны (например, время последнего доступа). http://www.pctools.com/guides/registry/detail/50/


11
2017-12-17 17:01



+1 для отключения 8.3 генерации имени файла и последнего времени доступа; это было первое, что приходило в голову, когда я читал «огромное количество [файлов]» и «NTFS» (Windows). - rob
ссылка вниз ........................ - Pacerier


Независимо от того, что вы делаете, не храните их в одном каталоге.

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

Так:

скоросшиватель img\a\b\c\d\e\f\g\ будет содержать изображения, начинающиеся с «abcdefg» и т. д.

Вы можете представить свою собственную необходимую глубину.

Самое замечательное в этом решении заключается в том, что структура каталогов эффективно действует как хэш-таблица / словарь. Учитывая имя файла изображения, вы узнаете его каталог и указали каталог, вы узнаете подмножество изображений, которые идут туда.


7
2017-12-17 16:58



\ a \ b \ c \ d \ e \ f \ я делаю сейчас, я думал, что есть мудрый способ сделать это. - s.mihai
Это общепринятое решение о том, как их физически хранить. Очевидно, что создание URL-адреса изображения - это то, что можно легко сделать динамически на основе имени файла изображения. Кроме того, чтобы обслуживать их, вы могли бы даже представить поддомены img-a, img-b на сервере изображений, если хотите, ускорить время загрузки.
И +1 для «не хранить их все в одном каталоге». Я поддерживаю унаследованную систему, которая наложила более 47000 файлов на сервер в одной папке, и для проводника требуется всего лишь минуту, чтобы открыть папку. - Mark Ransom
Выполнение \ b \ c \ d \ e \ f \ g делает структуру каталога очень глубокой, и каждый каталог содержит только несколько файлов. Лучше использовать больше одной буквы на уровне каталога, например. ab \ cd \ ef \ или abc \ def \. Каталоги также занимают пространство с диска, поэтому вам не нужно слишком много из них. - Juha Syrjälä
Я должен был поддерживать приложение, в котором было 4 + миллион файлов в одном каталоге; он работал на удивление хорошо, но вы НИКОГДА не могли бы получить проводник, чтобы открыть папку, он будет постоянно сортировать новые дополнения. +1 для NTFS, способной справиться с этим, не умирая. - SqlACID


Я бы сохранил их в файловой системе, но это зависит от того, насколько быстро будет расти количество файлов. Эти файлы размещены в Интернете? Сколько пользователей будет обращаться к этому файлу? Это вопросы, на которые нужно ответить, прежде чем я смогу дать вам лучшую рекомендацию. Я также посмотрю на Haystack от Facebook, у них есть очень хорошее решение для хранения и обслуживания изображений.

Также, если вы выберете файловую систему, вам нужно будет разбить эти файлы на каталоги. Я рассматривал этот вопрос и предлагал решение, но оно не было идеальным ни в коем случае. Я разделяю хэш-таблицу и пользователей, которых вы можете прочитать больше на моем блог,


5
2017-12-17 16:59



изображения не предназначены для частого доступа. поэтому нет проблем с этим. их число будет расти довольно быстро. Я предполагаю, что будет 1 мил. отметьте в 1 месяц. - s.mihai
я заинтересован в представлении программиста, чтобы я не слишком завывал это слишком - s.mihai
Поэтому, если вам не нужен быстрый доступ, Haystack, вероятно, не для вас. Использование каталогов для разделов - самое простое решение на мой взгляд. - Lukasz


У нас есть система хранения фотографий с 4 миллионами изображений. Мы используем базу данных только для метаданных, и все изображения хранятся в файловой системе с использованием инвертированной системы именования, где имена папок генерируются из последней цифры файла, last-1 и т. Д. например.: 000001234.jpg хранится в структуре каталогов, как 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

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


5
2017-12-30 22:10





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


4
2017-12-17 17:18



: -? хорошая быстрая точка. просто теперь у меня нет алгоритма для генерации пути. - s.mihai