Zend OPcache: принцип работы, установка и настройка, значения php.ini и отключение JIT

Тестовая среда Семейство RHELAlmaLinux 9.8Учётная запись rootПроверено 2026-10-16

Zend OPcache — это расширение PHP, которое компилирует PHP-скрипты в байт-код и сохраняет его в разделяемой памяти, чтобы при повторном запуске того же файла компиляция пропускалась. Когда после включения JIT на сервере WordPress с PHP 8.3 на всех страницах появилась ошибка 500, сервер восстановили, оставив OPcache как есть и отключив только JIT.

Начиная с PHP 5.5 OPcache по умолчанию входит в поставку PHP.

1️⃣ Принцип работы Zend OPcache: кеширование байт-кода

При каждом запросе PHP-скрипт проходит три этапа: чтение файла, компиляцию в байт-код и выполнение. Когда OPcache работает, начиная со второго запроса к тому же файлу первые два этапа исчезают и остаётся только выполнение.

Разделяемая память, в которой OPcache хранит байт-код, используется всеми воркерами PHP-FPM совместно. Если к одному и тому же PHP-FPM подключено несколько сайтов, скрипты этих сайтов тоже хранятся в одной разделяемой памяти.

🧩 Обработка запросов без OPcache и с OPcache
Поясняющая схема
🧠 OPcache
📨 Запрос
🧰 PHP-FPM Воркеры
Воркер 1Первый запрос
Воркер 2Второй запрос
Воркер 3ожидание
Три этапа при каждом запросеПервый запрос · три этапаТолько выполнение→
⚙️ Обработка PHP-скрипта
Чтение файлаПропускается
→
Компиляция в байт-кодПропускается
→
ВыполнениеВыполнение PHP · запрос к базе данных
Разделяемая память не используется↓ Байт-код сохраняется↑ Используется байт-код из разделяемой памяти
🧠 Разделяемая память
Байт-код (скомпилированный PHP-код)
Используется всеми воркерами PHP-FPM совместно · одна разделяемая память даже при нескольких сайтах
Без OPcache PHP-скрипт при каждом запросе проходит три этапа: чтение файла, компиляцию в байт-код и выполнение.
Без OPcache второй запрос к тому же файлу тоже снова проходит три этапа: чтение файла, компиляцию в байт-код и выполнение.
Когда OPcache работает, первый запрос проходит три этапа, а затем сохраняет байт-код в разделяемой памяти.
Начиная со второго запроса к тому же файлу первые два этапа исчезают и остаётся только выполнение; разделяемая память используется всеми воркерами PHP-FPM совместно.

OPcache хранит скомпилированный PHP-код, поэтому выполнение PHP и запросы к базе данных происходят при каждом открытии страницы по-прежнему. Полностью пропускать выполнение PHP, сохраняя готовый HTML, — задача кеша страниц.

2️⃣ Проверка установки PHP OPcache

Установлен ли OPcache, можно проверить по последней строке вывода [php -v].

php -v
PHP 8.3.22 (cli) (built: Jun  3 2025 17:17:57) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.22, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.22, Copyright (c), by Zend Technologies

Если последней строки нет, установите его через dnf. Пакет обычно называется php-opcache; если из репозитория Remi сразу установили несколько версий PHP, к названию добавляется версия, например php83-php-opcache.

dnf -y install php-opcache

Пакет php-opcache из репозитория Remi загружает расширение строкой [zend_extension=opcache] в файле [/etc/php.d/10-opcache.ini]. После установки перезапустите PHP-FPM, чтобы OPcache применялся и к веб-запросам.

3️⃣ Настройка OPcache: значения php.ini

Настройки OPcache могут находиться в двух местах: в разделе [opcache] файла [/etc/php.ini] и в [/etc/php.d/10-opcache.ini].

php --ini
Configuration File (php.ini) Path: /etc
Loaded Configuration File:         /etc/php.ini
Scan for additional .ini files in: /etc/php.d
Additional .ini files parsed:      /etc/php.d/10-opcache.ini,

Файлы из папки php.d читаются после php.ini, поэтому если одна и та же директива указана в обоих местах, применяется значение из php.d.

В таблице ниже приведены значения PHP 8.3 по умолчанию и значения, применённые на проверенном сервере WordPress.

ПараметрЗначение по умолчанию в PHP 8.3Применённое значениеНазначение
opcache.enable11Использовать OPcache
opcache.enable_cli01Используется и в PHP из командной строки (wp-cli и другие)
opcache.memory_consumption1281024Разделяемая память для хранения байт-кода (МБ)
opcache.interned_strings_buffer816Память, в которой одинаковые строки хранятся один раз (МБ)
opcache.max_accelerated_files1000010000Верхний предел числа ключей, которые можно кешировать (реальный предел — простое число, не меньшее этого значения: 16229 для 10000)
opcache.max_wasted_percentage510Если память заканчивается, а потерянное место превышает эту долю, кеш очищается и запускается заново
opcache.validate_timestamps11Проверять, изменились ли файлы
opcache.revalidate_freq260Как часто проверяются изменения файлов (секунды)
opcache.jittracingdisableРежим JIT (с PHP 8.4 значение по умолчанию — disable)
opcache.jit_buffer_size00Память для JIT; при 0 JIT не работает (с PHP 8.4 значение по умолчанию — 64M)

Значения, внесённые в раздел [opcache] файла [/etc/php.ini], приведены ниже. Размер памяти подбирается по памяти сервера, а [opcache.max_accelerated_files] — по числу файлов WordPress.

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=1024
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.max_wasted_percentage=10
opcache.validate_timestamps=1
opcache.revalidate_freq=60

