Какой самый быстрый и эффективный способ хранения и извлечения изображений, когда на сервере LAMP находятся миллионы пользователей? - PullRequest
7 голосов
/ 29 июля 2011

Вот лучший метод, который я когда-либо придумал, и я хотел бы знать, есть ли еще лучший метод (я уверен, что есть!) Для хранения и выборки миллионов пользовательских изображений:

Чтобы уменьшить размеры каталогов и избежать дополнительных вызовов к БД, я использую вложенные каталоги, которые рассчитываются на основе уникального идентификатора пользователя следующим образом:

$firstDir = './images';
$secondDir = floor($userID / 100000);
$thirdDir = floor(substr($id, -5, 5) / 100);
$fourthDir = $userID;
$imgLocation = "$firstDir/$secondDir/$thirdDir/$fourthDir/1.jpg";

Идентификаторы пользователя ($userID) варьируются от 1 до миллионов.

Так, например, если у меня есть идентификатор пользователя 7654321, первое изображение этого пользователя будет сохранено в:

./images/76/543/7654321/1.jpg

Для идентификатора пользователя 654321:

./images/6/543/654321/1.jpg

Для идентификатора пользователя 54321 это будет:

./images/0/543/54321/1.jpg

Для идентификатора пользователя 4321 это будет:

./images/0/43/4321/1.jpg

Для идентификатора пользователя 321 это будет:

./images/0/3/321/1.jpg

Для идентификатора пользователя 21 это будет:

./images/0/0/21/1.jpg

Для идентификатора пользователя 1 это будет:

./images/0/0/1/1.jpg

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

Я сравнил этот метод с использованием следующего метода «хэширования», который использует самый быстрый метод хэширования, доступный в PHP (crc32). Этот метод «хэширования» вычисляет Второй каталог как первые 3 символа в хэше идентификатора пользователя и Третий каталог как следующие 3 символа для распределения файлов случайным образом, но равномерно, следующим образом:

$hash = crc32($userID);
$firstDir = './images';
$secondDir = substr($hash,0,3);
$thirdDir = substr($hash,3,3);
$fourthDir = $userID;
$imgLocation = "$firstDir/$secondDir/$thirdDir/$fourthDir/1.jpg";

Однако этот метод хеширования медленнее, чем метод, описанный выше, поэтому он бесполезен.

Затем я пошел еще дальше и нашел еще более быстрый способ вычисления Третьего справочника в моем исходном примере (floor(substr($userID, -5, 5) / 100);) следующим образом:

$thirdDir = floor(substr($userID, -5, 3));

Теперь это меняет то, как / где хранятся первые 10000 идентификаторов пользователя, и некоторые третьи каталоги имеют либо 1 пользовательский подкаталог, либо 111 вместо 100, но преимущество в том, что он быстрее, так как нам не нужно делить на 100, так что я думаю, что в конечном итоге это того стоит.

Как только структура каталогов определена, вот как я планирую хранить фактические отдельные изображения: например, если пользователь загружает 2-е изображение, оно будет находиться в том же каталоге, что и его первое изображение, но будет иметь имя 2.jpg. Изображение пользователя по умолчанию всегда будет просто 1.jpg, поэтому, если он решит сделать 2-е изображение изображением по умолчанию, 2.jpg будет переименовано в 1.jpg, а 1.jpg будет переименовано 2.jpg. * 1056. *

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

1024px:

./images/0/0/1/1024/1.jpg
./images/0/0/1/1024/2.jpg

640px:

./images/0/0/1/640/1.jpg
./images/0/0/1/640/2.jpg

Вот и все.

Итак, есть ли недостатки этого метода? Если да, не могли бы вы указать на них?

Есть ли лучший метод? Если да, не могли бы вы описать это?

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

Спасибо!

1 Ответ

3 голосов
/ 29 июля 2011

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

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

Используйте весь алфавит (строчные и прописные, если ваш FS это поддерживает), а не только цифры. Проверьте, что делают другие программы. Хорошее место для проверки имен хешированных ключей - это Google Chrome, Mozilla, ... Лучше иметь короткие имена каталогов. Быстрее искать, занимает меньше места в ваших HTML-документах.

...