Top.Mail.Ru
OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Memcached vs Redis для кэша PHP: скорость, консистентность и простота

Какой кэш выбрать для PHP — Memcached или Redis? Разбираем производительность на чтение и запись, модель данных и памяти, консистентность, TTL и эвикшен, репликацию и эксплуатацию. Практические советы и анти‑паттерны.
Memcached vs Redis для кэша PHP: скорость, консистентность и простота

Спрос на быстрый кэш для PHP не снижается: рост трафика, требовательные фреймворки и микросервисы делают выбор между Memcached и Redis одним из самых частых вопросов для админов и разработчиков. Оба инструмента зрелые, быстрые и широко поддерживаются в PHP-клиентах, но сильно различаются по модели данных, поведению при исчерпании памяти, консистентности и операционной сложности. В этом обзоре я системно сравню Memcached и Redis именно с позиции кэша для PHP: что быстрее в типичных сценариях, где выше предсказуемость, где проще эксплуатация и когда переплата функциональностью действительно оправдана.

TL;DR: краткий итог

Если вам нужен простой, предсказуемый, максимально быстрый in-memory кэш ключ‑значение без персистентности — Memcached почти всегда проще и дешевле в сопровождении. Если вместе с кэшем нужны счетчики, очереди, транзакции, Lua-скрипты, структуры данных и отказоустойчивость с репликацией — Redis выигрывает по возможностям, часто с несущественной потерей скорости при грамотной настройке.

Модель данных и память

Memcached: компактность и минимализм

Memcached — это in-memory хранилище ключ‑значение с простыми типами: строка ключа и непрозрачное бинарное значение, TTL и флаги. Сильная сторона — малая издержка на метаданные и очень предсказуемое поведение памяти. Используется аллокатор со «слэбами»: память делится на классы фиксированного размера, что снижает фрагментацию и делает работу стабильной под высокой нагрузкой. Недостаток — «внутренние» потери при несоответствии размера значения ближайшему классу, но в целом это ожидаемая и контролируемая цена предсказуемости. По умолчанию максимальный размер одного элемента ограничен примерно 1 МБ, и это настраивается опцией -I (например, -I 5m).

Memcached хранит только «байтики» и не умеет сложные структуры. Это плюс для кэша PHP, где часто кладутся сериализованные объекты, JSON или отрендеренные куски HTML: минимум накладных расходов, минимум магии, максимум скорости.

Redis: структуры данных и их цена

Redis — не только кэш, а полноценное in-memory дата‑хранилище со строками, хешами, списками, наборами, отсортированными наборами, потоками и пр. За это платится памятью и сложностью: каждый ключ — запись в хеш-таблице, каждое значение — объект со своим заголовком, плюс внутренние структуры для контейнеров. Для очень маленьких значений накладные расходы могут составлять десятки байт на ключ, что увеличивает footprint по сравнению с Memcached при той же полезной нагрузке. Зато вы получаете атомарные инкременты, диапазонные операции, транзакции, Pub/Sub, гео‑операции и богатый набор инструментов для типовых задач веб‑приложений.

Скорость и латентность

Оба решения быстры и хорошо масштабируются по соединениям и RPS при корректном клиентском пуллинге и пайплайнинге. Но есть нюансы архитектуры:

  • Memcached использует многопоточную модель: несколько воркеров обслуживают запросы параллельно, эффективно используя многопроцессорные машины.
  • Redis традиционно однопоточный в ядре (в современных версиях есть I/O threads), что делает латентность очень предсказуемой и уменьшает накладные расходы на блокировки. Горизонтальный масштаб достигается шардированием или кластером.

В типичном сценарии кэша для PHP — множество коротких GET/SET до 1–4 КБ — оба инструмента выдадут сотни тысяч операций в секунду на современном CPU при работе по localhost и десятки-сотни тысяч по сети 1–10 Гбит. Разница в «сырых» цифрах часто нивелируется непрофильными задержками: сериализация в PHP, переключения контекста, GC, медленный бэкенд. Поэтому я рекомендую выбирать не по максимальному RPS бенчмарков, а по соответствию модели данных и эксплуатационной простоте.

