Хранение изображений большого размера

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

Ожидается, что количество входящих файлов составит около 500 000 в неделю (в среднем около 100 Кб каждый), максимум - около 100 000 файлов в день и 5 файлов в секунду. Ожидается, что общее количество файлов достигнет десятков миллионов до достижения равновесия, когда срок хранения файлов истекает по разным причинам при скорости ввода.

Поэтому мне нужна система, которая может хранить около 5 файлов в секунду в часы пик, считывая около 4 и удаляя 4 в любое время.

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

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

изменить

Спасибо за все комментарии и предложения. Еще немного дополнительной информации о проекте:

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

Доступ к изображениям осуществляется на 99% автономным приложением в порядке «первым пришел - первым обслужен», но также будет иметь место произвольный доступ со стороны пользовательского приложения. Изображения старше одного дня в основном служат для архивирования, хотя эта цель также очень важна.

Срок действия изображений определяется сложными правилами по разным причинам, но в какой-то момент все изображения должны быть удалены. Правила удаления следуют бизнес-логике, зависящей от метаданных и действий пользователя.

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

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

Итак, мои вопросы:

  • Какие технологии будут надежно работать?
  • Какие технологии будут иметь самые низкие затраты на внедрение?
  • Какие технологии проще всего обслуживать IT-отделу клиента?
  • Какие риски существуют для данной технологии в этом масштабе (данные 5–20 ТБ, 10–100 миллионов файлов)?

person Holstebroe    schedule 02.01.2011    source источник
comment
Имейте в виду, что количество файлов ограничено количеством файлов, мы столкнулись с проблемой Redhat с максимальным лимитом файлов на каталог, к сожалению.   -  person Jakub    schedule 03.01.2011
comment
Вот почему я хотел разбить файлы на папки в зависимости от их года, месяца, дня и часа. В конце концов, я не ожидаю больше 18000 файлов в час.   -  person Holstebroe    schedule 03.01.2011
comment
Также см. stackoverflow.com/questions/2104720 /   -  person Christian V    schedule 03.01.2011


Ответы (3)


Вот несколько случайных мыслей о реализации и возможных проблемах, основанных на следующих предположениях: средний размер изображения 100 КБ и стабильное состояние 50 МБ (5 ГБ) изображений. Это также предполагает, что пользователи не будут напрямую обращаться к хранилищу файлов, а будут делать это через программное обеспечение или веб-сайт:

  1. Носитель данных: размер изображений, которые вы предоставляете, составляет довольно мизерную скорость чтения и записи, я думаю, что у большинства обычных жестких дисков не будет проблем с такой пропускной способностью. Однако я бы поместил их в конфигурацию RAID1 для защиты данных. Резервное копирование не будет большой проблемой, поскольку это всего 5 ГБ данных.

  2. Хранилище файлов: чтобы предотвратить проблемы с максимальным количеством файлов в каталоге, я бы взял хэш (минимум MD5, это будет самый быстрый, но наиболее вероятный конфликт. И прежде чем люди начнут чирикать, чтобы сказать, что MD5 сломан, это для идентификации, Злоумышленник может заполнить изображения для второй атаки по прообразу и заменить все изображения на goatse, но мы сочтем это маловероятным) и преобразовать это в шестнадцатеричную строку. Затем, когда придет время поместить файл в файловую систему, возьмите шестнадцатеричную строку блоками по 2 символа и создайте структуру каталогов для этого файла на основе этого. Например. если хеш файла равен abcdef, то корневой каталог будет ab, тогда под ним будет каталог с именем cd, в котором вы будете хранить изображение с именем abcdef. Настоящее имя будет храниться в другом месте (обсуждается ниже).

    При таком подходе, если вы начинаете достигать ограничений файловой системы (или проблем с производительностью) из-за слишком большого количества файлов в каталоге, вы можете просто заставить часть хранилища файлов создать другой уровень каталогов. Вы также можете сохранить с метаданными количество уровней каталогов, в которых был создан файл, поэтому, если вы расширите его позже, старые файлы не будут искать в новых, более глубоких каталогах.

    Еще одно преимущество: если вы столкнетесь с проблемами скорости передачи или проблемами файловой системы в целом, вы можете легко разделить набор файлов на другие диски. Просто измените программное обеспечение, чтобы каталоги верхнего уровня оставались на разных дисках. Итак, если вы хотите разделить магазин пополам, 00-7F на одном диске, 80-FF на другом.

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

  3. Хранилище метаданных: хотя 50 миллионов строк кажутся большим количеством, большинство СУБД построены так, чтобы насмехаться над таким количеством записей, конечно, с достаточным объемом оперативной памяти. Следующее написано на основе SQL Server, но я уверен, что большинство из них применимо и к другим. Создайте таблицу с хешем файла в качестве первичного ключа, а также такими вещами, как размер, формат и уровень вложенности. Затем создайте другую таблицу с искусственным ключом (для этого подойдет столбец int Identity), а также исходное имя файла (varchar (255) или что-то еще) и хэш в качестве внешнего ключа обратно к первой таблице, и дату, когда он был добавлен, с индексом в столбце имени файла. Также добавьте любые другие столбцы, которые вам нужно выяснить, истек срок действия файла или нет. Это позволит вам сохранить исходное имя, если у вас есть люди, пытающиеся поместить один и тот же файл под разными именами (но в остальном они идентичны, поскольку они имеют одинаковый хэш).

  4. Техническое обслуживание: это должно быть запланированное задание. Позвольте Windows беспокоиться о том, когда ваша задача выполняется, меньше вам придется отлаживать и ошибаться (что, если вы проводите техническое обслуживание каждую ночь в 2:30 ночи, и вы находитесь в месте, где соблюдается летнее / летнее время. 2:30 утра не бывает во время весеннего переналадки). Затем эта служба выполнит запрос к базе данных, чтобы установить, у каких файлов истек срок действия (на основе данных, хранящихся для каждого имени файла, поэтому он знает, когда все ссылки, указывающие на сохраненный файл, истекли. Любой хешированный файл, на который не ссылается по крайней мере одна строка в таблице имен файлов больше не нужна). Затем служба удалит эти файлы.

