Есть в memcached такая неприятная штука как eviction. Случается когда свободной памяти не осталось для выделения новых страниц в slab, а свободных чанков в slab-e тоже нет. Тогда в slab-e берется какой-нибудь занятый чанк и затирается новыми данными. И это не взирая на то, что в соседних slab-ах могут быть свободны целые страницы – если страница выделена в slab, она останется там навсегда. Если не воспользоваться штукой под названием Slabs Automove. Иначе можно найти знатные грабли как мы.
В один прекрасный день наши разработчики выкатили новую версию кода, которая более агрессивно использовала memcache, причём распределение хранимых данных по размеру сильно изменилось. Так как наш memcache был и раньше забит и память уже была распределена по slab-ам, то некоторые большие slab-ы оказались практически полностью свободны, а нужные забиты под завязку и новые рабочие данные начали быстро вытеснятьcя по кругу. При этом, по факту memcached использовал только 50% памяти из доступной ему. Прошло значительное количество времени пока мы поняли в чём дело.
Вывод такой: если значительно меняется количество данных и их распределение по размеру, следует обнулять memcache.
Размер страницы (1MB по умолчанию) стоит ограничить максимально ожидаемым размером значения хранимых данных, при этом уменьшая фактор роста чанка с 1.25 по умолчанию например до 1.10. Это позволить существенно уменьшить потери памяти в slab-ах: на сервере c настройками по умолчанию Used/Wasted составляет 1.5 GBytes/532.0 MBytes, с настройками -I100k -f 1.10 – 1.2 GBytes/152.4 MBytes при том, что одни и те же данные пишутся на оба сервера.
В качестве бонуса пара заплаток для модуля pecl-memcache 3.0.8 для php:
- pecl-memcache-3.0.8-inbox-nolockinsessionhandler.patch
отключает блокировки при использовании session_redundancy = 2 и более, что ускоряет работу модуля за счёт потери 100% гарантии идентичности копий данных. - pecl-memcache-3.0.8-inbox-redundacyonread.patch
принуждает модуль при использовании redundancy = 2 и более проверять другие копии, если основная копия не содержит запрашиваемые данные.