Борьба с фрагментацией PHP кешеров

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

Итак лидером для этого дела(лично я) могу назвать систему memcached.
Распределенность. Своя память( нормальные кэшеры работают в shared-memory веб сервера), да и не какието там 32-512 мегабайт, а вплоть до 4х гигов
(4 гигабайта это лимит для одного процесса memcached(32 бит адресация), если у вас 32Гига оперативы просто запустите с десяток демонов на одном компе, ну и с десяток на другом)
Но что плохо в memcached.

1. Он тормоз - сетевое взаимодействие( даже в пределах Localhost) это не быстро
2. Он НЕ кеширует opcode


Главное не забыть главный плюс - мемкешед кеширует МНОГО данных..

Итак, вроде как разобрались что одним мемкешедом сыты не будем.
Требуется поставить еще и opcode cacher.
Опять же по моему мнению надо разорваться между

1.APC
2.eAccelerator
3.XCache


ВСЕ они работают с кешем ну раза в два-три быстрее чем memcached.
У memcached только store ничего не стоит(асинхронность?) а вот попробуйте вытащить данные - пока пакет сюда, пока туда. Ну миллисекунда будет уж точно, а то и все пять.

Плюс XCache - очень хорошо оптимизирует скрипты.
Плюс eAccelerator - имеет операцию LockUnlock что позволяет исключить одновременное кеширование одного блока четырьмя пользователями.
( у меня както один блок ( самые популярные новости этой недели ) кешировался одновременно в 6 потоков. База данных просто ложилась из-за перекрестных LOCK. До перехода на eAccelerator блок пришлось просто снять ( Lock через ФС я считаю ненадежным ))
Плюс APC - он работает быстрее чем eAccelerator, но ничего "такого" не умеет.

На локальной машине(винда) оптимизацией файлов у меня занимается XCache, кэширование данных - eAccelerator ( из-за lockunlock )
На сервере.. а на сервере система не дает поставить их одновременно.
Ложиться на пол, стучит ручками-ножками, и говорит - либо Xcache либо APC, многоженства у нас нет!
Так что стоит eAccelerator only.
Кеш лежит себе поживает в memcached на двух серверах.
Ну и плюс к этому все операции с кешем read-write также дублируются как в локальный кеш, так и в мемкешед.
Тоесть при операции store делаем


$ttl+=rand(0,$ttl/10);// ОЧЕНЬ полезно чтобы кешы созданные в одно время,EXPIREлись в разное
cache_storelocal($name,$value,$ttl/2);// кладем в eAcc на половину времени жизни
cache_storeglobal($name,$value,$ttl);// кладем в мемкешед на весь срок


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

Такс, я забыл по теме расказать..
В общем жили были мы хорошо, а потом проекты начали просто крашиться.
Встаешь с утра. Сайты висят(segmentation fault). service httpd restart
Проходит час. Сайты начинают тормозить( в десятки-сотни раз, загрузка процессора..7% ) service httpd restart
Три дня мы былись над проблемой.
А проблема была проста - фрагментация памяти кешера( просто проекты которые не использовали локальный кешер работали нормально)..
И как выглядела это фрагментация - при выделеных 64 метрах кешер ЧЕСТНО сообщал что его данные весят.. гигабайт?( обычно говорил 1.6G)
Идешь посмотреть переменные ручками - некий array на 60 байт весит..8 мегабайт?

Мы для начала решили всетаки эту проблему запретив локально кэшироваться большим данным( картинкам и текстам), вроде уже 50 часов сервер стоит и не перезагружается..

Но зайдя както на "вторичный" сервер( параллельная обработка ajax запросов ) я увидел картину репина - фрагментация 100%. Все сохраненные данные - махонькие махонькие( зато оч оч много ).
Что же делать какже быть. Как фрагментацию убить.

Лично я пока придумал только одно решение -
1.разрешаем "себе" занять побольше памяти.
2.забираем последовательно все данные из локального кеша ( он у нас 64 метра, из них 24 метра заняты кешем файлов, итого 40 метров - а это фигня)
3.грохаем кеш.
4.засовываем данные обратно.
Время работы - гдето полторы секунды.
и крон раз в час.
Но лично по мне - решение кривовато.
Другие варианты есть?

ПС: Предложение не кешировать переменые в локальном кеше отвергаю.
Поверте и проверте - стоит!

Автор: kashey
Источник: habrahabr



Опубликовал admin
12 Апр, Суббота 2008г.



Программирование для чайников.