Практический момент: и Memcached, и Redis хорошо реагируют на пайплайнинг (сгруппированные запросы), соединения держите пулами, не открывайте/закрывайте по запросу. Для PHP‑FPM это обычная настройка клиента: persistent connection и разумные таймауты. Избегайте «чата» (много мелких последовательных команд), лучше батчить операции, где это допустимо логикой.

Бенчмаркинг PHP‑клиентов кэша с пайплайнингом и метриками латентности.

Консистентность и конкурентный доступ

Оба решения обеспечивают атомарность отдельных команд. Но инструменты борьбы с гонками отличаются.

  • Memcached поддерживает механизм CAS (Compare-And-Set): вы читаете значение с токеном, и при записи указываете этот токен. Если кто‑то изменил запись раньше вас, операция не пройдет — хороший вариант для оптимистичной блокировки в простых сценариях.
  • Redis предлагает WATCH/MULTI/EXEC (оптимистичные транзакции), а также атомарные скрипты на Lua, где вся бизнес‑логика выполняется как единая операция. Плюс существуют команды инкремента/дека и условные установки ключей (SET NX, EX, PX), что облегчает реализации блокировок и счётчиков.

Если вам часто нужны атомарные инкременты, лимитирование, лотки задач, лидеры/локи — Redis естественно богаче. Если ваша модель «прочитал‑положил» со слабой согласованностью, Memcached навязывает меньше концепций и проще в поведении.

TTL, протухание и эвикшен

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

  • Memcached: TTL до 30 дней трактуется как относительный срок, а больше — как абсолютная метка времени Unix. Нулевой TTL означает «без истечения». Эвикшен — LRU в рамках слэб‑класса: наиболее давно неиспользуемые элементы в этом классе вытесняются первыми. Просроченные элементы могут удаляться лениво при обращении или активно при нехватке памяти. Важно понимать, что LRU внутри слэбов означает независимые «очереди» по размерным классам, что иногда даёт менее интуитивное распределение выживаемости ключей разных размеров.
  • Redis: TTL задаётся в секундах или миллисекундах, есть «ленивое» и «активное» истечение, плюс настраиваемые политики эвикшена при достижении лимита памяти: allkeys-lru, volatile-lru, allkeys-lfu, random и др. Это даёт гибкость, но требует осознанного выбора. Для кэша обычно хороши allkeys-lru или allkeys-lfu, если вы хотите учитывать частоту обращений.
maxmemory 2gb
maxmemory-policy allkeys-lfu
appendonly no

Практика показывает: при «узкой» памяти важнее правильно подобрать политику и TTL, чем спорить о разнице в микросекундах. Грамотная нормализация ключей (namespacing), единая сериализация, адекватные TTL под профиль обращений — залог высокой эффективности.

Персистентность, репликация и кластер

Ключевой водораздел между Memcached и Redis — персистентность и отказоустойчивость.

  • Memcached не хранит данные на диск и не реплицирует их сам по себе. Масштабирование и отказоустойчивость достигаются клиентским шардированием (consistent hashing) и избыточностью на уровне приложения: потеря узла означает потерю его ключей до прогрева. Плюсы — простота и отсутствие write‑amplification; минусы — холодные старты и отсутствие «сквозной» HA.
  • Redis поддерживает асинхронную репликацию, автоматическое переключение на реплику (через наблюдающий компонент), персистентность в виде снапшотов (RDB) и журнала (AOF) с гибкой политикой fsync. Redis Cluster разбивает ключевое пространство на слоты и распределяет их по шартам, обеспечивая горизонтальный рост и определённую степень отказоустойчивости. За это придется платить сложностью настройки и потреблением ресурсов на персистентность и репликацию.