Я думаю, что это все по основным частям.

РЕДАКТИРОВАТЬ: мой комментарий становился слишком длинным, перемещая его в редактирование:

Ой, моя ошибка, это то, что я получаю за математику, когда устаю. В этом случае, если вы хотите избежать дополнительной избыточности при добавлении уровней RAID (51 или 61, например, зеркальное отображение в чередующемся наборе), хеширование принесет вам преимущество, заключающееся в возможности вставить в сервер 5 дисков емкостью 1 ТБ, а затем иметь программное обеспечение для хранения файлов распределяет диски по хэшу, как указано в конце 2. Вы можете даже использовать RAID1 диски для дополнительной безопасности.

Резервное копирование было бы более сложным, хотя время создания / модификации файловой системы все равно будет сохраняться для этого (вы можете коснуться каждого файла, чтобы обновить его время модификации, когда добавляется новая ссылка на этот файл).

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

Хранилище метаданных не обязательно должно находиться на самом сервере. Вы уже храните данные, относящиеся к файлам, в базе данных. Вместо того, чтобы просто ссылаться на путь непосредственно из строки, в которой он используется, вместо этого укажите ключ имени файла (вторая таблица, которую я упомянул).

Я предполагаю, что пользователи используют какую-то сеть или приложение для взаимодействия с магазином, поэтому ум, чтобы выяснить, где будет находиться файл на сервере хранения, будет жить там и просто делиться корнями дисков (или делать какие-то причудливые вещи с соединением NTFS, чтобы поместить все диски в один подкаталог). Если вы ожидаете получить файл через веб-сайт, создайте страницу на сайте, которая принимает идентификатор имени файла, затем выполните поиск в БД, чтобы получить хэш, тогда он сломает хеш до любого настроенного уровень и запросить это через общий ресурс на сервер, а затем передать его обратно клиенту. Если вы ожидаете, что UNC получит доступ к файлу, пусть сервер просто построит UNC вместо этого.

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

person Matt Sieker    schedule 03.01.2011
comment
Спасибо за ваши Коментарии. 1. Что касается размера, 50 МБ * 100 КБ - это 5 ТБ, а не 5 ГБ. Эффективное резервное копирование / восстановление - это проблема. 2. Я не думаю, что хеширование имен файлов принесет какую-либо пользу по сравнению с моим предложением, почему папки основаны на дате / часе. Использование папок на основе даты / часа упростит сценарии резервного копирования / восстановления, например, если вы хотите восстановить файлы за последние 24 часа. - person Holstebroe; 03.01.2011
comment
3. На сервере хранения файлов не будет метаданных. Ссылки на файлы будут происходить из таблиц в другой базе данных, которая также определит, у каких файлов срок годности истек. Это должно быть простое автономное хранилище файлов большой емкости. - person Holstebroe; 03.01.2011
comment
@Holstebroe, я только что добавил еще несколько деталей и предложений - person Matt Sieker; 03.01.2011
comment
У вас есть хороший смысл в том, чтобы распространять файлы на основе их хэш-ключа, что могло бы сделать более масштабируемое решение, но я также считаю, что именование на основе временных меток имеет некоторые важные преимущества. Один из них - удаление файлов с истекшим сроком действия будет происходить очень быстро, и это может быть выполнено вручную администратором. Я просто попытался удалить папку с 20 000 файлов на своих старых настольных компьютерах, и это заняло всего 10 секунд. Другая вещь - это резервное копирование, которое можно разбить, скажем, на недели, что значительно ускоряет восстановление. - person Holstebroe; 04.01.2011
comment
Я должен добавить, что это система, в которой день простоя может легко стоить + 100000 долларов, поэтому быстрое резервное копирование / восстановление является важной проблемой. - person Holstebroe; 04.01.2011
comment
Если время безотказной работы настолько критично, независимо от решения, вам следует настроить общий ресурс DFS для хранилища файлов, распределенный между двумя компьютерами с избыточным хранилищем. Вы также можете расширить это до третьего члена общей папки DFS, расположенного в другом географическом месте для целей аварийного восстановления. Или запланированное задание с чем-то вроде rsync, если DFS слишком много для настройки - person Matt Sieker; 04.01.2011

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

