Как хранить изображения в вашей файловой системе
В настоящее время у меня есть изображения (макс. 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 альбома на несколько серверов.
Мой вопрос:
Каков наилучший способ сбалансированного хранения данных изображения в файловой системе при сохранении данных пользователя / альбома вместе?
Думаю ли я в правильном направлении? или это неправильный способ делать вещи вообще?
Обновить:
Я пойду за md5(user_id)
нарезка строк для разделения на высшем уровне. А затем поместите все пользовательские данные в ту же корзину. Это обеспечит равномерное распределение данных при одновременном хранении пользовательских данных.
/ вар - 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 - н - album1_n
Я думаю, что я буду использовать albumId, разделенный сзади (мне нравится эта идея!), Чтобы уменьшить количество альбомов в каталоге (хотя это не будет необходимо для большинства пользователей).
Спасибо!
3 ответа
Просто разделите свой идентификатор пользователя сзади. например
UserID = 6435624
Path = /images/24/56/6435624
Что касается резервного копирования, вы можете использовать MySQL Replication и сделать резервную копию подчиненной базы данных, чтобы избежать проблем (например, блокировок) во время резервного копирования.
Одна вещь о распределении имен файлов в разные каталоги, если вы подумаете о том, чтобы разделить имена файлов md5 на разные подкаталоги (что, как правило, хорошая идея), я бы предложил сохранить полный хэш как имя файла и дублировать первые несколько символов как имена каталогов. Таким образом, вам будет легче идентифицировать файлы, например, когда вам нужно переместить каталоги.
например
abcdefgh.jpg -> a/ab/abc/abcdefgh.jpg
если ваши имена файлов распределены неравномерно (не хеш), попробуйте выбрать метод разделения, который получает равномерное распределение, например, последние символы, если это инкрементный идентификатор пользователя
Я использую эту стратегию, учитывая уникальный идентификатор изображения
- перевернуть строку
- обнулять его с нулем в начале, если есть нечетное число цифр
- разбить строку на две цифры подстроки
построить путь, как показано ниже
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 является предсказуемым, оно зависит от ваших потребностей.