Лучший способ хранения / извлечения миллионов файлов, когда их метаданные находятся в базе данных SQL

У меня есть процесс, который сначала будет генерировать 3-4 миллиона PDF-файлов и продолжать со скоростью 80K/day. Они будут довольно маленькими (50K) каждый, но я беспокоюсь о том, как управлять общей массой файлов, которые я генерирую для легкого поиска. Некоторые детали:

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

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

  1. одна папка в порядке? Файлы никогда не будут перечислены - они будут извлечены только с помощью системы.ИО.Файл с именем, которое я уже определил.
  2. Если я делаю папку, могу ли я наблюдать за новыми файлами с системой.ИО.DirectoryWatcher, даже с таким количеством файлов, или он начнет становиться вялым с таким количеством файлов?
  3. должны ли они храниться как капли в Вместо этого база данных SQL Server? Поскольку мне нужно будет получить их по ссылочному значению, возможно, это имеет больше смысла.

Спасибо за ваши мысли!

12 ответов


Я бы сгруппировал файлы в определенные подпапки и попытался организовать их (подпапки) каким-то бизнес-логическим способом. Возможно, все файлы, сделанные в течение данного дня? В течение шести часов каждого дня? Или каждый # файлов, я бы сказал, несколько 1000 max. (Вероятно, есть идеальный номер, надеюсь, кто-то опубликует его.)

файлы когда-нибудь стареют и удаляются? Если это так, сортировка и файл будут удаляемым куском. Если нет, Могу ли я быть вашим поставщиком оборудования?

там аргументы с обеих сторон хранение файлов в базе данных.

  • С одной стороны, вы получаете повышенную безопасность, потому что это более неудобно, чтобы вытащить файлы из БД; с другой стороны, вы получаете потенциально более низкую производительность, потому что это более неудобно, чтобы вытащить файлы из БД.
  • в БД вам не нужно беспокоиться о том, сколько файлов в папке, секторе, кластере NAS, что угодно-это проблема БД, и, вероятно, у них есть хорошая реализация для этого. На с другой стороны, будет сложнее управлять/просматривать данные, так как это будет bazillion blobs в одной таблице и, Ну, фу. (Вы можете разделить таблицу на основе вышеупомянутой бизнес-логики, что сделает удаление или архивирование бесконечно проще в выполнении. Это или, возможно, секционированные представления, поскольку секционирование таблиц имеет ограничение в 1000 разделов.)
  • SQL Server 2008 имеет тип данных FileStream; я мало знаю об этом, может быть, стоит посмотреть в.

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


чтобы ответить на ваши вопросы:

  1. Я бы не стал хранить их в одной папке. Как шансы в какой-то момент Вы захочется посмотреть на фактические файлы на диске, а не каким-то другим способом.
    Вместо этого почему бы не хранить их в отдельных каталогах, разделенных на пакеты по 1000? Возможно, используя ID в качестве ключа.
  2. что многие файлы, вероятно, затопят DirectorWatcher, поэтому некоторые будут потеряны. Я использовал это в прошлом, и спустя некоторое время (несколько сто), я обнаружил, что он начинает пропускать файлы. Возможно, используйте другой каталог для входящих файлов, а затем обрабатывайте это так часто. Это может вызвать процесс обновления оригинала.
  3. Я бы не хранил документы в базе данных, но определенно храню метаданные в базе данных.

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

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

sf394fgr90rtfofrpo98tx.pdf

затем разбейте это на двухсимвольные блоки, и вы получите следующее:

sf/39/4f/gr/90/rt/fo/fr/po/98/tx.pdf

Как вы видите, это дает вам глубокое дерево каталогов, которое вы можете легко ориентироваться.

С хорошей хэш-функцией это будет очень равномерно распределено, и вы никогда не получите более 1296 записей в каталоге. Если вы когда-нибудь получите столкновение (что должно быть крайне редко), просто добавьте номер в конец: tx.формат PDF, tx_1.формат PDF, tx_2.документ pdf. Опять же, столкновения на таких больших хэшах должны быть чрезвычайно редкими, так что вид сгущения, который вы получаете из-за этого, не является проблемой.

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


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

просто имейте в виду, что если вы используете идентификаторы заказов, вы можете испытать http://en.wikipedia.org/wiki/Benford%27s_law


определите некоторый логический порядок подкаталогов и сохраните их в блоках не более 512 или около того файлов в папке.

Не храните файлы в базе данных. Базы данных, файловые серверы для файлов. Храните их на файловом сервере, но храните путь и информацию о получении в базе данных.


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

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

Если файловая система индексирует каталоги (например, btree или просто сортирует его внутри, что фактически одно и то же в этом контексте), то размеры каталогов менее важны, хотя некоторые инструменты могут жаловаться (загрузка окна Проводника Windows с файлами 4M, кто знает, что произойдет).

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


Почему бы не рассмотреть возможность хранения всех этих файлов после преобразования в PDF в DB (blob) Отсюда Преимущества:

  1. Я верю, что вам не придется иметь дело с прямым вводом/выводом ОС и оставлять все до БД.
  2. не нужно хэш-имен
  3. простота резервного копирования и обслуживания

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

DELETE FROM BLOBTABLE WHERE NAME LIKE '<whatever>'

или когда у вас есть срок действия или вы хотите обновить файл, вы удаляете его:

DELETE FROM BLOBTABLE WHERE CREATIONDATE < ...
etc...

вопрос:

Почему эти документы должны быть сгенерированы и сохранены в виде PDF-файлов?

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


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

2) храните их все в каталогах и либо индексируйте их с помощью службы индексирования windows (ежится) или создайте свой собственный индекс в SQL Server, которая будет содержать имя файла и полный путь. Я бы предложил хранить их в отдельных каталогах, с несколькими десятками тысяч файлов каждый. Возможно, вы могли бы использовать круглый год в качестве имени папки?

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

надеюсь, что это помогает!


моя файловая база данных содержит более 4 миллионов папок, со многими файлами в каждой папке.

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

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

поэтому, чтобы получить файл, я ищу базу данных mysql по некоторым метаданным и получаю индекс. Затем Я использую этот индекс, чтобы прочитать файл напрямую. Для меня пока все хорошо. Но обратите внимание, что вы будете превращать все в случайный доступ и, следовательно, случайное чтение/запись. Это плохая производительность для HDD, но, к счастью, SSD поможет много.

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


Я думаю, как и многие другие сказали, Вы должны делать подпапки, но таким образом, что вы можете найти данные через код. Например, если datetime работает, используйте это. Из чтения того, что вы сказали, кажется, что есть какая-то иерархическая структура отчетов (ежедневный, еженедельный, ежедневный отчет X, почасовой отчет Y и т. д.), Я бы посмотрел на структуру того, когда и почему отчеты генерируются и строят мои каталоги таким образом.