Эффективный способ хранения множества эскизов - PullRequest
9 голосов
/ 08 июля 2020

Итак, в настоящее время я храню все эскизы в одном каталоге с именем файла как md5 ha sh полного пути к полноразмерному изображению. Но я читал здесь, что это вызывает проблемы, когда каталог достигает тысяч файлов. Они будут обнаруживаться медленнее и медленнее файловой системой linux.

Какие у меня есть альтернативы, учитывая, что я могу найти эскиз только по пути исходного изображения? Даты были бы лучшими вариантами, например year/month/day/md5_hash.jpg, но это потребовало бы, чтобы я где-то сохранил и прочитал дату, поэтому было бы добавлено несколько дополнительных шагов.

Я думал разделить md5, например первые два символа = имя подпапки, остальные = имя файла. Это дало бы мне примерно 15 * 15 вложенных папок, но я бы хотел услышать лучшие варианты, спасибо!

Мне пришла еще одна идея: создать отдельный сервер для организации миниатюр. Сервер будет отслеживать количество миниатюр и создавать дополнительные папки при достижении определенного предела и повторно использовать старые папки, когда значки удаляются. Обратной стороной является то, что мне нужен отдельный db, который сопоставляет хэши с путями миниатюр: (

Ответы [ 5 ]

5 голосов
/ 12 июля 2020

Мы используем FreeBSD (файловая система UFS), а не Linux, поэтому некоторые детали могут отличаться.

Фон

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

Сервер 1 (названный: Tom) имеет основной пользовательский веб-сайт с довольно стандартной Apache настройкой и MySQL данными основание. Ничего особенного.

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

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

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

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

Исторически мы использовали несколько дисков SCSI на нескольких серверах. На данный момент у нас есть один сервер с дисками 300 МБ / с. Некоторое время бизнес находился в упадке (благодаря Facebook), но мы по-прежнему выполняем более 2 миллионов файловых запросов в день. На нашем пике это было больше похоже на 10 миллионов в день.

Наша структура (возможный ответ)

Все на Джерри настроено для доставки небольших файлов и ничего больше.

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

Каждому файлу дается четырехзначный идентификатор. Идентификатор - это буквенно-цифровые символы c (0-9, az, AZ). Это дает вам 61 * 61 * 61 * 61 комбинацию (или 13 845 841 идентификатор).

У нас также есть несколько доменов, поэтому каждый домен имеет максимум 13 845 841 идентификатор. Мы очень близко подошли к популярным «доменам» к этому пределу до того, как появился Facebook, и у нас были готовые планы на go, которые позволили бы использовать 5-символьные идентификаторы, но в конце концов нам это не понадобилось.

Файл поиск в системе выполняется очень быстро, если вы знаете полный путь к файлу. Это только медленно, если вам нужно сканировать файлы совпадений. Мы в полной мере воспользовались этим.

Каждый 4-значный идентификатор представляет собой серию каталогов. например, aBc9 равно /path/to/a/B/c/9.

Это очень большое количество уникальных идентификаторов всего в 4 каталогах. Каждый каталог имеет максимум 61 подкаталог. Создание быстрого поиска без переполнения индекса файловой системы.

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

Если пользователь обновляет или проверяет метаданные, идентификатор известен, поэтому возвращается запрос метаданных.

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

Если ID недействителен, возвращается неверный результат.

Ничего сложного, все для скорости.

Наши проблемы

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

Мы отключили и / или отредактировали ряд проверок системы FreeBSD. Cronjobs обслуживания не предназначены для систем с таким большим количеством файлов.

Настройка Apache была немного пробной и ошибочной, чтобы получить ее правильно. Когда вы его получите, облегчение будет огромным. Очень помогает mod_status Apache.

Самое первое, что нужно сделать, это отключить все файлы журналов. Затем отключите все и повторно добавьте только то, что вам нужно.

Код для доставки (и сохранения) метаданных и необработанных данных также очень оптимизирован. Забудьте о библиотеках кода. Каждая строка кода проверялась и перепроверялась годами на скорость.

Заключение

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

Система идентификации на основе каталогов (будь то 4 случайных символа или части MD5) может быть быстрой, если вам не нужно сканировать файлы.

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

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

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

Удачи!

2 голосов
/ 13 июля 2020

Самый лучший, эффективный, минимальный и простой метод - SeaweedFS

С 2017 года я использую SeaweedFS для хранения около 4 миллионов jpeg каждые 24 часа. В настоящее время в БД хранится более 2 миллиардов записей. У меня никогда не было проблем с этим, и он экономит много места на диске по сравнению с хранением в виде файлов файловой системы.

Ниже автор:

SeaweedFS - это простая и хорошо масштабируемая распределенная файловая система. Есть две цели:

  1. для хранения миллиардов файлов!
  2. для быстрого обслуживания файлов!

Подробности:

Мой проект содержит по 2 изображения для каждого события, одно - эскиз, а другое - полнокадровое. На первом этапе проекта я хранил изображения как файлы со структурой каталогов year/month/day/[thumb|full].jpg, но через несколько дней мне пришлось просматривать файлы, и это был кошмар, и реакция диска была медленной. а в случае удаления большого количества файлов (более миллиона) это займет несколько часов. Поэтому я решил исследовать, как крупные парни, такие как google, facebook, instagram и twitter, хранят миллиарды изображений, и нашел пару видеороликов на YouTube, которые объясняют части архитектуры, затем я наткнулся на SeaweedFS и попробовал. Я быстро взглянул на исходный код "версии 0.76", и все кажется прекрасным "без подозрительного кода". единственной запиской был lo go, полученный через CDN, а не локально.

Красота seaweedFS заключается в его простоте и стабильности, и это своего рода скрытый драгоценный камень (догадывайтесь, пока сейчас). Помимо возможности хранить миллиарды файлов и получать к ним доступ за sh миллисекунд, он автоматически очищает файлы на основе TTL, это очень полезная функция, поскольку у большинства клиентов ограниченный объем хранилища, поэтому они не могут хранить все данные навсегда. И второе, что мне нравится в нем, - это экономия большого объема памяти, например:

На моем сервере каждый файл потреблял Multiple of 8 KB из дискового пространства (из-за структуры файловой системы), так что даже большая часть мои эскизы имели размер 1 or 2 KB, он потреблял 8 KB, поэтому, когда вы складываете все потраченные впустую байты, вы в конечном итоге тратите большой процент хранилища, в SeaWeedFS метаданные каждого файла занимают только дополнительные 40 bytes, и это наследие! .

Надеюсь, это поможет.

1 голос
/ 11 июля 2020

Я прочитал здесь, что это вызывает проблемы, когда каталог достигает тысяч файлов

  1. Похоже преждевременная оптимизация мне. Вы беспокоитесь о тысячах . Но сейчас у меня в каталоге ~/.cache/thumbnails около 10 000 файлов, и проблем с этим у меня нет. Сколько эскизов вам действительно нужно? Сделать их! А потом проверьте свою работоспособность.

  2. Где вы это читали? Какие именно проблемы были там описаны? Потому что из this и this вы можете понять, что даже с полмиллионом файлов в одном каталоге вы можете получить к ним доступ довольно быстро. Да, у вас будут проблемы с огромными каталогами, когда вы будете использовать некоторые инструменты (например, ls), но вы уверены, что сможете лучше написать свой сервер.

  3. И, как вариант, вы можете создать параллельную структуру каталогов. Так что для файла z/y/x/image.png миниатюра переходит в thumbnails/z/y/x/image.png. Таким образом, вы получите следующие преимущества:

    1. удобочитаемость
    2. простое сравнение деревьев каталогов исходных изображений и эскизов в случае ошибок
    3. нет необходимости в md5 hashes
    4. более простой код на случай, если вам понадобятся некоторые пакетные операции (например, удаление всех миниатюр для файлов из z/y/x/)

    Это также может быть более эффективным. Но я не уверен - протестируйте.

1 голос
/ 11 июля 2020

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

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

1 голос
/ 08 июля 2020

Если вы используете первые 2 символа md5 в качестве имени папки и предположите, что у вас есть 100 эскизов, причем только 2 эскиза имеют общие первые 2 символа имени файла, вы скоро столкнетесь с проблемой медленной файловой системы.

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

Может быть, вы можете создать структуру каталогов миниатюр на основе даты создания исходного изображения?

Предположим, исходное изображение был создан 3rd May 2019, тогда структура каталогов эскизов может быть thumbnails/52019/abc123.jpg. (Считайте abc123 ха sh)

Итак, чтобы найти указанную выше миниатюру, вам необходимо:

  1. Прочитать дату создания исходного изображения
  2. Вычислить md5 ha sh полного пути исходного изображения (в данном случае это abc123)
  3. Go до папки thumbnails
  4. Найдите подпапка, основанная на дате создания исходного изображения. В данном случае это 52019
  5. Найдите файл, используя ha sh полного пути к исходному изображению

Надеюсь, это хорошо ответит на ваш вопрос.

...