Если вы хотите разворачивать и настраивать Memcached/Redis под свой профиль нагрузки, удобнее делать это на VDS. На некоторых планах виртуального хостинга сервисы могут быть уже доступны, но с ограничениями по конфигурации.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Безопасность и изоляция

Исторически обе системы страдали от «слишком открытых» инсталляций.

  • Memcached: не оставляйте порт доступным из внешней сети, отключайте UDP, используйте аутентификацию SASL и шифрование при транспортировке, если это требуется вашей политикой. В большинстве случаев разумно слушать только loopback или внутреннюю сеть и закрывать доступ фаерволом.
  • Redis: используйте bind к приватным интерфейсам, пароли/ACL, опционально TLS, подумайте о переименовании опасных команд. Не полагайтесь на «security through obscurity». Доступ — только с приложений, которым он действительно нужен.
memcached -m 1024 -I 5m -p 11211 -U 0 -l 127.0.0.1

Для проектов с многими сервисами имеет смысл разносить роли: отдельные инстансы под кэш, под очереди/счётчики и т.п., чтобы не мешать разным профилям нагрузки и политикам эвикшена.

Интеграция с PHP и фреймворками

В PHP оба инструмента доступны через зрелые расширения и клиенты. Переход между ними обычно упирается в конфиг и фабрики кэша.

  • Интерфейсы: PSR‑6/PSR‑16 поддерживаются в большинстве современных библиотек, что упрощает миграции. Ларгеры и симфониевские адаптеры позволяют быстро переключить бэкенд.
  • Сессии: у обоих решений есть хэндлеры сессий. Redis удобнее, если нужна персистентность и репликация; Memcached — если важнее «чистая» производительность и простота. Подробнее — в материале про Redis для сессий и объектного кэша: практический разбор.
  • Кэш объектов и шаблонов: Memcached даёт минимальную издержку при хранении сериализованных структур; Redis выигрывает, если вы активно используете инкременты, атомарные обновления и TTL‑политики уровня ключевого пространства.

Обратите внимание на сериализацию. Разные клиенты могут по‑разному кодировать данные (php‑serialize, igbinary, json). Выберите один формат во всём приложении, чтобы избежать коллизий и проблем при миграции.

Производительность на практике: на что смотреть в тестах

Синтетические бенчмарки полезны, если правильно настроены. Для честного сравнения:

  • Сравнивайте на одинаковом железе, с одинаковыми лимитами памяти и ядрами CPU.
  • Тестируйте рабочие распределения размеров: 200 B, 1 KB, 4 KB — а не только «идеальные» 32 B.
  • Проверяйте не только среднюю латентность, но и хвосты (p95/p99): прогнозируемость важнее в проде.
  • Задействуйте пайплайнинг и персистентные соединения, как в реальном приложении.
  • Для Redis протестируйте разные политики эвикшена; для Memcached — разные размеры слэб‑классов и лимит элемента через -I.
  • Смотрите на footprint памяти при одинаковом наборе ключей: у Redis он будет больше, но вопрос — на сколько в вашем профиле.

Дашборд мониторинга кэша: hit ratio и p99 латентность.

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

Простота эксплуатации

Memcached выигрывает в минимализме: меньше настроек, предсказуемая память, отсутствие персистентности и репликации упрощает операционку и обновления. Масштабирование — добавить ещё экземпляров и настроить шардирование на стороне клиента. Пошаговую настройку Memcached на VDS мы показывали в руководстве: Nginx + PHP‑FPM + Memcached.

Redis требует большего внимания: выбор между RDB/AOF или их сочетанием, настройки save/appendfsync, бэкап и ротация файлов, репликация и мониторинг задержек. Зато вы получаете возможности, которых у Memcached просто нет: отказоустойчивость с почти бесшовным переключением, богатые структуры данных и расширяемость.

Типичные сценарии выбора

