Лучший способ хранить много файлов в диске

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

  • Это - приложение.NET.
  • Я должен хранить до 200 000 объектов (между 3KB-500KB)
  • Я должен сохранить приблизительно 10 из них в секунду от нескольких-потоков
  • Я использую binaryserialization прежде, чем сохранить его
  • Я должен получить доступ к ним позже целым числом, уникальным идентификатором

Что лучший способ состоит в том, чтобы сделать это?

  • Я не могу сохранить их на памяти, поскольку я получу outofmemory исключения
  • Когда я храню их в диске как отдельные файлы, каковы возможные проблемы производительности? Это уменьшило бы общую производительность очень?
  • Я реализую своего рода кэширование, например, объединю 100 объектов и запишу это однажды как один файл. Затем проанализируйте их позже. Или что-то подобное?
  • Буду использовать базу данных? (время доступа не важно, не будет поиска, и я получу доступ только несколько раз известным уникальным идентификатором). В теории мне не нужна база данных, я не хочу усложнять это.

ОБНОВЛЕНИЕ:

  • Я предполагаю, что база данных была бы медленнее, чем файловая система, доказала бы меня неправильно, если бы Вы получили что-то об этом. Так вот почему я также склоняюсь к к файловой системе. Но то, что я действительно волнуюсь, о записи 200KB*10 в секунду к жесткому диску (это может быть любым жестким диском, я не управляю аппаратными средствами, это - настольный инструмент, который будет развернут в различных системах).
  • Если я буду использовать файловую систему, то я буду хранить файлы в отдельных папках для предотвращения связанных с файловой системой проблем (таким образом, можно будет проигнорировать то ограничение),
8
задан Rachel 23 September 2010 в 14:07
поделиться

6 ответов

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

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

Хорошим решением является ограничение директории небольшим количеством узлов (скажем, n = 1000) и создание дерева файлов под директорией.

Таким образом, вместо того, чтобы хранить файлы как:

/dir/file1 /dir/file2 /dir/file3 ... /dir/fileN

Хранить их как:

/dir/r1/s2/file1 /dir/r1/s2/file2 ... /dir/rM/sN/fileP

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

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

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

Или же, если это не поможет, вы можете использовать какую-нибудь встроенную базу данных, например, SQLlite или Firebird.

HTH.

4
ответ дан 5 December 2019 в 18:59
поделиться

Мне бы хотелось использовать базу данных, на C++ либо sqlite, либо coucheDB.
Оба варианта будут работать в .Net, но я не знаю, есть ли более подходящая альтернатива для .Net.

Даже на файловых системах, которые могут обрабатывать 200,000 файлов в каталоге, потребуется навсегда открыть каталог

Edit - БД, вероятно, будет быстрее!
Файловая система не предназначена для огромного количества маленьких объектов, это БД.
В нем будут реализованы всевозможные умные кэширование/транзакции, о которых вы никогда не задумывались.

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

2
ответ дан 5 December 2019 в 18:59
поделиться

вы можете проверить mongoDb, он поддерживает хранение файлов.

1
ответ дан 5 December 2019 в 18:59
поделиться

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

Если вам нужно много писать и редко читать (например, файлы журнала), вам следует создать файл .zip или аналогичный (выберите уровень сжатия, который не слишком снижает производительность; в рейтинге 1–9 , 5 или около того обычно у меня работает). Это дает вам несколько преимуществ: вы не так сильно ударяете по файловой системе, ваше пространство для хранения уменьшается, и вы можете, естественно, группировать файлы в блоки по 100 или 1000 или что-то еще.

Если вам нужно много писать и много читать, вы можете определить свой собственный формат плоского файла (если у вас нет доступа к утилитам для чтения и записи файлов .tar и т. П., Или мошенничества и поместить двоичные данные в 8-битный TIFF в оттенках серого). Определите записи для каждого заголовка - возможно, 1024 байта каждый, который содержит смещение в файл, имя файла и все остальное, что вам нужно сохранить, - а затем запишите данные кусками.Когда вам нужно прочитать кусок, вы сначала читаете заголовок (возможно, 100k), а затем переходите к нужному смещению и считываете нужную сумму. Преимущество заголовков фиксированного размера заключается в том, что вы можете записывать в них пустые данные в начале, а затем просто продолжать добавлять новые данные в конец файла, а затем вернуться и перезаписать соответствующую запись.

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

0
ответ дан 5 December 2019 в 18:59
поделиться

Вы можете рассмотреть возможность использования Microsoft Caching Application Block. Вы можете настроить его для использования IsolatedStorage в качестве резервного хранилища, чтобы элементы в кеше были сериализованы на диск. Производительность может быть проблемой - я думаю, что из коробки он блокируется при записи, поэтому вам может потребоваться настроить его, чтобы вместо этого выполнялась асинхронная запись.

0
ответ дан 5 December 2019 в 18:59
поделиться

Единственный способ узнать наверняка - это узнать больше о вашем сценарии использования.

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

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

Вот что я бы сделал:

  1. Создайте класс, который занимается хранением и извлечением (чтобы впоследствии вы могли изменить этот класс, а не каждую точку в вашем приложении, которая его использует)
  2. Храните файлы на диске как есть, не объединяйте их
  3. Распространяйте их по подкаталогам, сохраняя 1000 или меньше файлов в каждом каталоге (доступ к каталогу увеличивает накладные расходы, если у вас много файлов в одном каталоге)
0
ответ дан 5 December 2019 в 18:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: