Кэширование объекта размером 302 МБ

#php #caching

#php #кэширование

Вопрос:

У меня есть объект (фактически, массив объектов) размером 302 МБ. Когда я пытаюсь кэшировать его с помощью memcached, это не работает, независимо от того, сколько памяти я предоставляю memcached, по-видимому, потому, что memcached имеет ограничение в 1 МБ на объекты, которые он может кэшировать. (Возможно, я ошибаюсь насчет последней части. Я не смог найти отличную документацию.)

Есть предложения о том, как это кэшировать? Я использую PHP / symfony в Linux.

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

1. Почему он такой большой? Это кажется довольно огромным!

2. кэшируйте его в файловой системе, а не в memcache, или кэшируйте каждый элемент массива по отдельности

3. Кэширование и 320 МБ …огоооооооооооооооооооооооооп

4. Откуда берутся 302 мб?

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

Ответ №1:

Цитирование

15.5.5.4: Каков максимальный размер объекта, который вы можете сохранить в memcache, и настраивается ли он?

Максимальный размер объекта по умолчанию равен 1 МБ. В memcached 1.4.2 и более поздних версиях вы можете изменить максимальный размер объекта, используя опцию командной строки -I.

Для версий до этой, чтобы увеличить этот размер, вам придется повторно скомпилировать memcached. Вы можете изменить значение POWER_BLOCK в файле slabs.c в исходном коде.

В memcached 1.4.2 и более поздних версиях вы можете настроить максимальный поддерживаемый размер объекта с помощью опции командной строки -I. Например, для увеличения максимального размера объекта до 5 МБ:

  $ memcached -I 5m
  

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

Цитирование Почему размер элементов ограничен 1 мегабайтом?

Краткий ответ: Из-за того, как работает алгоритм распределителя памяти.

Длинный ответ: Механизм хранения памяти Memcached (который будет подключаться / настраиваться в будущем …) использует модульный подход к управлению памятью. Память разбита на фрагменты разного размера, начиная с минимального числа и возрастая на факториал до максимально возможного значения.

Допустим, минимальное значение равно 400 байтам, а максимальное значение равно 1 мегабайту, а факториал равен 1,20:

таблица 1 — 400 байт, таблица 2 — 480 байт, таблица 3 — 576 байт … и т.д.

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

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

Если вы действительно хотите хранить элементы размером более 1 МБ, вы можете перекомпилировать memcached с отредактированным значением slabs.c:POWER_BLOCK или использовать неэффективный сервер malloc / free. Другие предложения включают базу данных, MogileFS и т.д.

Ответ №2:

Возможно, вы могли бы использовать общую память (но с таким размером я бы проголосовал против этого) или использовать RAM-накопитель.

Это для одного веб-сервера или вы ищете общий кэш для нескольких веб-серверов?

Я все еще присоединяюсь к другим, когда они говорят, что вам, вероятно, нужен другой подход. Попытайтесь объяснить, какого рода данные вы хотите кэшировать.

Ответ №3:

В качестве альтернативы вы можете быстро изменить ограничение, отредактировав файл конфигурации [/etc/memcached.conf], добавив:

 # Increase limit 
-I 512M
  

После перезапуска вашего сервиса.

Ответ №4:

Вам никоим образом не понадобится кэшировать экземпляр объекта размером 302 МБ (или массив объектов).

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