В настоящее время у меня есть изображения (макс. 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) для разделения на высшем уровне.
А затем поместите все пользовательские данные в ту же корзину. Это обеспечит равномерное распределение данных, сохраняя при этом данные пользователей близко друг к другу.
/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, разделенный сзади (мне нравится эта идея!), Чтобы уменьшить количество альбомов в каталоге (хотя для большинства пользователей в этом нет необходимости).
Спасибо!
Рассматривали ли вы создание инкрементных резервных копий БД?
Я думаю, что инкрементное резервное копирование только временно решит проблему.

Просто разделите свой идентификатор пользователя сзади. например
UserID = 6435624
Path = /images/24/56/6435624
Что касается резервного копирования, вы можете использовать репликацию MySQL и резервное копирование ведомого устройства. база данных, чтобы избежать проблем (например, блокировок) при резервном копировании.
Ага, вот что я хотел сказать. Поменяйте местами цифры в числовом идентификаторе, и это с большей вероятностью будет распределяться равномерно, что-то вроде циклического перебора.
@ Билл: Я не понимаю. Почему реверсирование идентификатора пользователя с большей вероятностью приведет к равномерному распределению? Это потому, что у старых пользователей было больше времени для загрузки большего количества изображений?
@Alix: предположим, что 75 идентификаторов пользователей выделяются монотонно возрастающим образом. Цифра 1 циклически проходит от 0 до 9 и повторяется. В среднем каждая цифра встречается в равном количестве. Цифры 10 тоже цикличны, но только от 0 до 7; он никогда не достигает 8 или 9. Кроме того, цифра 100 - это просто 0 - никакого распределения. Поэтому лучше использовать младшие цифры идентификатора пользователя в качестве индекса для каталогов более высокого уровня.
@ Билл: Конечно, в этом есть смысл! Спасибо, что объяснили мне это. знак равно
@Bill, @Node: если имя файла хешировано, должна ли структура каталогов по-прежнему быть получена из нехешированного идентификатора или лучше применить ту же стратегию к хешированному значению?
@wilmoore: зависит от того, какой алгоритм хеширования вы используете, но, вероятно, вы используете md5 или что-то в этом роде, где любая цифра с такой же вероятностью будет распределена равномерно, как другая цифра. Так что в этом случае нет никакого преимущества выбирать крайние правые цифры для ваших каталогов верхнего уровня. С такой же вероятностью вы распределите файлы равномерно, выбрав крайние левые цифры хеш-строки.
какой у пользователя id маленький (например 5 или 19)? где бы вы хранили изображения?
@cherouvim: Поменяйте местами, а затем заполните ID до 4 символов, например /00/05/0005 или /00/91/0019?
одна вещь о распределении имен файлов по разным каталогам, если вы рассматриваете возможность разделения имен файлов 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 предсказуемо, это зависит от ваших потребностей.
Ах, я бы посоветовал отредактировать "красиво распределить" на "равномерно распределить". Теперь я понимаю, что ваша цель - попытаться усреднить количество изображений в папке файловой системы.