Если снова добавить в php.ini строку [zend_extension], расширение загрузится дважды и появится предупреждение [Cannot load Zend OPcache].

При [opcache.revalidate_freq], равном 60, после изменения PHP-файла старый код может выполняться ещё до 60 секунд.

На сервере WordPress, где PHP-файлы меняются часто, оставьте [opcache.validate_timestamps] равным 1, чтобы изменения файлов проверялись. Значение 0, которое документация Symfony рекомендует для рабочих серверов, подходит для серверов, где PHP-файлы меняются только при развёртывании новой версии.

Даже при [opcache.validate_timestamps], равном 0, WordPress сам очищает кеш изменённых файлов, когда вы обновляете его из админки. Но если обновлять через wp-cli или править файлы по SSH, старый код продолжит выполняться, пока PHP-FPM не будет перезапущен.

4️⃣ Отключение JIT в OPcache

JIT в PHP 8 ускоряет задачи с большим объёмом вычислений на процессоре, поэтому для приложения вроде WordPress, которое обрабатывает веб-запросы, эффект невелик. В замере на WordPress из PHP JIT RFC тоже прогон с включённым JIT обработал 326 запросов в секунду, а с выключенным — 315.

На сервере WordPress с PHP 8.3.22 JIT включили настройками [opcache.jit=tracing] и [opcache.jit_buffer_size=128M]. Через три дня, в день, когда наплыв запросов несколько раз перезапустил воркеры PHP-FPM, на всех страницах возникла ошибка 500.

В журнале ошибок осталось сообщение [Allowed memory size of 1073741824 bytes exhausted]. Следующая за ним запись [tried to allocate 4295229440 bytes] — это попытка выделить сразу 4 ГБ при лимите памяти PHP в 1 ГБ. После отключения JIT те же запросы стали обрабатываться нормально.

JIT отключается добавлением двух строк ниже в [/etc/php.d/10-opcache.ini]. Даже если настройки JIT остались в [/etc/php.ini], применяются значения из этого файла.

opcache.jit=disable
opcache.jit_buffer_size=0

В PHP 8.3 значение [opcache.jit_buffer_size] по умолчанию равно 0, поэтому без отдельной настройки JIT не работает. С PHP 8.4 значение [opcache.jit] по умолчанию тоже disable.

5️⃣ Применение и проверка настроек

Изменённые настройки применяются только после перезапуска PHP-FPM.

systemctl restart php-fpm

После перезапуска разделяемая память OPcache очищается и выделяется заново с новыми настройками.

php -i | grep -E '^opcache\.(enable|memory_consumption|revalidate_freq|validate_timestamps|jit) '
opcache.enable => On => On
opcache.jit => disable => disable
opcache.memory_consumption => 1024 => 1024
opcache.revalidate_freq => 60 => 60
opcache.validate_timestamps => On => On

Значения, которые выводит [php -i], — это настройки PHP из командной строки. В семействе RHEL PHP-FPM читает те же файлы [/etc/php.ini] и [/etc/php.d], поэтому значения совпадают.

Если вызвать [opcache_get_status()] из командной строки, число закешированных скриптов будет равно 0. PHP из командной строки при каждом запуске создаёт новую разделяемую память, поэтому использование PHP-FPM проверяют, поместив файл ниже в папку веб-документов и открыв его в браузере.

<?php
header('Content-Type: text/plain');
$s = opcache_get_status(false);
print_r($s['memory_usage']);
print_r($s['opcache_statistics']);
print_r($s['interned_strings_usage']);
var_dump($s['cache_full']);

Если [cache_full] равно true, разделяемая память или ключи заполнены. После проверки сразу удалите этот файл.

На сервере, где три сайта WordPress используют один PHP-FPM, из 1024 МБ разделяемой памяти было занято 317 МБ. Закешированных скриптов было от 3 366 до 4 222 на сайт, всего 11 358.

OPcache хранит скрипты по реальному пути, а для файлов, загруженных по относительному пути, создаёт ещё один ключ с добавленным рабочим каталогом, поэтому ключей становится больше, чем скриптов. При 11 358 скриптах ключи заполнили предел в 16 229, а в буфере строк размером 16 МБ тоже не осталось свободного места.

Когда ключи заполнены, новые скрипты не кешируются и компилируются при каждом запросе. За 5 минут 21 секунду число промахов кеша выросло с 18 408 до 36 027, а число закешированных скриптов осталось равным 11 358.

На сервере с несколькими WordPress или множеством плагинов задайте [opcache.max_accelerated_files] с запасом, чтобы предел ключей не заполнился. При 20000 реальный предел ключей составит 32 531. Если буфер строк заполнен, увеличьте и [opcache.interned_strings_buffer].

🔢 FAQ & рекомендуемые материалы

Эта настройка удалена в PHP 7.2, поэтому в PHP 8 она не влияет на работу, даже если осталась в php.ini. Если сервер унаследовал старые настройки, эту строку можно удалить.

OPcache хранит скомпилированный PHP-код, а объектный кеш Redis — результаты запросов к базе данных. Поскольку хранят они разное, их можно использовать вместе.

На сервере, который запускает PHP через PHP-FPM, OPcache работает внутри PHP-FPM, поэтому перезапускают только PHP-FPM. На сервере, где PHP работает как модуль Apache (mod_php), перезапустите Apache.

🔗 Рекомендуемые материалы
Следующий шаг Сравнение хостингов WordPress: TOP 7 на 2026 год Статья, сравнивающая цены и оценки скорости 7 хостингов — на случай, когда настройку OPcache и PHP-FPM вы поручаете управляемому хостингу, а не делаете сами. Читать → сравнение хостингов для WordPress

ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Докажите, что вы человек: 8   +   9   =