Перейти к контенту

Как мы ломали

  • записи
    24
  • комментариев
    147
  • просмотра
    16 233

Используем мемкеш - паттерны и антипаттерны


MiksIr

203 просмотра

Чего никогда не стоит делать при работе с мемкешом

1. Быть уверенным, что там есть те данные, что мы положили. Мемкеш не гарантирует хранение данных.

2. Менять какие-то данные в структуре, записанной под одним ключом, т.е. операция вида get -> change -> set. Гарантированны коллизии.

3. Услышав слово "блокировки" реализовывать их для того, что бы предыдущий пункт работал. Блокировки - зло.

4. Хотеть получить список ключей. Это очень часто хочется получить, и с этим желанием нужно боротся, ибо это путь к неверному пониманию принципа "зачем нужен мемкеш"

 

Неймспейсы.

Реализация неймспейсов, которая позволить очистить весь неймспейс, достаточно проста. Введите ключ типа mynamespacename_version в котором храните... м.. таймстамп. К каждому ключу (при чтении и записи) в этом неймспейсе приделывайте сам неймспейс и вот тот таймстамп из ключа _version. Теперь, стоит лишь поменять значение ключа _version, все последующие чтения перестанут находить старые ключи. Со временем старые ключи удаляться за счет вытеснения.

 

Теги.

Теги более интересны, так как позволяют вешать зависимость одного ключа от нескольких тегов. Например, когда мы кешировали данные выборки, сначала использовали неймспейсы (по имени модели). Когда пошли join-ы, выборка стала зависеть от нескольких моделей - при изменении каждой нужно было удалить кеш. Принцип тут похожий, но немного другой. Для каждого тега в отдельном ключе мы храним его версию - таймстамп. При сохранении данных, мы оборачиваем их в массив (хеш), и храним таймстамп (т.е. время создания объекта в кеше) и теги. При получения объекта смотрим теги и запрашиваем их из мемкеша. Теперь к нас набор таймстампов - у каждого тега (время "очистки" этого тега) и у объекта - время его создания. Сравниваем, если объект устарел - просто про него забываем (или даже можнем сказать delete в мемкеш)

 

Бизи-локи.

Своеобразные блокировки. Задача проста - если ключ в кеше протух, не допустить, что бы *дцать процессов ломанулись за ним в базу. Суть проста - не найдя ключ ставим флаг блокировки, лезем в базу, пишем в кеш, снимаем блокировку. Другие процессы, не найдя ключ проверяют блокировку... и если она есть - ждут ее снятия или протухания (на блокировку имеет смысл ставить мальненькое время жизни, ибо огромная очередь "ожидающих" может оказаться хуже, чем запросы в базу).

 

Читаем-сохраняем.

Если очень нужно делать п.2 из списка того, чего не нужно делать - есть средство. Появилось оно не так давно. Делаем специальный запрос get, который возвращает не только значение, но и уникальное число. Это число привязано к ключу внутри мемкеша и увеличивается при каждой операции над ключом. При сохранении ключа мы так же передаем это число. Операция успешна только если переданное при записи и сохраненное внутрях мемкеша числа совпадают (т.е. изменений не было). Эта операция лучше хотя бы тем, что мы не тратим время на установку блокировок, а значит вероятность коллизии уменьшается. Хотя под активной нагрузкой это решение особо не поможет.

 

В общем, это банальности, по которым мы прошли... может еще потом что вспомню.

17 комментариев


Рекомендуемые комментарии

На мемкеше свет клином не сошелся поглядите eAccelerator в нем блокировка нативно есть

 

мемкеш хорош, но недостаточен

вам надо иметь кучу серверов с мемкешем? думаю нет Ну и про затраты доставки данных по TCP/IP не забываем

Ссылка на комментарий

Совершенно разные вещи. Разные _цели_ и разные методики использования.

Даже и в голову не могло приди их рассматривать вместе ;)

От MySQL думаю, вы уже давно отказались в пользу кого-нибудь беркли, да? А то.. затраты на tcp/ip =)

Ссылка на комментарий

eAccelerator, APC, X-Cache - это все варианты shared memory. С тем же успехом можно использовать shmop_*. Мемкеш в эту группу вписывать никак нельзя, а значит и сравнивать. Никто же мемкеш (и уж тем более шаред мемори) не сравнивает с СУБД.

 

Необходимость шареной памяти для кеширования... для меня очень призрачная, если честно. Т.е. я даже представляю, что такое решение может помочь сэкономить дополнительный сервер СУБД, когда один уже перестает справляться... но стоит посмотреть чуточку дальше, и второй сервер под исполнение скриптов маячит уже близко. А если сразу думать о HA (резервирование), то два сервера изначально.

 

