Кэш блоков начинался там, где WordPress предлагает хранить временные данные, — во временных записях в таблице опций. Для сотни ячеек это нормально. Для десятков тысяч — нет: на крупном каталоге таблица опций стала 88 % всей базы.
Это четырнадцатая часть цикла «Кэш фрагментов и Redis».
Что было в базе
- файл таблицы опций — 3,24 ГБ, из них полезных данных 739 МБ, остальное — пустота от удалённых записей;
- мёртвых ячеек — 8016 из 9468;
- рост — около 2 ГБ в неделю.
Промежуточная чистка
До переезда базу надо было спасти. Мёртвые ячейки удалялись пачками по 400 и только после окна догрева после выката — и только записи, записанные до текущей версии кода. Строк стало 19 761 → 12 058. Затем OPTIMIZE TABLE — онлайн, за 9 секунд: 3236 → 516 МБ, вся база 3,7 ГБ → 1006 МБ.
Ложный диагноз: «таблица 800 МБ при буфере базы 128 МБ — надо поднять буфер». Мы проверили: попаданий в память было 99,979 %. Буфер ни при чём, поднимать его — тратить память впустую.
Redis: как настроить
| Настройка | Значение | Почему |
|---|---|---|
maxmemory-policy | noeviction | вытеснение ключа — это MISS; лучше отказ записи, который видно |
appendonly | yes | кэш переживает перезапуск контейнера |
| сеть | внутренняя | Redis не должен быть доступен снаружи |
| имя ключа | frag:{версия кода}:{ключ} | старое поколение отделено от нового |
Сжатие
HTML жмётся отлично. Значения сжимаются перед записью: 35 973 КБ → 1301 КБ, в 27,6 раза.
function frag_store_set(string $key, array $cell): void {
$redis = frag_redis();
if (!$redis) {
set_transient('frag_' . md5($key), $cell, WEEK_IN_SECONDS); // откат
return;
}
$redis->setex(
'frag:' . frag_code_version() . ':' . $key,
WEEK_IN_SECONDS,
gzcompress(serialize($cell), 6)
);
}
Откат на временные записи
Если Redis недоступен, кэш не должен исчезнуть — он откатывается на временные записи в базе. Проверять это надо по-настоящему: погасить контейнер Redis и убедиться, что сайт работает и блоки отдаются.
Реестр без потолка
Реестр ячеек в опции упирался в потолок в 4000 записей. В Redis он стал хэшем плюс отсортированным множеством по времени обращения — потолок снят. Сторож проверяет наличие ячеек одним конвейером команд EXISTS.
Проверьте виджеты. Виджет мониторинга после переезда продолжал читать старую опцию и показывал 4000 ячеек при реальных 31 574 — врал в 8 раз.
Таблица опций WordPress раздулась до гигабайтов?
Пришлите адрес — помогу разобраться, что там лежит, и перенести кэш в Redis.
// загружаю комментарии…