Подтвердить что ты не робот

Мембранное выселение до истечения срока действия ключа?

Может ли пара ключ/значение, хранящаяся в memcached, быть выселена до истечения срока ее действия, если имеется свободное пространство?

У меня есть процесс memcached, который позволяет потреблять до 6 ГБ; 2,5 ГБ сообщается в использовании, и это число колеблется только минимально (+/- 100 МБ в однодневном пролете). Если я установил простое строковое значение, которое истекает через 15 минут, возможно ли, что он будет выдворен (cache.get возвращается не найден) до истечения 15 минут?

Спасибо, -Эрик

4b9b3361

Ответ 1

да

В основном, memcache выделяет пространство в chuncks vs on-demand, а затем сохраняет элементы в кусках и управляет этой памятью вручную. В результате более мелкие элементы могут "использовать" гораздо большие части памяти, чем если бы они были распределены по каждому элементу.

Ссылка объясняет это намного лучше, чем я могу

https://groups.google.com/group/memcached/browse_thread/thread/8f460034418262e7?pli=1

Изменить: добавление дополнительных объяснений

Memcache работает, выделяя плиты разных размеров. Эти плиты имеют ряд специальных размеров (которые определяются классом slab).

Гипотетически (и используя только мою абстракцию внутренних элементов Memcache), допустим, что наименьший размер slab-класса был 1K. Это означает, что самые маленькие слоты составляют 1K. Кроме того, Memcache будет выделять их только в наборах 1024 или 1 Мбайт памяти за раз. Допустим, у нас была такая конфигурация, и мы хотим сохранить 1-байтовый объект (char значение?) В Memcache. Предположим, для этого потребуется 5 байт памяти (4 байтовый ключ?). В пустом кеше Memcache будет выделять новую панель наименьшего размера, которая может удерживать значение (слоты 1K). Таким образом, сохранение ваших 5 байтов заставит Memcache выделить 1 МБ памяти.

Теперь, скажем, у вас их много. Следующие 1023 будут "бесплатными" - Memcache уже выделил память, поэтому дополнительной памяти не требуется. В конце этого вы сохранили 1024 * 5 байт = ~ 5 КБ, но Memcache использовал 1MB для его хранения. Сохраните несколько миллионов из них, и вы можете представить себе потребляющие гигабайты памяти для хранения килобайт данных.

Это близко к худшему. На практике Memcache может быть настроен на минимальный размер класса slab, если необходимо, и фактор роста (разность размеров между slab-классами) можно расширить или сузить. Если вы выполняете кеширование запросов к базе данных, у вас могут быть элементы размером от нескольких байтов до нескольких КБ, причем содержимое страницы можно даже попасть в МБ.

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

Предположим, что у вас есть система, которая была успешно запущена и кэшировалась в течение нескольких дней. У вас есть сотни плит разных размеров. Вы развертываете новую стратегию кэширования страниц для своего приложения без сброса кеша. Теперь вместо кэширования целых страниц вы кешируете части страницы. Вы изменили свой шаблон кэширования на хранение большого количества объектов размером ~ 1 МБ для хранения большого количества объектов размером ~ 10 КБ. Здесь, где мы попадаем в беду. Memcache выделил кучу слябов, содержащих объекты размером около 1 МБ. Вы никогда не использовали для кэширования многих объектов размером 10 КБ раньше. Плиты с слотами 10 КБ быстро заполняются, но теперь у вас есть целая куча выделенных слябов, в которых хранятся объекты 1 МБ, которые не используются (ничего больше не так уж и много). Memcache не будет помещать ваши объекты 10 КБ в 1 МБ слот (даже если бы это произошло, это не помогло бы очень долго). Он должен получить больше слябов, содержащих объекты 10 КБ, но это невозможно, потому что вся ваша память была выделена в панели, на которых хранятся объекты 1 МБ. В результате вы остаетесь с потенциально гигабайтами памяти, выделенной в слябах, для хранения объектов 1 МБ, которые сидят без дела, пока ваши плинты на 10 Кбайт заполнены. В этом случае вы начнете высекать предметы из плит 10KB-слотов, несмотря на то, что гигабайты сидят без дела.

Это был длинный, надуманный и экстремальный пример. Редко ваша стратегия кэширования меняется так явно или так резко. По умолчанию коэффициент роста slab-классов составляет 1,25, поэтому у вас будут плиты с 1 КБ слотами, 1.25 КБ слотов, 1.5 КБ слотов и т.д. Концепция выполняется - если вы сильно используете плиты определенного размера и сдвиги шаблонов (sql запросы возвращают больше объектов? веб-страницы становятся больше? добавьте столбец в таблицу, которая перемещает кешированный ответ на класс slab? и т.д.). Тогда вы можете получить кучу слябов, которые являются "неправильным" размером, и вы можете иметь "нигде" не хранить что-то, несмотря на гигабайты "неиспользуемого" пространства.

Если вы получаете выселения, возможно, telnet в Memcache и узнать, какие плиты вызывают выселения. Обычно проблема с кешем - reset (да, пустое все) устраняет проблему. Вот ссылка на то, как попасть в статистику. http://lzone.de/articles/memcached.htm

Ответ 2

Memcached хранит данные в соответствии с плитками разных блоков памяти. Если разные фрагменты памяти уже выделены, то последний использованный алгоритм работает на панели и вытесняет данные, даже если в других плитках памяти нет данных.

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