А два сервера... можно, конечно, с шаренной памятью запустить, но во-первых не экономно, а во-вторых - поддерживать консистентность такого кеша - аццкая задача, ибо при изменении объекта об этом придется сказать всем нодам. Так что мемкеш.

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

 

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

 

По-этому у меня не стояло никаких VS - что использовать. Мемкеш хорош и _достаточен_ для тех целей, которые он выполняет. Но в использовании есть свои хитрости, основная из которых - отучиться думать, что мемкеш - это типа СУБД... и вид шаред мемори.

Ссылка на комментарий

И при чем тут сравнение с СУБД?

 

Кто это сказал что Мемкеш это СУБД? Может быть вы? :)

 

Просто напросто чаще всего Мемкеш юзают для хранения даных из СУБД. )))

 

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

Ссылка на комментарий

Я не говорил, что это СУБД. Я говорил, что люди, привыкшие работать с СУБД и взявшие в руки механизм типа мемкеша пытаются с ним работать так же, как и СУБД - а он для этого не предназначен. Новых программистов, которые даже знают что такое мемкеш приходится отучать так думать. И пишут "велограбли" именно такие люди, которые не умеют работать с мемкешем... остальные следуют принципу - блокировки зло.

 

И мне _не нужны_ блокировки. А вы говорите - посмотрите, а там они есть. Блокировки для кеша - антипаттерн, использовать его можно только десять раз подумав головой - как это скажется на производительности... а если уж решено, решение мемкеша мне тут больше нравится (не блокировки, а как бы контроль целостности). А если на производительность плевать - то зачем вообще кеш? СУБД умеет блокировки сама и гораздо лучше.

 

Пространно я рассуждают не о меж... проблемах, а об архитектуре проекта, как текущем, так и в будущем. Т.е. вы можете, конечно, разрабатывать по другому принципу, не думая о последвиях. Я - не могу ;)

 

И.. спасибо за совет, но я в общем его не спрашивал. Этот пост не о том, когда выбирать и использовать мемкеш. А о том - _как_ его использовать. Возможно кому-то подойдет шаренная память для кеша - что ж, если он сделал этот выбор осознанно после проектирования архитектуры проекта - его право. С удовольствием послушаю причины выбора. Я же других альтернатив, когда серверов больше одного - не вижу.

Ссылка на комментарий

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

 

Лан сори тебе не это нужно, я замолкаю.

Ссылка на комментарий

Угу.. начал обновление - поставил лок. Второй процесс ждет освобождение лока. Окончил обновление - снял лок. Второй процесс пошел обновлять кеш =)) Там же локи на кусок кода, а не на ключи в шареной памяти. Дополнительную логику писать придется... в частности, опять проверять кеш.

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

Ссылка на комментарий

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

Я бы, кстати, локи еацелератора для выстраивания очереди за данными, назвал бы костылем... да еще и неуправляемым. Интуиция подсказывает, не для этого эти функции там сделали...

Ссылка на комментарий
Я вообще не встречал термина "когерентность данных" ;) Консистентность тут более понятно... так как данные в кеше у нас все же связаны с исходными данными в базе, и при изменении последних нужно обновить все данные по всем кешам.
Ссылка на комментарий

Жаль, исчезла запись про вакансии. Вы там в комментах писали о том, что российский веб-дев имеет свойство терпеть до тех пор, пока нагрузки окончательно не нагнут стартап. А потом только начинается оптимизация.

 

Ну да.. http://www.autocommunity.ru/forum/ -> спустя год, здесь противоположная картина. Код офигенен и быстр, но вот беда - нет дизайна и контента. Но главное -> нет пользователей. И кому теперь нужен этот труд?

 

Какая ирония..

Ссылка на комментарий

Ой, напугали.. аж ручку выронил. ^_^ Собираетесь ли ещё с какими-то проектами поглотить объединиться в ближайшем будущем, или пока только toyota-russia?

 

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

 

Вакансии всегда интересуют, но в чуть отдалённой перспективе. Август-октябрь этого года. Пока что информацию собираю.

Ссылка на комментарий

Уверен, что 90% привыкнут к новому дизайну. Привычка - дело такое... не зависит от реальной удобности =) сразу вспоминаются эксперименты, особо 10-й.

Слияния в перспективе есть, но подобные планы - это уже не ко мне. Пока ничего опредеденного - нужно на этом объеме процесс отладить =)

Ссылка на комментарий
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, вы соглашаетесь на использование файлов cookie, а также с нашим положением о конфиденциальности Политика конфиденциальности и пользовательским соглашением Условия использования.