Memcached
Memcached — это свободно распространяемая высокопроизводительная система кэширования данных в оперативной памяти, работающая по принципу «ключ-значение» (key-value store). Предназначена для ускорения работы динамических веб-приложений путём снижения нагрузки на базы данных и другие медленные источники данных. Memcached хранит данные в виде пар «ключ-значение» в оперативной памяти сервера, обеспечивая субмиллисекундное время доступа.
История
Система Memcached была разработана в 2003 году Брэдом Фицпатриком (Brad Fitzpatrick) для нужд популярного веб-сервиса LiveJournal. Основной проблемой, которую решал Фицпатрик, была высокая нагрузка на базу данных при каждом запросе к странице, особенно при посещении популярных сообществ и записей. Идея заключалась в том, чтобы кэшировать результаты выполнения запросов к базе данных (например, список друзей, текст записи, количество комментариев) в оперативной памяти, чтобы при повторном запросе не обращаться к базе данных.
Первая версия Memcached была написана на Perl, но быстро показала свою эффективность, и вскоре была переписана на C для повышения производительности. В 2004 году код был опубликован под лицензией BSD, что способствовало его широкому распространению. Ключевой вклад в развитие проекта внесли Анатолий Воробей (Anatoly Vorobey) и другие разработчики из сообщества LiveJournal.
С момента своего появления Memcached стал стандартом де-факто для кэширования в крупных веб-приложениях, таких как Facebook (продукт Meta, признанной экстремистской и запрещённой в РФ), Twitter, YouTube, Wikipedia и многих других. В 2009 году проект перешёл под эгиду организации Memcached.org, а в 2011 году был выпущен протокол двоичной связи (Binary Protocol), повысивший производительность и надёжность.
Архитектура и принцип работы
Memcached представляет собой клиент-серверное приложение. Серверная часть (демон) хранит данные в оперативной памяти и предоставляет доступ к ним по протоколу TCP или UDP. Клиентская часть — это библиотека, встраиваемая в приложение (на PHP, Python, Java, Ruby, C/C++ и др.), которая отправляет запросы на сервер.
Ключевые характеристики:
- Распределённость: Memcached не поддерживает кластеризацию или репликацию встроенными средствами. Распределение данных между несколькими серверами осуществляется на стороне клиента с помощью алгоритма консистентного хеширования (consistent hashing). Это позволяет легко масштабировать кэш горизонтально, добавляя новые серверы.
- Простота: Модель данных — только пары «ключ-значение». Ключ — строка (до 250 символов), значение — бинарные данные (до 1 МБ по умолчанию). Нет поддержки сложных структур данных (списков, множеств, хешей), как в Redis.
- Эфемерность: Данные хранятся только в оперативной памяти. При перезапуске сервера или исчерпании памяти все данные теряются. Это делает Memcached непригодным для долговременного хранения критически важных данных.
- Автоматическое вытеснение (eviction): Когда память, выделенная под кэш, заполняется, Memcached автоматически удаляет старые или редко используемые записи, чтобы освободить место для новых. Используется алгоритм LRU (Least Recently Used — наименее недавно использовавшийся).
- Тайм-ауты (TTL): Каждая запись может иметь время жизни (Time To Live), после которого она автоматически удаляется. Это предотвращает использование устаревших данных.
Протокол связи
Изначально использовался текстовый протокол (ASCII), основанный на командах, передаваемых по TCP. Позже был добавлен двоичный протокол (Binary Protocol), который обеспечивает более высокую производительность и безопасность (поддержка SASL-аутентификации). Основные команды:
set— запись значения по ключу.get— получение значения по ключу.delete— удаление записи.add— запись только если ключ не существует.replace— запись только если ключ существует.incr/decr— атомарное увеличение/уменьшение целочисленного значения.
Применение
Memcached широко применяется для кэширования результатов различных операций, которые выполняются часто и требуют значительных ресурсов:
- Кэширование результатов запросов к базе данных: Самый распространённый сценарий. После выполнения сложного SQL-запроса его результат сохраняется в Memcached. При повторном запросе данные извлекаются из кэша, минуя базу данных.
- Кэширование HTML-фрагментов: Целые блоки страницы (например, меню, список последних новостей, боковая панель) могут быть сохранены как строки и вставлены в страницу без повторной генерации.
- Кэширование сессий пользователей: Данные сессии (идентификатор пользователя, корзина покупок) могут храниться в Memcached, что позволяет масштабировать веб-серверы без необходимости синхронизировать файлы сессий.
- Кэширование объектов API: Результаты вызовов внешних API (например, данные о погоде, курсы валют) могут быть закэшированы для снижения задержек и нагрузки на внешние сервисы.
- Счётчики и ограничители частоты: Благодаря атомарным операциям
incr/decr, Memcached может использоваться для реализации счётчиков просмотров, голосований или ограничения частоты запросов (rate limiting).
Критика и ограничения
Несмотря на свою популярность, Memcached имеет ряд недостатков:
- Отсутствие персистентности: Данные хранятся только в оперативной памяти и теряются при перезапуске. Это делает его непригодным для хранения данных, которые должны быть восстановлены после сбоя.
- Отсутствие встроенной репликации и кластеризации: Распределение данных между серверами — задача клиента. При выходе из строя одного сервера все его данные теряются, и нагрузка перераспределяется на оставшиеся серверы, что может привести к временному снижению производительности.
- Ограниченная модель данных: Поддерживаются только простые пары «ключ-значение». Нет возможности работать со списками, множествами, хешами, что ограничивает его применение по сравнению с Redis.
- Уязвимость к атакам: По умолчанию Memcached не имеет аутентификации. В 2018 году была зафиксирована крупная атака с использованием уязвимости в конфигурации Memcached для усиления DDoS-атак (amplification attack). Злоумышленники отправляли запросы на серверы Memcached с подменённым IP-адресом жертвы, и серверы отправляли ответы, значительно превышающие размер запроса.
- Ограничение на размер значения: Максимальный размер значения по умолчанию составляет 1 МБ, что может быть недостаточно для кэширования больших объектов (например, изображений или больших HTML-фрагментов).
Сравнение с Redis
Memcached и Redis — два наиболее популярных решения для кэширования, но они имеют существенные различия. Redis, в отличие от Memcached, поддерживает:
- Персистентность данных на диск (RDB, AOF).
- Богатую модель данных (строки, списки, множества, хеши, битовые карты, геопространственные индексы).
- Встроенную репликацию (master-slave) и кластеризацию.
- Транзакции и Lua-скрипты.
- Публикацию/подписку (pub/sub).
Memcached, в свою очередь, проще, легче и быстрее для простых операций «ключ-значение» благодаря своей минималистичной архитектуре. Он лучше подходит для сценариев, где требуется максимальная производительность при минимальных накладных расходах, а сложные структуры данных не нужны.
Интересные факты
- Название «Memcached» является комбинацией слов «memory» (память) и «cache» (кэш).
- Исходный код Memcached написан на C и отличается высокой оптимизацией для работы с памятью.
- В 2011 году компания Facebook (организация Meta признана экстремистской и запрещена в РФ) разработала собственную модификацию Memcached, названную Mcrouter, которая добавляет поддержку кластеризации, репликации и более гибкого управления трафиком.
- Многие современные веб-фреймворки (например, Django, Ruby on Rails, Laravel) имеют встроенную поддержку Memcached в качестве бэкенда для кэширования.
Источники
- Официальная документация Memcached (memcached.org).
- Статья «Memcached: A Distributed Memory Object Caching System» (Brad Fitzpatrick, 2004).
- Книга «High Performance MySQL» (Baron Schwartz, Peter Zaitsev, Vadim Tkachenko).
- Документация по протоколу Memcached (Binary Protocol).
- Статья «Memcached DDoS amplification attack» (Cloudflare, 2018).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →