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

В настоящее время у меня есть изображения (максимум 6 МБ), хранящиеся как BLOB в таблице 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 альбома на нескольких серверах.

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

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

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

  /var
   - imageStorage
     - f/347e/013b
       - f347e013bc04251cf985f7ad0daa987d
         - 0
           - album1_10
             - picture_1.jpeg
         - 1
           - album1_1
             - picture_2.jpeg
             - picture_3.jpeg
           - album1_11
             - picture_n.jpeg
         - n
           - album1_n

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

Спасибо!

Ответ 1

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

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

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

Ответ 2

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

например.

abcdefgh.jpg → a/ab/abc/abcdefgh.jpg

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

Ответ 3

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

  • изменить строку
  • zerofill с начальным нулем, если нечетное число цифр
  • помещает строку в двухзначные подстроки
  • постройте путь ниже

    17 >> 71 >> /71.jpg
    163 >> 0361 >> /03/61.jpg
    6978 >> 8796 >> /87/96.jpg    
    1687941 >> 01497861 >> /01/49/78/61.jpg
    

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

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