Я объясняю, как Поведение кэша запросов mysql в современных хостингах, почему MySQL 8.0 упразднил внутренний кэш запросов и как я могу стать заметно быстрее с помощью Redis или Memcached. Я покажу вам четкие рычаги для Кэширование запросов, Проверка, мониторинг и аппаратное обеспечение кэша, с помощью которого сайты чаще доставляются из кэша, а базы данных работают меньше.
Центральные пункты
- MySQL 8.0: Внутренний кэш запросов удален, внешние кэши заняты.
- In-MemoryЧастое считывание данных из оперативной памяти с молниеносной скоростью.
- ИнвалидизацияTTL, события и версионирование против устаревших данных.
- МониторингНастройка управления коэффициентом попадания, задержкой и вытеснениями.
- 300%Правильное кэширование снижает нагрузку и повышает производительность.
Краткое описание поведения кэша запросов в хостинге
Когда поступают запросы, я сначала проверяю, есть ли результат уже в Кэш находится. Если он находится там, я отвечаю без доступа к базе данных и экономлю время ожидания и процессорное время на Сервер базы данных. Если запись отсутствует, я создаю результат, сохраняю его в кэше и доставляю, чтобы следующий заход был быстрее и Время загрузки страницы уменьшается. Таким образом, я уменьшаю количество одинаковых запросов и снижаю нагрузку на сервер при повторяющихся обращениях к Популярное содержание. В хостингах с большим количеством однотипных запросов (стартовая страница, списки товаров, структуры меню) поведение кэша запросов приносит значительные преимущества. Ускорение.
От MySQL Query Cache к Redis/Memcached: современный путь
Старый кэш запросов MySQL замедлял многие операции записи, поэтому в MySQL 8.0 он был удален. Функция. Я полагаюсь на Redis или Memcached, потому что они позволяют мне использовать кэши независимо от База данных и может использовать гранулированные ключи, TTL и стратегии вытеснения. Это заметно снижает нагрузку на MySQL, поскольку запросы на чтение попадают на Кэш-память, в то время как MySQL концентрируется на реальных транзакциях. Я намеренно сохраняю ключи кэша небольшими, версифицирую их при внесении изменений и таким образом обеспечиваю высокий уровень безопасности. Скорость попадания. Такой подход обеспечивает последовательные ответы при высоком коэффициенте использования и масштабировании нескольких Рабочий или контейнеры.
Почему внутренний кэш запросов действительно был удален? Он блокировал высокопараллельные системы с глобальными блокировками, часто аннулировал целые области таблиц при внесении изменений и вызывал большие административные издержки при смешанных нагрузках чтения и записи. В результате чем больше обращений к записи, тем меньше польза - вплоть до сетевых тормозов. Поэтому современные кэши располагаются вне MySQL, используют изолированные TTL для каждого ключа, допускают горизонтальное масштабирование и могут быть развернуты независимо. Сам MySQL продолжает получать преимущества от буферного пула InnoDB, хороших индексов и подготовленных операторов - но кэширование результатов остается задачей прикладного уровня.
Понимание уровней кэша: в памяти, в базе данных, в приложении
Я различаю три уровня, чтобы Кэширование Кэш, связанный с приложением (Redis/Memcached), кэш, связанный с базой данных (например, буферный пул) и HTTP/обратный прокси-кэш. В непосредственной близости от приложения я кэширую полные результаты запросов или рендеринг Фрагменты, что обеспечивает наибольшую гибкость. Вблизи базы данных я получаю преимущества от оптимизированных индексов и буферного пула InnoDB, который хранит часто читаемые страницы в RAM держит. На уровне HTTP я минимизирую динамические вызовы, если содержимое действительно статический являются. Предлагаю краткий обзор тактик в компактном исполнении Руководство по стратегиям кэширования, что облегчает их использование в зависимости от сценария применения.
Модели кэширования в сравнении
Я выбираю паттерн в зависимости от риска, частоты изменений и необходимости постоянства:
- Кэш-сторона (ленивая загрузка): Приложение проверяет кэш, загружает из БД при промахе, записывает в кэш. Простота, гибкость, низкая сопряженность - но подверженность штампам, когда TTL истекает.
- Читать дальшеСлой кэша загружается автоматически из источника данных. Единое поведение, но дополнительные сложности в промежуточном слое.
- Write-Through: При каждой записи данные сначала попадают в кэш, а затем в БД. Очень последовательно, но путь записи длиннее.
- Запись на заднем фонеКэш принимает операции записи и асинхронно передается в БД. Быстро, но опасно в случае сбоя; используйте только при наличии четких гарантий.
- Stale-While-RevalidateПросроченные записи можно ненадолго вернуть как „старые“, пока фоновое задание заполняет их. Идеально подходит для борьбы с пиками нагрузки.
Проверка кэша без ошибок данных
Я планирую аннулирование кэша таким образом, чтобы текущие данные всегда имели приоритет и Скорость остается. Я устанавливаю время жизни (TTL) достаточно коротким, чтобы изменения отображались быстро, но достаточно длинным, чтобы коэффициент попадания остается высоким. Во время операций записи я удаляю определенные ключи (write-through/write-behind) или увеличиваю Версия в пространстве имен ключей, чтобы при последующих обращениях получался свежий набор данных. Для чувствительного содержимого (цены, акции, счета) я использую более короткие TTL или немедленное аннулирование после обновлений. Это предотвращает появление устаревших ответов и обеспечивает согласованность данных в распределенных центрах обработки данных. Системы.
Предотвращение наплыва кэша: stale-while-revalidate, блокировки и джиттер
Чтобы избежать „проблемы собачьей кучи“, я использую комбинированные механизмы: a Мягкий TTL, что позволяет несколько секунд „простоять“, пока однопролетный рабочий обновляет объект; короткий Mutex (например, через Redis SET NX + TTL), так что перезагружается только один процесс; и Джиттер на TTL (случайное отклонение), чтобы тысячи ключей не истекли одновременно. В случае ошибок в первоисточнике я разрешаю stale-if-error и защитить базу данных от лавин.
Размер, TTL и выселение: правильные регулировочные винты
Я выбираю размер кэша в соответствии с объемом данных, который стоит в RAM обманывать. Слишком маленький размер увеличивает количество промахов, слишком большой - тратит память, поэтому я постоянно измеряю и реагирую на Пики нагрузки. Для вытеснения я предпочитаю использовать LRU, если модели доступа цикличны, и переключаюсь на LFU для чистых моделей доступа. Давние фавориты. Я поддерживаю дифференцированные TTL: статическая навигация дольше, динамическая доступность продукта короче. В следующей таблице приведены типичные начальные значения, которые я затем уточняю с помощью мониторинга и подгоняю под реальные Использовать настраивать.
| Параметры | Назначение | начальное значение | Измеряемая переменная |
|---|---|---|---|
| Размер кэша | Бюджет оперативной памяти для кэша запросов или фрагментов | 5-15% оперативной памяти сервера | Выселения в минуту, использование оперативной памяти |
| Статический TTL | Меню, страницы категорий, частые объявления | 300-1800 секунд | Коэффициент попадания, требование к своевременности |
| TTL динамический | Цены, акции, персонализация | 10-120 секунд | Коэффициент ошибок, исправления |
| Выселение | LRU/LFU/FIFO для каждого шаблона доступа | LRU в стандартной комплектации | Частота пропусков, повторных обращений |
| Ключевая схема | Версионирование против устаревших данных | user:v1:queryhash | Отсутствие удара после развертывания |
Я также учитываю распределение размеров объектов и верхние пределы. Например, я сжимаю отдельные объекты размером более 512 КБ или разделяю их на страницы (пейджинг), чтобы вытеснения не вытесняли целые мегабайтные блоки. Различные кэши (например, „горячий“ и „холодный“) с разным размером не позволяют нескольким крупным объектам вытеснять множество мелких, часто читаемых записей.
Разработка и нормализация ключей
Хорошие ключи определяют частоту попаданий и возможность аннулирования. Я нормализую параметры запроса (сортировка, верхний/нижний регистр, значения по умолчанию), преобразую списки в каноническую последовательность и хэширую длинные параметры в Хэш запроса, чтобы ключи оставались короткими. Я четко разделяю грани в ключе: site:v3:en-EN:category:42:page:2:filter:abc123. Персонализация, клиент, валюта, локаль и категория устройства находятся на видном месте в пространстве имен. Чтобы избежать дублирования, я количественно оцениваю числовые параметры (например, округляю фильтры цен до значимых значений). Негативные кэши (например, „нет попадания“) с очень коротким TTL уменьшают количество обращений к БД при повторных попаданиях. Мисс-поиск.
Правильный выбор сериализации и сжатия
Я выбираю форматы в соответствии с интерфейсом и бюджетом процессора: JSON является универсальным и разборчивым, MessagePack или Protobuf экономить оперативную память/пропускную способность. Для больших объектов я использую LZ4 или Snappy для быстрого сжатия; Gzip - только если максимальный размер важнее процессора. Один Порог (например, от 4 до 8 КБ) предотвращает ненужное сжатие небольших данных. Я уделяю внимание стабильным схемам: если я добавляю поля, я увеличиваю Ключевая версия, чтобы старые парсеры не сломались.
Redis против memcached: Различия в работе
Memcached Благодаря простой архитектуре, многопоточности и Плиты для эффективного распределения. Это первый выбор для очень простых ключевых/значимых результатов с чрезвычайно высоким QPS без необходимости сохранения. Redis Предлагает структуры данных (хэши, наборы, сортированные наборы), тонкий контроль TTL, репликацию и возможность кластеризации. Redis идеально подходит для списков, таблиц лидеров, счетчиков и pub/sub. В качестве чистого кэша результатов я отключаю персистентность (или устанавливаю разреженные снимки) для экономии ввода-вывода. Я использую Трубопровод и MGET, чтобы сократить количество обходов, и выбрать политику вытеснения в соответствии с шаблоном доступа (allkeys-lfu для чистых, постоянных горячих ключей, volatile-lru для строгого использования TTL). Я распределяю горячие ключи по шардингам/кластерам или намеренно дублирую их несколько раз, чтобы сгладить узкие места.
Контроль и настройка во время работы
Я наблюдаю за коэффициент попадания, задержку на одну операцию с кэшем и скорость вытеснения, чтобы выявить узкие места. Если задержка увеличивается, я проверяю сетевые каналы, насыщенность процессора и сериализация объектов. Я уменьшаю большие объекты, сжимая их или разделяя на более мелкие, чтобы Память чтобы лучше использовать его. Если коэффициент попадания падает, я определяю недостающие клавиши и регулирую TTL или Ключевые схемы на. Настройка остается циклом измерения, выдвижения гипотез, адаптации, а затем Измерение.
Конкретные ключевые цифры помогают проанализировать причины: keypace_hits/misses, выселенные_ключи, восстановленный (Memcached), использованная_память и RSS-Отклонения для фрагментации, задержки P99 для каждой команды, уровень ошибок в сети и Slowlog-записи. Я обращаю внимание на непрерывные, не скачкообразные выселения, равномерное распределение размеров объектов и долю „несвежих обслуживаемых“. Если промах→db→set происходит чаще, чем планировалось, то либо TTL не соответствует действительности, либо ключи изменяются слишком широко (отсутствие нормализации).
Безопасность и высокая доступность
Я никогда не выставляю кэш-серверы на всеобщее обозрение, а привязываю их к внутренним интерфейсам/VPC, активирую ACL и, по возможности TLS. Я строго разделяю производственную, промежуточную и тестовую среды, чтобы ключи не сталкивались и данные не мигрировали. Я блокирую критические операции (FLUSH*) с помощью авторизаций. Для Отказоустойчивость Я использую репликацию и, в зависимости от технологии, автоматическое переключение (например, watchdog/sentinel/cluster). В качестве чистого кэша постоянство используется лишь в редких случаях или не используется вовсе - если кэш выходит из строя, приложение может работать медленнее, но корректно. Я ограничиваю команды, сканирующие все пространство ключей, и планирую резервное копирование только в тех случаях, когда кэш также используется. Источник истины является (редко).
WordPress и электронная коммерция: типичные модели и подводные камни
В WordPress я кэширую структуры меню, результаты запросов из WP_Query и важные Виджеты, пока я исключаю персонализированные части. Я слежу за тем, чтобы плагины не блокировали каждый запрос. Байпас, устанавливая сессии или постоянно меняя файлы cookie. Для магазинных систем я кэширую страницы категорий, списки бестселлеров и фильтрую результаты с помощью коротких TTL, в то время как корзины и страницы учетных записей остаются динамичными. Те, кто полагается на старый кэш запросов, часто ухудшают Производительность; здесь я объясняю, почему это так: Кэш запросов WordPress. Так я поддерживаю баланс между скоростью и правильным Персонализация.
Я также варьирую тайники в нужных местах: Валюта, Язык, Расположение и Группа клиентов влияют на цены, наличие и содержание. Я отделяю персонализацию от всего остального: страница берется из кэша, динамически перезагружаются только небольшие блоки (например, количество корзин). Для сильно изменяющихся фильтров (фасетов) я нормализую последовательность и создаю ключи страницы (page=1,2,...) вместо того, чтобы генерировать огромные, запутанные ключи. И я убеждаюсь, что ответы „Нет результата“ кэшируются на короткое время, чтобы уменьшить количество сканирований БД.
Планирование мощностей и модель затрат
Я заранее делаю приблизительный расчет: средний размер объекта × ожидаемое количество ключей + накладные расходы (10-30%) дают База оперативной памяти. Пример: 80 000 объектов по 6 КБ плюс 25% накладных расходов ≈ 600 МБ. Я планирую буферы на случай роста (например, 30-50%). Что касается пропускной способности, я оцениваю соотношение чтения и записи, целькоэффициент попадания (70-95%) и, как следствие, снижение нагрузки на базу данных. Если 60% предыдущих чтений БД обслуживаются из кэша, снижается не только нагрузка на процессор и IOPS, но и часто Репликация-Лаги. Я оцениваю сценарии: Сделать оперативную память дороже, сэкономить ядра БД - обычно инвестиции в оперативную память значительно выигрывают, поскольку обеспечивают более стабильное время отклика.
Буферный пул, план запросов и индексы InnoDB вместе
Я не оптимизирую по отдельности, а смотрю на кэш, Буферный пул, план запроса и индексы как единое целое. Хорошо рассчитанный буферный пул увеличивает количество обращений к InnoDB, сокращает ввод-вывод и усиливает каждый Кэш о себе. Я проверяю медленные запросы, создаю недостающие индексы и обновляю статистику, чтобы оптимизатор получал наилучшие результаты. План выбирает. Для получения более подробной информации об этих шагах см. Оптимизация буферного пула, которые я использую параллельно с кэшированием. Это увеличивает скорость: меньше операций ввода-вывода, больше обращений к оперативной памяти и более эффективное кэширование. Запросы.
На практике это означает, что я определяю размер буферного пула таким образом, чтобы „горячие“ страницы данных помещались в него без голода для операционной системы. Профили запросов показывают, не подрывают ли кэш полное сканирование таблицы, неоптимальные JOIN или отсутствующие покрывающие индексы. Я проверяю, не генерируют ли слишком широкие SELECT (лишние столбцы) большие объекты кэша, и уменьшаю их. Если запросы сильно различаются, я нормализую параметры в приложении или свожу их к нескольким многократно используемым вариантам.
Правильное использование аппаратных ресурсов
Я резервирую достаточно оперативной памяти для Redis/Memcached и для InnoDB Буфер пул, чтобы жесткие диски практически не блокировались. Я обращаю внимание на ядра процессора, чтобы приложение и сервер кэша могли работать одновременно. работа можно. Твердотельные накопители NVMe уменьшают остаточную задержку, если пропуск кэша становится проблемой. Память вступает в силу. Задержка в сети остается важной, поэтому я размещаю серверы кэша вблизи Приложение или на одном хосте. Такие решения часто позволяют сэкономить на хостинге в евро, поскольку при меньшем количестве ядер и более низком Загрузить достижение одинакового времени отклика.
Я также обращаю внимание на топологии NUMA и сокетов, при необходимости привязываю процессы к ядрам и использую короткие сетевые пути (или сокеты Unix на одном хосте). Для контейнерных установок я планирую „гарантированные“ ресурсы, чтобы не дросселировать кэш и обеспечить запас для пиковых нагрузок. Если горячие ключи неизбежны, я распределяю трафик между несколькими репликами или направляю его в наиболее локальный кэш, чтобы избежать межзональных задержек.
Развертывание, тесты и прогрев кэша
Я тестирую изменения в кэшировании с помощью профилей нагрузки, которые отражают реальные данные об использовании. В производстве я поэтапно внедряю изменения (Canary), наблюдаю за коэффициентом попадания, задержками и нагрузкой на БД и только потом увеличиваю TTL. Для развертывания я увеличиваю Ключевая версия и разогреваем верхние n-ключей (главная страница, топ-продавцы, важные категории). Фоновые задания целенаправленно заполняют страницы со списками и деталями, чтобы первые пользователи не несли расходов на прогрев. Я имитирую выселения (тестовое окружение) и напрягаю горячие пути, чтобы проверить защиту от набегов и джиттер.
Пошаговый план повышения производительности хостинга
Я начинаю с инвентаризации: медленно Запросы, файлы журналов, коэффициент попадания, вытеснения и профили CPU/RAM. Затем я определяю ключи кэша для наиболее важных страниц и создаю TTLs которые обеспечивают баланс между своевременностью и скоростью. Я включаю проверку изменений на основе записи или событий, чтобы Последовательность остается. Затем я снова провожу измерения, увеличиваю или уменьшаю TTL, регулирую размер кэша и удаляю Outliers с большими объектами. Наконец, я оттачиваю буферный пул, индексы и планы до тех пор, пока доставка страниц не станет заметной. жидкость бежит.
Краткое резюме
Я заменяю старый кэш запросов MySQL на Redis или Memcached, сознательно контролировать ключи, TTL и выселения и поддерживать надежность данных с помощью четкого аннулирования. В зависимости от приложения, я достигаю 200-300% Скорость, особенно когда поступает много одинаковых запросов. Мониторинг направляет мои решения: Если коэффициент попадания падает или задержка увеличивается, я корректирую размер, TTL и ключ на. Вместе с мощным буферным пулом InnoDB и чистыми индексами платформа лучше масштабируется и очень отзывчива. быстро. Если вы понимаете поведение кэша запросов mysql как целостной системы, вы экономите нагрузку на сервер, сокращаете расходы в евро и предоставляете пользователям четкий Пользовательский опыт.