SQLite чрезвычайно эффективен при хранении двоичных данных и, сохраняя файлы в агрегированной базе данных вместо отдельных файлов ОС, он экономит накладные расходы, когда изображения не вписываются в точные размеры блока (что важно для такого количества файлов). Кроме того, выгружаемые данные в SQLite могут обеспечить более высокую пропускную способность, чем при использовании простых файлов ОС.

SQLite имеет ограничения параллелизма при записи, но вполне в пределах, о которых вы говорите, и их можно еще больше смягчить за счет грамотного использования нескольких (сотен) баз данных SQLite.

Попробуйте, вы будете приятно удивлены.

person Samuel Neff    schedule 03.01.2011
comment
(сотни) баз данных SQLite - обслуживание кажется головной болью - person Mitch Wheat; 03.01.2011
comment
@Mitch Wheat по сравнению с миллионами файлов? - person Samuel Neff; 03.01.2011
comment
@ Самуэль Нефф: да, вот оно! - person Mitch Wheat; 03.01.2011
comment
Я пробовал SQLite несколько раз и согласен с тем, что он действительно довольно быстр для таких простых операций с хранилищем. - person Holstebroe; 03.01.2011
comment
Но при больших нагрузках я не пробовал. Хорошо ли он обрабатывает случайные удаления строк с течением времени? Он фрагментирован? Это РОК стабильно? Это для производственной среды, где клиент потеряет $$$$$$ из-за простоя. В чем преимущества NTFS помимо накладных расходов на размер блока? (что меньше проблем с сегодняшними ценами на хранение). - person Holstebroe; 03.01.2011
comment
Есть ли у вас какой-либо опыт работы с SQLite, если его попросят удалить дневные файлы (100 000 строк) из 50 000 000 строк. Будет ли остановка системы во время удаления? Не то чтобы это большая проблема, система не будет получать новые данные 24/7, поэтому будет довольно много моментов для обслуживания. - person Holstebroe; 03.01.2011
comment
@Hostebroe, удаление будет очень быстрым, но сразу не освободится место. В случае простоя вы можете запустить VACUUM, который освободит место. Разработчики SQLite создали свою собственную систему контроля версий, fossil, которая внутренне использует SQLite для хранения миллионов крошечных файлов. - person Samuel Neff; 03.01.2011
comment
@Samuel Neff, я легко убежден, что SQLite справится с этой задачей, поскольку ранее я был впечатлен производительностью. Однако я не уверен, что это действительно решает проблему в моем случае. Если решение для файловой системы NTFS достаточно быстрое, я считаю его более простым и удобным в обслуживании решением. - person Holstebroe; 03.01.2011
comment
@Hostebroe, все в порядке, я не утверждаю, что NTFS вам тоже не по плечу. Я просто выбрасываю SQLite как альтернативу, которую в некотором смысле лучше для вас рассмотреть. Ваше приложение, однако, вы можете выбрать любое решение, которое вам больше нравится. - person Samuel Neff; 04.01.2011

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

  • использовать sha1 файла в качестве имени файла (при необходимости сохранить указанное пользователем имя файла в БД)

    дело в том, что если вы заботитесь о данных, вам все равно придется хранить контрольную сумму.
    Если вы используете sha1 (sha256, md5, другой хеш), тогда будет легко проверить данные файла - прочитать файл, хеш cacl , если оно совпадает с именем, то данные действительны. Предполагая, что это какое-то веб-приложение, имя файла на основе хэша может использоваться как etag при передаче данных. (проверьте свой каталог .git для примера). Это предполагает, что вы в любом случае не можете использовать имя файла, указанное пользователем, так как пользователь может отправить что-то вроде «‹>? :(). Txt »

  • используйте структуру каталогов, которая имеет смысл с точки зрения вашего приложения

    основной тест здесь состоит в том, что должна быть возможность идентифицировать файл, просто посмотрев только на PATH \ FILE, без выполнения поиска метаданных в БД. Если вы храните / доступ к шаблонам строго по времени, тогда STORE \ DATE \ HH \ FILE будет иметь смысл, если у вас есть файлы, принадлежащие пользователям, тогда, возможно, STORE \ ‹первых N цифр UID> \ UID \ FILE сделает смысл.

  • использовать транзакции для операций с файлами / метаданными

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

  • использовать несколько корневых хранилищ

    то есть STORE01 \ STORE02 \ STORE \ - это может помочь в разработке (а затем и в масштабировании). Возможно, что несколько разработчиков будут использовать одну центральную базу данных и файловое хранилище, локальное для их машины. Использование STORE с самого начала поможет избежать ситуации, когда метаданные / файл расчесываются. будет действителен в одном экземпляре приложения и недействителен в другом.

  • никогда не храните абсолютные ПУТИ в БД

person Konstantin Antselovich    schedule 03.01.2011