Интересно — это самописный доклад или перевод? Если самописный, товам явно нужно тренировать свое умени формулировать мысли. потом учто просто бьет по ушам английский способ строить предложения. Обратный порядок слов и так далее. По-русски так не говорят. Поэтому и возник вопрос — не перевод ли это.
Извините, а вы не смотрели вот это — code.google.com/p/memcached-tag/? Просто очень часто надо что бы значения удалялись сразу по нескольким ключам. Можно конечно самими организовать на бэкенде, но это медленнее чем если бы на уровне сервера было.
На тестовых данных вроде не плохо себя показывает, а вот на продакт пока боимся.
Эту штуку не смотрел, через пару-тройку постов в серии опубликую «наш» метод работы с тэгами, который не требует патчей (но требует больше операций get).
Подобных патчей к memcached было довольно много, этот — один из самых разумных. Покуда оно не войдет в стабильную ветку, пользоваться этим будет немного рискованно, как мне кажется (в силу того, что оно сильно завязано на ядро memcached и совместимость с последующими версиями под вопросом). Но тут каждый решает сам, конечно же.
Правильно боитесь, почитайте лучше у Котерова (если что, это автор МоегоКруга) его апгрейд для мемкешд. В описании он говорит, что ваше предложение работает, но периодически делает это криво.
Я читал у Котерова, более того, так получилось, что аналогичное с ним решение нам пришло в голову практически одновременно. Я уже рассказывал о своем варианте на конференции, а в следующих постах будет кусок, посвященный тэгированию.
А никто не знает как бороться с «миганием» демонов?
Например есть три сервера…
Жмем ф5- уже два
Еще раз жмем ф5 — три, один, три, ни одного, три и так далее
Возможно, проблемы с сетью, у addServer есть последний параметр — failure_callback, через него советую попробовать настроить логгинг в файл, например. Каждая запись там будет сетевой проблемой с конкретным серверов.
Тем же пингом можно, интервал поменьше, потери он покажет. Если честно, я совсем не админ, так что тут, возможно, нужен «админский глаз». Если я прав про сетевые проблемы, конечно.
Можно попробовать что-то вроде
$conn = new Memcache;
if(!$conn->AddServer($ip, $port) and !$conn->pconnect($ip, $port))
throw new Exception(«Memcache connection error»);
Немного погуглил и выявил несколько вопросов которые было бы хорошо уточнить
1. Соединение с кешедом может упасть когда угодно
2.(Я пока не пробовал) Но если схитрить и в failure_callback сделать конект тудаже где упало — упадет весь ПХП
3. При addServer соединение не производиться до тех пор пока хэшер не решит залесть на частную ноду.
Получается что после старта нельзя проверить какие сервера живы(экстендед статусом) иначе это приведет к конекту ко всем серверам, что не есть гуд.
Хотя… наверное надо будет уменьшить лимиты памяти на демоны кешеда, но задублировать их.
Будет не три по гигу, а 6 по 500.
Вероятность отказа сильно меньше
Сейчас пытаюсь смотреть в сторону libmemcached tangent.org/
У нее большой плюс — с полпинка завелась в MySQL, через UDF полный доступ ко всем основным функциям.
Есть сомнения по совместимости с организацией кластера memcached в том же PHP.
Соединение может пропасть когда угодно, это правда. Но интерфейс клиента прозрачный.
failure_callback не для пересоединения, конечно! Там есть таймауты на новую попытку коннекта и всё остальное. Надо искать причину рассоединения — их не должно быть по-хорошему.
Коннект ко всем серверам — это нормально, если они перзистенты. Какая разница? Потом всё равно с высокой вероятностью все понадобятся.
Почему же нельзя? Если есть кластер memcached серверов, можно ввести избыточное хранение — запись на несколько, чтение с любого. Понятие «нельзя терять» относительно, конечно.
Думаю, понятно, что здесь речь шла не о балансе счета пользователя, а о тех данных, потерю которых хотелось бы минимизировать.
Потеря данных возможна при любом способе хранения, речь идёт об относительной вероятности потери. И данные, которые имеет смысл хранить в memcached, всё равно можно разделить по нашему отношению из возможной потере.
Не вхождения, а в обратном порядке «использования». Это раз. Освобождение зон в слабах, конечно, не контролируется, но при достаточном объеме кэширующей памяти и нормальном распределении размеров мы получим ситуацию, что сессия «живёт» ровно столько, сколько мы хотим.
Речь про потери идёт в двух ситуациях: потеря сервера и вытеснение ключа. Первое — решается избыточностью, второе — правильной настройкой/использованием. Конечно, если мы хотим положить в memcached 2 Гб сессий, а у нас всего 1 Гб — то будет вытеснение, но мы хотим от memcached того, что он не умеет ;)
Про обратный порядок использования пруфлинк, пожалуйста. Что такое <достаточный объём>? Какой объём достаточный? Я понимаю на винтах доступны сотни гигабайт, в памяти такого близко нет.
Про корзины (buckets) вы, кстати, ничего не сказали. Мне кажется или вы не знаете что это? Что будет, если у вас много данных по 16.1Кб вы знаете? Что память забъётся быстрее, чем вы ожидаете тоже знаете? Что потери в памяти могут достигать 50% тоже знаете? И что у вас нет никакого <запаса>, если вы расчитали, что ваши данные могут достигать 1Гб, а у вас их всего два?
Memcached — далеко не самая удачная технология. Не говоря уже о откровенно глупом паттерне его использования: поставить его на тот же сервер, где крутится всё остальное.
Памяти в кластере memcached доступно столько, сколько есть. Сколько каждому нужно. Сегодня есть инсталляции (не самые большие), где кластер имеет ёмкость 750Гб, например. (Это то, о чем я знаю, есть и больше, я думаю).
Про slab-аллокатор я не сказал не случайно. Это тема отдельного разговора и статьи, которая будет попозже в цикле. Да, действительно он так работает, что если зоны будут иметь размер 16 и 32 Кб, то выделения в 16.1Кб пойдут в зону 32Кб и будут потери 50%. Однако сегодня memcached более умно адаптирует slab-аллокатор под потребности конкретной задачи (выделяет зоны нужного размера). Такое поведение slab-аллокатора — это его «фича», он обладает своими недостатками и своими преимуществами.
Запас есть всегда, надо лишь рассчитать грамотно и грамотно мониторить. Я не призываю всё хранить в memcached, я рассказываю о нём как о решении.
Насчет LRU — прямо под рукой линка нет, можете заглянуть в исходники, там механизм LRU достаточно явный.
Согласен с первым, хотя на первом этапе роста это совершенно нормально, лишь бы не навсегда. Хотя, если объем кэширования велик, то memcached работает быстрее, чем, например, кэш на файлах.
Но это всё очень относительно и зависит от конкретной задачи, «серебряной пули» здесь нет.
При масштабировании и росте числа frontend-ов для большинства задач кластер memcached — то, что надо.
Насчет второго — если «нельзя терять» воспринимать буквально, то да, тогда это не задача для memcached, а для ACID-БД на хорошем RAIDе с батарейкой, с бэкапами off-site, hot standy и т. п.
Кто говорит о кеше на файлах? Методов доступа к разделяемой памяти — миллион. И мне не кажется это нормальным. Пишешь абстрактную прослойку для работы с разделяемой памятью, а там что надо то и цепляешь.
Разделяемая память — да, это отличная штука, пока одна машина, один язык программирования и один код. Но дальше не масштабируется. А так согласен, пошустрее будет.
Если несколько языков программирования, например, даже в рамках одного физического сервера, ваять «свою» разделяемую память смысла нет, лучше сразу использовать то, для чего есть биндинги — например, memcached.
1) ну да, тут уместнее использовать Shared memory. Мы не теряем время на подключении к серверу мемкешеда. И если сайт будет расширятся с одной машины на много, и есть возможность в случае чего променять, например APC, на Memcached, то да для одной машины его можно и не юзать. Если такой возможности нет (нет абстрактного интерфейса доступа), то никуда не денешься от использования его на одном сервере.
2) зачастую «нельзя-терять» данные дублируются в БД. Имхо, без этого никак.
а когда так бывает, что абстрактного интерфейса нет? У нас магическим образом появился сервис уже с memcached? :) Memcached, кстати, тоже shared memory.
Если быть более точным, то shared memory — это память, к которой прямой доступ имеют несколько процессов, находящихся на одном физическом сервере.
Distributed memory — это память, которая распределена на нескольких физических хостах, и к ней имеют прозрачный доступ процессы с разных хостов.
Что такое 'distributed' 'shared', я не знаю.
Memcached не является 'memory' в точном смысле этого слова, т. к. доступ не прямой к памяти, а через некоторый API. Это типичный сетевой сервис, на самом деле, который можно рассматривать как 'distributed memory'.
Я думаю, определения для большинства читателей будут полезны. Потому что термины должны быть у всех одинаковы. Я привел классические и широко используемые определения этих терминов и пояснил, почему не бывает «разделяемый распределенный».
В остальном согласен — когда нужна исключительно разделямая память и повышенная производительность, memcached не нужен. Пример такой задачи — разделямая память в сервере PostgreSQL/Oracle, которые работают в многопроцессном режиме.
Чтоб восстанавливать сессию можно использовать автологин. Если не хранить в сессии данные которые должны существовать там между многими запросами и не добавляются при старте сессии, только тогда есть смысл беспокоиться об этом.
Для юзера это выглядит как разлогинивание, особенно если нет автологина. Я бы, например, обиделся, если посреди написания гигантского поста на Хабр у меня бы слетела сессия, а я бы забыл это сохранить ;)
Раз уж топик про кешед — разьсните мне один момент.
Есть пачка сайтов.
И три сервера кешедов. Соединение — гигабит.
Нагрузка на кешед 333 запроса\57 килобайт в секунду
Фигня в общем
Смотрим время генерации страницы… иногда обижаемся… дебажим дебажим и получается что…
иногда fetch занимает много времени.
и это много — 0.20..0.23 секунды.
задержка почти что константна…
бывает 0-4 таких задержок за одно обращение…
Очень интересно, жду продолжения. Я пока с мемкешем работал в тестовом режиме, в продуктиве серверов с ним нет. По этому интересно узнать о том как объединить несколько мемкеш серверов в один кластер, а также можно ли реализовать прозрачное обращение приложения к кластеру мемкеша, то есть, например, есть 3 сервера, на каждом установлен мемкеш. Приложение делает set не указывая на какой их серверов, а затем, точно также не указывая к какому из серверов обращается, делает get и получает ответ от того, на котором был сделан set.
Это пожалуй лучший доклад про мемкеш, коих я слышал уже много на разных конфах(обычно все сводиться в ману+расказу насколько мемкеш крут). Автор молодец, правильный подход к изложению материалов.
Итересно послушать как организуете все это на уровне кода. Просто я вот вижу что многие вещи типичны, в плане usecase-ов кеширования:
— списки
— составные объекты
— атомарные объекты
Если не заботится об атомарности изменений — любой объект разумного размера можно положить в memcached просто через сериализацию.
Когда требуется атомарное изменение, списка, например, это уже становится довольно сложной задачей: можно использовать аналог блокировок (об этом будет позже в цикле статей) или другими подходами.
Если будет конкретный вопрос, постараюсь ответить.
Послушать подход. Код не проблема.
Если какой-то каркас классов?
Например, интефейсы или классы с общей логикой взаимождействия с кешем. Или все просто if(cache) else
Например, в яве кешированием можно управлять через аннотации, а там уж само создаются враперы…
Я думаю что управление кешем это задача исключительно фреймворка.
Если пхп не умеет понимать «умные» конструкции типа явовский анотаций — есно дело и кешед это никак не научиться.
В принципе для себя я выбрал два подхода
1- ручной if(!cache_start(«name»,ttl)){ code ;cache_end();}
2- документ-представление — если блок класса N смотрим таймаут на класс N
Это больше про доступ к кешу.
Я больще хотел узнать про выделения стратегий кеширования. Например, что-то работает через теги, изменилось удалить/пересчитать все связи. Что-то пересчитывается через локи… Т. е. типичные поведения
Здравствуйте, Андрей. Возник вопрос. Какие есть решения для разделения данных по критичности? Следует ли хранить различные по критичности данные на разных серверах или есть какие-нибудь способы повлиять на то, каким образом удаляются ключи?
Управлять удалением по сути нет прямой возможности, т.е. сказать что данный ключ «важен». Есть MemcacheDB, который гарантирует сохранность данных. Можно брать несколько пулов серверов, если память не будет заканчиваться в «важном» пуле, то и удаления ключей не будет.
Кэширование и memcached