Как хранить изображения в вашей файловой системе

#database #data-structures #blob #file-organization

Вопрос:

В настоящее время у меня есть изображения (максимум 6 МБ), хранящиеся в виде большого двоичного объекта в таблице InnoDB. По мере увеличения размера данных ночное резервное копирование становится все медленнее и медленнее, что препятствует нормальной производительности.

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

Данные имеют древовидную связь:

 - main site
  - user_0
    - album_0
    - album_1
    - album_n
  - user_1
  - user_n
etc...
 

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

Я думаю, я мог бы попробовать MD5('userId, albumId, imageId'); разрезать полученную строку, чтобы получить свой путь к каталогу:

 /var/imageStorage/f/347e/013b/c042/51cf/985f7ad0daa987d.jpeg

Это позволило бы мне сопоставить первый символ с сервером и равномерно распределить структуру каталогов по нескольким серверам.

Однако это не позволит упорядочить изображения для каждого пользователя, вероятно, распространяя изображения для 1 альбома на нескольких серверах.

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

Думаю ли я в правильном направлении? или это вообще неправильный способ делать что-то?

Обновить:
Я пойду на md5(user_id) нарезку струн для разделения на самом высоком уровне. А затем поместите все пользовательские данные в ту же корзину. Это обеспечит равномерное распределение данных, сохраняя при этом пользовательские данные, хранящиеся близко друг к другу.

 /var
 - Хранилище изображений
 - f/347e/013b
 - f347e013bc04251cf985f7ad0daa987d
 - 0
 - альбом1_10
 - picture_1.jpeg
 - 1
 - альбом1_1
 - picture_2.jpeg
 - picture_3.jpeg
 - альбом1_11
 - picture_n.jpeg
 - n
- альбом1_n

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

Спасибо!

Комментарии:

1. Рассматривали ли вы возможность создания инкрементного резервного копирования базы данных?

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

3. Я думаю, что инкрементное резервное копирование только временно решит проблему.

Ответ №1:

Просто разделите свой идентификатор пользователя сзади. например

 UserID = 6435624 
Path = /images/24/56/6435624
 

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

Комментарии:

1. Да,именно это я и собирался сказать. Переверните цифры в числовом идентификаторе, и, скорее всего, он будет распределяться равномерно, как бы по кругу.

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

3. @Alix: Предположим, что 75 идентификаторов пользователей распределяются монотонно возрастающим образом. Цифра 1 проходит циклически от 0 до 9 и повторяется. В среднем существует равное количество вхождений каждой цифры. 10-значные циклы тоже, но только от 0 до 7; они никогда не доходят до 8 или 9. Кроме того, цифра 100-это просто 0-никакого распределения вообще. Поэтому лучше использовать нижние цифры идентификатора пользователя в качестве индекса для каталогов более высокого уровня.

4. @wilmoore: Зависит от того, какой алгоритм хэширования вы используете, но, вероятно, вы используете md5 или что-то в этом роде, где любая цифра с такой же вероятностью будет равномерно распределена, как и другая цифра. Так что в этом случае нет никакого преимущества в выборе крайних правых цифр для ваших каталогов верхнего уровня. Вы с такой же вероятностью распределите файлы равномерно, выбрав крайние левые цифры хэш-строки.

5. какой идентификатор пользователя маленький (например, 5 или 19)? где бы вы хранили изображения?

Ответ №2:

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

напр.

abcdefgh.jpg -> a/ab/abc/abcdefgh.jpg

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

Ответ №3:

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

  • переверните строку
  • обнулите его начальным нулем, если есть нечетное количество цифр
  • разделите строку на двухзначные подстроки
  • постройте путь, как показано ниже
     17 >> 71 >> /71.jpg
    163 >> 0361 >> /03/61.jpg
    6978 >> 8796 >> /87/96.jpg    
    1687941 >> 01497861 >> /01/49/78/61.jpg
     

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

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