У меня есть проект, который будет генерировать огромное количество изображений. Около 1 000 000 для начала. Они не являются большими изображениями, поэтому при запуске я буду хранить их все на одной машине.
Как вы рекомендуете хранить эти изображения эффективно? (Файловая система NTFS в настоящее время)
Я рассматриваю схему именования ... для начала все изображения будут иметь инкрементное имя от 1 до. Я надеюсь, что это поможет мне отсортировать их позже, если потребуется, и выбросить их в разные папки.
что будет лучше схема именования:
a / b / c / 0 ... z / z / z / 999
или же
A / B / C / 000 ... Z / Z / Z / 999
есть идеи по этому поводу?
Ответы:
Я бы рекомендовал использовать обычную файловую систему вместо баз данных. Использовать файловую систему проще, чем базу данных, вы можете использовать обычные инструменты для доступа к файлам, файловые системы предназначены для такого рода использования и т. Д. NTFS должна прекрасно работать как система хранения.
Не храните фактический путь к базе данных. Лучше сохранить порядковый номер изображения в базе данных и иметь функцию, которая может генерировать путь из порядкового номера. например:
Проще справиться, если вам нужно как-то изменить структуру каталогов. Может быть, вам нужно переместить изображения в другое место, может быть, вам не хватает места и вы начинаете хранить некоторые изображения на диске A, а некоторые на диске B и т. Д. Изменить одну функцию проще, чем изменить пути в базе данных. ,
Я бы использовал этот вид алгоритма для генерации структуры каталогов:
12345
->000000012345.jpg
000000012345
->000/000/012
123
является000/000/012/00000000012345.jpg
12345678901234
путь будет123/456/789/12345678901234.jpg
Некоторые вещи, которые следует учитывать относительно структуры каталогов и хранения файлов:
источник
Я собираюсь поставить свои 2 цента на один отрицательный совет: не ходите с базой данных.
Я работаю с базами данных для хранения изображений в течение многих лет: большие (1 мегабайта) файлы, часто изменяемые, несколько версий файла, доступ к которым осуществляется достаточно часто. Проблемы с базой данных, с которыми вы сталкиваетесь при хранении больших файлов, чрезвычайно утомительны, проблемы с записью и транзакциями запутаны, и вы сталкиваетесь с проблемами блокировки, которые могут привести к серьезным авариям поездов. У меня есть еще практика в написании сценариев DBCC и восстановление таблиц из резервных копий , чем любой нормальный человек должен когда - либо иметь.
Большинство новых систем, с которыми я работал, перенесли хранилище файлов в файловую систему и полагались на базы данных только для индексации. Файловые системы спроектированы таким образом, чтобы справляться с подобными злоупотреблениями, их гораздо проще расширять, и вы редко теряете всю файловую систему, если одна запись повреждена.
источник
Я думаю, что большинство сайтов, которые имеют дело с этим, используют какой-то хэш, чтобы обеспечить равномерное распределение файлов в папках.
Допустим, у вас есть хеш файла, который выглядит примерно так:
515d7eab9c29349e0cde90381ee8f810
вы можете хранить его в следующем месте и использовать сколько угодно глубоких уровней, чтобы количество файлов в каждой папке было низким.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg
Я видел этот подход, принятый много раз. Вам по-прежнему нужна база данных для сопоставления этих файловых хэшей с понятным для человека именем и другими метаданными, которые вам нужно сохранить. Но этот подход довольно хорошо масштабируется, поскольку вы можете начать распределять адресное пространство хеш-функции между несколькими компьютерами и / или пулами хранения и т. Д.
источник
В идеале вам следует запустить некоторые тесты на время произвольного доступа для различных структур, поскольку ваши конкретные настройки жесткого диска, кэширование, доступная память и т. Д. Могут изменить эти результаты.
Предполагая, что у вас есть контроль над именами файлов, я бы разделил их на уровне 1000 с на каталог. Чем больше уровней каталогов вы добавляете, тем больше инодов вы записываете, так что здесь есть push-pull.
Например,
/ Корень / [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/
источник
Что бы вы ни делали, не храните их все в одном каталоге.
В зависимости от распределения имен этих изображений вы можете создать структуру каталогов, в которой у вас будут однобуквенные папки верхнего уровня, где у вас будет другой набор подпапок для 2-й буквы изображений и т. Д.
Так:
Папка
img\a\b\c\d\e\f\g\
будет содержать изображения, начинающиеся с abcdefg и т. Д.Вы можете ввести свою собственную необходимую глубину.
Отличительной особенностью этого решения является то, что структура каталогов эффективно действует как хэш-таблица / словарь. По имени файла изображения вы будете знать его каталог, а по каталогу вы узнаете подмножество изображений, которые туда попадают.
источник
Я бы сохранил их в файловой системе, но это зависит от того, насколько быстро будет расти количество файлов. Эти файлы размещены в Интернете? Сколько пользователей будет иметь доступ к этим файлам? На эти вопросы нужно ответить, прежде чем я смогу дать вам лучшую рекомендацию. Я бы также посмотрел на Haystack из Facebook, у них есть очень хорошее решение для хранения и обработки изображений.
Также, если вы выберете файловую систему, вам нужно будет разделить эти файлы по каталогам. Я смотрел на эту проблему и предложил решение, но оно ни в коем случае не идеальное. Я делю по хеш-таблице и пользователям, вы можете прочитать больше на моем блоге .
источник
У нас есть система фотомагазинов с 4 миллионами изображений. Мы используем базу данных только для метаданных, и все изображения хранятся в файловой системе с использованием системы с обратными именами, где имена папок генерируются из последней цифры файла, last-1 и т. Д. Например: 000001234.jpg хранится в структуре каталогов, например 4 \ 3 \ 2 \ 1 \ 000001234.jpg.
Эта схема очень хорошо работает с индексом идентичности в базе данных, потому что она равномерно заполняет всю структуру каталогов.
источник
Быстрый момент: вам не нужно хранить путь к файлу в вашей БД. Вы можете просто сохранить числовое значение, если ваши файлы названы так, как вы описываете. Затем, используя одну из четко определенных схем хранения, которые уже обсуждались, вы можете получить индекс в виде числа и очень быстро найти файл, пройдя через структуру каталогов.
источник
Новый MS SQL 2008 имеет новую функцию для обработки таких случаев, она называется FILESTREAM. Посмотри:
Обзор Microsoft TechNet FILESTREAM
источник
Ваши изображения должны быть названы уникально? Может ли процесс, который генерирует эти изображения, создавать одно и то же имя файла более одного раза? Трудно сказать, не зная, какое устройство создает имя файла, но сказать, что устройство «перезагружено», и после перезапуска оно начинает называть изображения так же, как в прошлый раз, когда оно «сбрасывалось» - если это такая проблема.
Кроме того, вы говорите, что вы получите 1 миллион изображений за месяц. Как насчет этого? Как быстро эти изображения будут продолжать заполнять файловую систему? Будут ли они завершаться в какой-то момент и выровняться примерно на 1 млн. ОБЩИХ изображений или оно будет расти и расти месяц за месяцем?
Я спрашиваю, потому что вы можете начать проектирование вашей файловой системы по месяцам, а затем по имиджу. Я мог бы предложить вам сохранить изображения в такой структуре каталогов:
Месяц, год, даже день хорош для изображений типа безопасности. Не уверен, что это то, что вы делаете, но я сделал это с домашней камерой безопасности, которая делала снимки каждые 10 секунд ... Таким образом, ваше приложение может переходить к определенному времени или даже диапазону, в котором вы можете подумать, что изображение было сгенерировано. , Или вместо года, месяца - есть ли какое-то другое «значение», которое может быть получено из самого файла изображения? Некоторые другие дескрипторы, кроме примера даты, который я дал?
Я бы не стал хранить двоичные данные в БД. Никогда не было хорошей производительности / удачи с такими вещами. Не могу себе представить, что это хорошо работает с 1 миллионом изображений. Я хотел бы сохранить имя файла, и это все. Если они все будут JPG, тогда даже не храните расширение. Я хотел бы создать контрольную таблицу, в которой хранится указатель на сервер файла, диск, путь и т. Д. Таким образом, вы можете переместить эти изображения в другое поле и по-прежнему находить их. Вам нужно пометить тегами ваши изображения? Если это так, то вы захотите построить соответствующие таблицы, которые позволяют такого рода маркировки.
Возможно, вы / другие обсуждали эти идеи, когда я отвечал. Надеюсь, это поможет.
источник
Я участвую в проекте, который хранит 8,4 миллиона изображений в течение года для документирования состояния различных устройств. К более поздним изображениям обращаются чаще, а к более старым изображениям редко обращаются, если не было обнаружено условие, побуждающее кого-то копаться в архивах.
Мое решение, основанное на этом использовании, заключалось в постепенном сжатии изображений в сжатые файлы. Изображения представляют собой файлы JPG, каждый размером около 20 КБ и не сжимают сильно, поэтому схема сжатия ZIP отсутствует. Это делается просто для объединения их в одну запись файловой системы, что значительно помогает NTFS с точки зрения скорости, когда речь идет о перемещении их с диска на диск или просмотре списка файлов.
Изображения старше суток объединяются в «ежедневный» почтовый индекс; молнии старше месяца объединяются в соответствующие «месячные» молнии; и, наконец, ничего больше года больше не нужно и, следовательно, удаляется.
Эта система работает хорошо, потому что пользователи могут просматривать файлы (либо через операционную систему, либо через ряд клиентских приложений), а все имена называются на основе имен устройств и временных меток. Обычно пользователь знает эти две части информации и может быстро найти любое из миллионов изображений.
Я понимаю, что это, вероятно, не связано с вашими конкретными деталями, но я думал, что поделюсь.
источник
Возможно, схема именования, основанная на дате создания - либо включающая всю информацию в имени файла, либо (лучше для просмотра позже), разделив ее по каталогам. Я могу думать о следующем, в зависимости от того, как часто вы генерируете изображения:
Year/Month/Day/Hour_Minute_Second.png
Year/Month/Day_Hour_Minute_Second.png
и т.д. Вы понимаете мою точку зрения ... =)
источник
Year/Month/Day/Hour/Minute
- решить, сколько уровней папок вам нужно, в зависимости от того, как часто изображения генерируются, когда скорость самая высокая - и тогда просто не создавать папки, которые были бы оставлены пустыми.Я был бы склонен создать структуру папок на основе даты, например, \ year \ month \ day, и использовать временные метки для имен файлов. При необходимости временные метки могут иметь дополнительный компонент счетчика, если изображения должны создаваться так быстро, что их может быть больше одного в течение миллисекунды. Благодаря использованию наиболее значимой или наименее значимой последовательности для сортировки имен поиск и обслуживание становятся проще простого. например, hhmmssmm [seq] .jpg
источник
Вы рассматриваете возможность аварийного восстановления?
Некоторые из предложенных здесь решений приводят к искажению имени файла (например, если физический файл был перемещен, вы потеряете информацию о том, какой это файл на самом деле). Я рекомендую сохранить уникальное физическое имя файла, чтобы, если ваш основной список расположений файлов был поврежден, вы могли восстановить его с помощью небольшой оболочки, например, powershell, script;)
Из того, что я прочитал здесь, звучит так, как будто все эти файлы будут храниться в одной файловой системе. Рассмотрите возможность их хранения в нескольких файловых системах на нескольких машинах. Если у вас есть ресурсы, определите систему хранения каждого файла на двух разных компьютерах на случай, если вы потеряете источник питания, и замена займет 2 дня.
Подумайте, какие процедуры вам необходимо создать для переноса файлов между компьютерами или файловыми системами. Возможность сделать это с вашей системой в режиме реального времени и онлайн может сэкономить вам значительную головную боль в будущем.
Вы можете рассмотреть возможность использования GUID в качестве физического имени файла вместо инкрементного числа, если ваш счетчик инкрементных чисел (столбец идентификатора базы данных?) Испортился.
При необходимости рассмотрите возможность использования CDN, например Amazon S3.
источник
Хотя я не обслуживал изображения в таком масштабе, ранее я написал небольшое приложение для галереи, обслуживающее ~ 25 тыс. Изображений на машине с частотой 400 МГц. 512 МБ ОЗУ или около того. Некоторые переживания;
Избегайте реляционных баз данных любой ценой; В то время как базы данных, без сомнения, умны в обработке данных, они не предназначены для такого использования (у нас есть специализированные, иерархические базы данных значения ключа для так называемых файловых систем ). Хотя у меня нет ничего, кроме догадки, я бы поспорил, что кеш БД уходит в окно, если вы кидаете в него действительно большие капли. В то время как моё доступное оборудование было в самом начале, полное отсутствие обращения к БД при поиске изображения дало скорость на порядок выше.
Исследуйте, как ведет себя файловая система; в ext3 (или это был ext2 в то время - не помню) предел способности эффективно искать подкаталоги и файлы был около отметки 256; Таким образом, имея только столько файлов и папок в любой папке. Опять заметное ускорение. Хотя я не знаю о NTFS, такие вещи, как XFS (которая, насколько я помню, использует B-деревья), чрезвычайно быстры, просто потому, что они могут выполнять поиск очень быстро.
Распределить данные равномерно; когда я экспериментировал с вышеизложенным, я пытался распределить данные равномерно по всем каталогам (я сделал MD5 URL-адреса и использовал его для каталогов;
/1a/2b/1a2b...f.jpg
). Таким образом, требуется больше времени, чтобы достичь любого ограничения производительности (и кэш файловой системы в любом случае становится пустым при таких больших наборах данных). (наоборот, вы можете захотеть увидеть, где находятся ограничения в начале; затем вы хотите выбросить все в первый доступный каталог.источник
Может быть, опоздал на игру по этому вопросу. Но одним из решений (если оно соответствует вашему варианту использования) может быть хеширование имени файла. Это способ создать легко воспроизводимый путь к файлу, используя имя файла, а также создать хорошо распределенную структуру каталогов. Например, вы можете использовать байты хэш-кода имени файла в качестве пути:
Это приведет к тому, что путь будет:
Затем вы можете найти
cat.gif
в структуре каталогов, воспроизведя алгоритм.Использование HEX в качестве имен каталогов будет так же просто, как преобразование
int
значений:В результате чего:
Я написал статью об этом несколько лет назад и недавно переместил ее в Medium. В нем есть еще несколько деталей и пример кода: Хеширование имени файла: Создание хешированной структуры каталогов . Надеюсь это поможет!
источник
Если вы находитесь в Windows, как насчет exfat файловой системы
http://msdn.microsoft.com/en-us/library/aa914353.aspx
это было разработано с хранением медиа-файлов и доступно сейчас.
источник
Если они ВСЕ не требуются немедленно, и вы можете генерировать их на лету, и это небольшие изображения, почему бы не реализовать кэш-память LRU или дисковый кэш над генератором изображений?
Это может спасти вас от хранения и сохранить горячие изображения, которые будут поданы из памяти?
источник
Я просто запустил тест на zfs, потому что я люблю zfs, и у меня был раздел на 500 гигабайт, на котором у меня было сжатие. Я написал скрипт, который генерировал файлы размером 50-100 тыс. И помещал их во вложенные каталоги 1/2/3/4/5/6/7/8 (5-8 уровней в глубину) и позволил ему работать, я думаю, 1 неделю. (это был не очень хороший сценарий.) Он заполнил диск и в итоге получил около 25 миллионов файлов или около того. Доступ к любому файлу с известным путем был мгновенным. Перечисление любого каталога с известным путем было мгновенным.
Однако подсчет списка файлов (через find) занял 68 часов.
Я также провел тест, поместив множество файлов в один каталог. Я получил до 3,7 миллионов файлов в одном каталоге, прежде чем я остановился. Перечисление каталога для подсчета заняло около 5 минут. Удаление всех файлов в этом каталоге заняло 20 часов. Но поиск и доступ к любому файлу был мгновенным.
источник
Я вижу другие упоминания о базе данных, но не вижу упоминаний об этом в вашем посте. В любом случае, мое мнение по этому конкретному вопросу таково: либо придерживайтесь базы данных, либо файловой системы. Если вам нужно смешать два, будьте осторожны с этим. Все становится сложнее. Но вам, возможно, придется. Хранение миллиона фотографий в базе данных не самая лучшая идея.
Вас может заинтересовать следующая спецификация, большинство цифровых камер следуют ей для управления хранением файлов: https://en.wikipedia.org/wiki/Camera_Image_File_Format
По сути, создается папка, например,
000OLYMPUS
и фотографии добавляются в эту папку (напримерDSC0000.RAW
). Когда счетчик имени файла достигает,DSC9999.RAW
создается новая папка (001OLYMPUS
) и изображение добавляется снова, сбрасывая счетчик, возможно, с другим префиксом (например:)P_0000.RAW
.В качестве альтернативы вы также можете создавать папки на основе частей имени файла (уже упоминалось несколько раз). Например, если ваша фотография названа
IMG_A83743.JPG
, сохраните ее вIMG_\A8\3\IMG_A83743.JPG
. Его сложнее реализовать, но он облегчит поиск ваших файлов.В зависимости от файловой системы (это потребует некоторых исследований), вы можете просто сбросить все изображения в одну папку, но, по моему опыту, это обычно вызывает проблемы с производительностью.
источник
Возможно, вы захотите взглянуть на ZFS (файловая система, менеджер томов от Sun). С уважением,
источник
Чистый способ создать путь из большого числа - легко преобразовать его в гекс, а затем разделить!
например ,
1099496034834
>0xFFFF1212
>FF/FF/12/12
Хранить и загружать:
Полные исходные коды: https://github.com/acrobit/AcroFS
источник
К сожалению, файловые системы очень плохи (производительность с большим количеством файлов в каждом каталоге или глубоких деревьях каталогов, проверка времени при перезапуске, надежность) при управлении большим количеством маленьких файлов, поэтому приведенное выше решение с использованием ZIP-файлов является лучшим, если вы хотите использовать файловую систему.
Использование менеджера баз данных, безусловно, лучший вариант; простой, например, BDB или GDBM; даже родственная СУБД, такая как MySQL, будет лучше. Только ленивые люди, которые не понимают файловые системы и базы данных (например, те, кто отклоняет транзакции), склонны использовать файловые системы в качестве баз данных (или, реже, наоборот).
источник
Как насчет базы данных с таблицей, содержащей идентификатор и большой двоичный объект для хранения изображения? Затем вы можете добавлять новые таблицы, когда хотите связать больше элементов данных с фотографией.
Если вы ожидаете масштабирования, почему бы не масштабировать сейчас? Вы сэкономите время как сейчас, так и позже IMO. Реализуйте слой базы данных один раз, с чего довольно легко начать. Или реализуйте что-то с помощью папок и имен файлов и бла-бла-бла, а затем переключитесь на что-то другое, когда вы начнете взрывать MAX_PATH.
источник