Когда Memcached

  • Эфемерный кэш результатов запросов к базе и API, который можно безопасно восстановить после перезапуска.
  • Максимум throughput на простых GET/SET с небольшими объектами.
  • Минимизация накладных расходов памяти на ключ.
  • Простая эксплуатация без персистентности и репликации.

Когда Redis

  • Нужны счётчики, лимитеры, очереди задач, распределённые блокировки, транзакции.
  • Требуется персистентность и/или репликация, быстрое восстановление после отказа.
  • Хочется тонко управлять эвикшеном (LRU/LFU), TTL и уведомлениями о событиях ключей.
  • Планируется кластеризация и горизонтальный рост с прозрачным редистрибьютингом ключей.

Частые ошибки и анти‑паттерны

  • Открытый порт в Интернет: для обеих систем это критическая уязвимость. Доступ — только из приватной сети/loopback, плюс контроль фаерволом.
  • Слишком большие элементы: в Memcached упираетесь в лимит элемента (лечится -I, но будьте осторожны), в Redis — раздуваете память и рискуете по эвикшену.
  • Случайные TTL и отсутствие инвалидации: ведёт к «вечному» мусору и непредсказуемым промахам.
  • Разнородная сериализация: разные сервисы кладут одно и то же под одним ключом, но в разных форматах. Итог — падения при десериализации.
  • Отсутствие ключевых пространств (namespacing): коллизии между компонентами, сложность массовой инвалидации.
  • Игнорирование хвостов латентности: p99 важнее среднего в нагруженных PHP‑пуле.

Наблюдаемость и мониторинг

Для продуктивной эксплуатации следите за базовыми метриками:

  • Hit ratio и доля промахов по кэшу (коррелируйте с размером памяти и TTL).
  • Латентность команд (p50/p95/p99), количество активных соединений и ошибок.
  • Память: общий лимит, фрагментация, распределение по слэбам (Memcached) и overhead (Redis).
  • Эвикшены и истечения, частота перезаписей, размер «горячего» набора данных.
  • Для Redis: задержки репликации, размер AOF/RDB, время снапшотов и влияние на латентность.

Итоги

Memcached и Redis — сильные инструменты, но с разной философией. Memcached идеален как скоростной и понятный кэш для PHP, когда данные эфемерны, а простота и предсказуемость важнее всего. Redis — выбор для систем, где кэш — лишь часть задач хранения: нужны счётчики, очереди, транзакции, гибкие политики TTL/эвикшена и отказоустойчивость. В большинстве PHP‑проектов переход от одного к другому несложен: используйте абстракции кэша, продумайте формат сериализации и ключевые пространства, протестируйте реальные нагрузки и хвосты латентности. Тогда выбор станет очевидным именно для вашей архитектуры, а не «в среднем по бенчмаркам».

Поделиться статьей

Вам будет интересно

gVisor и Firecracker: обзор изоляции контейнеров для прод‑нагрузки OpenAI Статья написана AI Fastfox

gVisor и Firecracker: обзор изоляции контейнеров для прод‑нагрузки

gVisor и Firecracker — два разных подхода к усилению изоляции контейнеров. Разбираем, как они устроены, чем отличаются, какие риск ...
Odyssey vs PgBouncer: пул соединений PostgreSQL под веб‑нагрузкой OpenAI Статья написана AI Fastfox

Odyssey vs PgBouncer: пул соединений PostgreSQL под веб‑нагрузкой

Когда веб‑приложение открывает тысячи коротких соединений к PostgreSQL, без пула растёт латентность и падает TPS. В обзоре — PgBou ...
OpenLiteSpeed vs Nginx для PHP‑сайтов: производительность и совместимость OpenAI Статья написана AI Fastfox

OpenLiteSpeed vs Nginx для PHP‑сайтов: производительность и совместимость

Практичный обзор OpenLiteSpeed и Nginx для PHP‑проектов: где быстрее динамика, как работает кэш, поддержка .htaccess и CMS, особен ...