...

PHP OPcache explicado en profundidad: cómo sacar el máximo partido a su caché

PHP OPcache acelera mis scripts porque PHP utiliza el compilado código de bytes en la memoria y así ahorra el nuevo análisis. En esta guía, muestro cómo utilizo OPcache. configure, superviso y ajusto con precisión para que su aplicación responda de forma notablemente más rápida y absorba con tranquilidad los picos de carga.

Puntos centrales

  • Caché de código byte Reduce la carga de la CPU y la E/S.
  • Parámetros Cómo seleccionar específicamente memory_consumption y max_accelerated_files
  • Alrededores Configuración diferenciada: desarrollo, staging, producción
  • Monitoreo Para utilizar la tasa de visitas, la ocupación y los desalojos.
  • Despliegue y sincronizar correctamente el vaciado de la caché

Así funciona OPcache: código byte en lugar de recompilación

Con cada solicitud, PHP normalmente lee los archivos, analiza el código y crea código de bytes, que ejecuta el motor Zend. OPcache interviene precisamente aquí y almacena este código byte en la memoria compartida, de modo que las solicitudes posteriores se inician directamente desde la memoria. Esto reduce los ciclos de la CPU y los accesos a los archivos, lo que acorta notablemente los tiempos de respuesta. En configuraciones típicas, consigo ganancias de entre el 30 y el 70 %, dependiendo de la base de código y el perfil de tráfico. Es fundamental que la caché sea lo suficientemente grande y que los scripts más importantes permanezcan permanentemente en el Memoria permanecer.

Comprobar y activar OPcache en Linux, Windows y alojamiento compartido

Siempre empiezo echando un vistazo a phpinfo() y buscando „Zend». OPcache“ y claves como opcache.enable u opcache.memory_consumption. En Linux, activo el módulo mediante el paquete php-opcache y un archivo opcache.ini en el directorio conf.d. En Windows, basta con introducir zend_extension=opcache en el archivo php.ini y reiniciar el servidor web. En el alojamiento compartido, suelo activar OPcache a través de un archivo php.ini personalizado o del menú del cliente. En caso de cuellos de botella, también compruebo el Aumentar el límite de memoria PHP, para que OPcache y PHP-FPM tengan suficiente Recursos recibido.

Los interruptores más importantes explicados de forma comprensible

Con opcache.enable activo la caché para las solicitudes web, mientras que opcache.enable_cli controla el uso para los trabajos CLI, lo que resulta útil en las colas de trabajo. El núcleo lo constituye opcache.memory_consumption, que especifica la memoria compartida disponible en megabytes; si se calcula con demasiada precisión, se producen expulsiones y nuevas Compilaciones. opcache.max_accelerated_files define cuántos archivos pueden almacenarse en la caché; este valor debe superar de forma razonable el número de archivos del proyecto. Con opcache.validate_timestamps y opcache.revalidate_freq determino el nivel de rigor con el que OPcache comprueba los cambios en los archivos, desde muy dinámico (desarrollo) hasta muy moderado (producción con vaciado manual). Guardo los comentarios con opcache.save_comments=1, porque muchas herramientas en DocBlocks dependen.

Comparación de valores iniciales y perfiles

Para garantizar una puesta en marcha sin problemas, apuesto por perfiles claros para el desarrollo, la puesta en escena y la producción. De este modo, por un lado, obtengo ciclos de retroalimentación rápidos durante la codificación y, por otro, un rendimiento fiable en el funcionamiento en vivo. Es importante que compruebe y ajuste regularmente estos valores iniciales con métricas reales. En instalaciones de WordPress más grandes, planifico generosamente el almacenamiento y las entradas, porque los plugins y los temas ocupan mucho espacio. Archivos . La siguiente tabla resume los valores iniciales recomendados, que luego ajusto con precisión en función de la tasa de aciertos y las expulsiones.

Configuración Desarrollo Puesta en escena/Prueba Producción
opcache.enable 1 1 1
opcache.enable_cli 0 0-1 1 (en trabajos CLI)
opcache.consumo_memoria 128-256 MB 256-512 MB 256-512+ MB
opcache.interned_strings_buffer 16-32 MB 32-64 MB 16-64 MB
opcache.max_accelerated_files 8000-10 000 10 000-20 000 10 000-20 000+
opcache.validate_timestamps 1 1 0-1 (dependiendo de Deploy)
opcache.revalidate_freq 0-2 s 60-300 s 300+ s o 0 (con comprobación manual)
opcache.save_comments 1 1 1
opcache.fast_shutdown 1 1 1

Esta matriz es deliberadamente pragmática, ya que los proyectos reales crecen de forma muy diferente. Empiezo con estos valores y luego observo la tasa de aciertos, la parte ocupada de la memoria compartida y la aparición de expulsiones. Si hay signos de presión, primero aumento opcache.memory_consumption en pasos moderados. A continuación, ajusto opcache.max_accelerated_files hasta que el número de archivos encaja cómodamente. De este modo, el Cache Eficaz y las consultas siguen siendo igual de rápidas.

Configuración según el entorno: desarrollo, puesta en escena, producción

En el desarrollo, es importante obtener respuestas rápidas a los cambios en el código, por lo que establezco validate_timestamps=1 y revalidate_freq en un valor muy bajo o incluso en 0. En la fase de prueba, compruebo la carga realista y asigno una memoria generosa para que los resultados se acerquen al funcionamiento posterior en vivo. En producción, aumento la frecuencia de comprobación o desactivo completamente las marcas de tiempo si mi implementación vacía la caché de forma selectiva después. Para los trabajadores basados en CLI, activo enable_cli=1 para que los trabajos recurrentes también se ejecuten desde el Caché de código byte . De este modo, cada entorno genera exactamente el comportamiento que necesito, sin sorpresas en los tiempos de respuesta.

Configuración avanzada que a menudo marca la diferencia

Además de los parámetros básicos, hay interruptores con los que puedo aumentar la estabilidad y la seguridad y minimizar los efectos secundarios:

  • opcache.max_wasted_percentage: Define a partir de qué grado de fragmentación OPcache inicia una reconstrucción interna de la memoria. En bases de código muy variables, reduzco ligeramente el valor para tener menos memoria „recortada“.
  • opcache.force_restart_timeout: intervalo de tiempo en segundos tras el cual OPcache realiza un reinicio forzado cuando es necesario reiniciar, pero los procesos siguen activos. Esto evita estados de incertidumbre prolongados.
  • opcache.file_update_protection: ventana de protección en segundos durante la cual los archivos recién modificados no se almacenan inmediatamente en la caché. Esto ayuda a evitar archivos a medio escribir durante las implementaciones o en unidades de red.
  • opcache.restrict_api: Restringe qué scripts pueden llamar a opcache_reset() y a las funciones de estado. En producción, lo configuro de forma estricta para que solo los puntos finales de administración tengan acceso.
  • opcache.blacklist_filename: archivo en el que mantengo patrones que se excluyen de la caché (por ejemplo, generadores altamente dinámicos). Esto ahorra espacio para scripts más críticos.
  • opcache.validate_permission y opcache.validate_root: Activo cuando hay varios usuarios/chroots en juego. De esta forma, PHP evita que el código almacenado en caché de un contexto se utilice sin autorización en otro.
  • opcache.use_cwd y opcache.revalidate_path: controlan cómo OPcache identifica los scripts cuando las rutas se integran a través de diferentes directorios de trabajo/enlaces simbólicos. En el caso de los enlaces simbólicos de lanzamiento, compruebo estos valores específicamente para evitar cachés duplicadas.
  • opcache.cache_id: cuando varios hosts virtuales comparten el mismo SHM (algo poco habitual), separo las cachés de forma clara mediante un ID único.
  • opcache.optimization_level: Normalmente lo dejo en el valor predeterminado. Solo en casos extremos de depuración reduzco temporalmente las pasadas de optimización.

Precarga: mantener partes del código permanentemente en la memoria

Con PHP 7.4+, puedo cargar y vincular archivos centrales del marco de trabajo o del proyecto al iniciar el servidor mediante opcache.preload y opcache.preload_user. La ventaja: las clases están disponibles sin autoload hits y las rutas calientes están disponibles de inmediato. Algunas reglas prácticas:

  • La precarga resulta especialmente útil en bases de código grandes y estables (por ejemplo, Symfony, bibliotecas centrales propias). En WordPress la utilizo con cautela, ya que el núcleo y los plugins se actualizan con mayor frecuencia.
  • Un archivo de precarga contiene llamadas específicas a opcache_compile_file() o integra un autocargador que define clases. de antemano cargando.
  • Cada cambio de código en los archivos relevantes para la precarga requiere un reinicio de PHP-FPM para que se reconstruya la precarga. Lo integro en las implementaciones.
  • Mido el efecto por separado: no todos los códigos se benefician; la precarga consume memoria compartida adicional.

JIT y OPcache: ventajas, limitaciones, requisitos de memoria

Desde PHP 8 existe el compilador Just-In-Time (JIT), que se controla a través de OPcache (opcache.jit, opcache.jit_buffer_size). Para cargas de trabajo web típicas con carga de E/S y bases de datos, JIT suele aportar poco. En el caso de código con gran carga de CPU (por ejemplo, procesamiento de imágenes/datos), puede ser de gran ayuda. Yo procedo de la siguiente manera:

  • Activo JIT de forma conservadora y mido las métricas de usuarios reales, así como los perfiles de CPU. La activación ciega aumenta los requisitos de memoria y puede provocar casos extremos.
  • Dimensiono el búfer JIT en función de las rutas con mayor carga de CPU. Los búferes demasiado pequeños no aportan ningún valor añadido, mientras que los demasiado grandes desplazan el código byte.
  • Si la tasa de aciertos o la ocupación SHM se ven afectadas, doy prioridad a OPcache frente a JIT. La caché de código byte es la herramienta más importante para la mayoría de los sitios web.

Rutas de archivos, enlaces simbólicos y estrategias de implementación seguras

OPcache se basa en rutas. Por eso me centro en la estrategia de implementación:

  • Lanzamientos atómicos mediante enlaces simbólicos (por ejemplo, /releases/123 -> /current): limpio, pero cuidado con opcache.use_cwd y el comportamiento de realpath. Evito las cachés duplicadas haciendo que todos los trabajadores vean la misma ruta real de forma coherente.
  • Con validate_timestamps=0, la caché debe en todas partes Se vacían: después del cambio, vacío OPcache de forma selectiva en todos los hosts/pods y reinicio PHP-FPM de forma controlada.
  • Ajusto realpath_cache_size y realpath_cache_ttl con OPcache para que las búsquedas de archivos sigan siendo rápidas y estables.
  • En unidades de red (NFS/SMB), aumento file_update_protection y configuro las implementaciones para que los archivos se sustituyan de forma atómica.

Para reinicios muy rápidos, suelo utilizar un procedimiento de dos pasos: primero, calentamiento en segundo plano; luego, una recarga breve y coordinada de todos los trabajadores, para que el primer tráfico en vivo encuentre una caché ya calentada.

Caché de archivos, calentamiento y cebado

Además de la memoria compartida, OPcache puede escribir opcionalmente el código byte en el disco (opcache.file_cache). Esto resulta útil en situaciones especiales:

  • En entornos de contenedores, se puede utilizar una caché de archivos. entre Los reinicios de FPM reducen los tiempos de recompilación, siempre que el almacenamiento sea rápido.
  • Utilizo opcache.file_cache con precaución: en sistemas de archivos lentos o distribuidos, no aporta mucho y aumenta la complejidad.
  • opcache.file_cache_only es un caso especial para entornos sin SHM, poco habitual en configuraciones orientadas al rendimiento.

Para los calentamientos, me preparo pequeños „primers“:

  • Un script CLI llama a opcache_compile_file() para archivos calientes, por ejemplo, autocargadores, clases centrales del framework, ayudantes grandes.
  • Un rastreador visita las rutas principales (página de inicio, inicio de sesión, finalización de la compra) para que el código byte y las cachés posteriores estén listos a tiempo.
  • Programo los calentamientos para que estén listos justo antes de cambiar la versión.

OPcache en la pila: PHP-FPM, caché de objetos y caché de páginas

OPcache muestra su potencial sobre todo en combinación con PHP-FPM, una configuración de procesos limpia y capas de caché adicionales. En WordPress, lo combino con una caché de objetos (como Redis) y una caché de páginas para aliviar la carga de la base de datos y el renderizado. Para ello, presto atención a la Rendimiento de un solo subproceso, ya que las solicitudes PHP dependen en gran medida de los núcleos individuales de la CPU. Si, a pesar de ello, se produce presión, distribuyo la carga a través de PHP-FPM-Worker, sin seleccionar una memoria compartida de OPcache demasiado pequeña. Así utilizo el Pila por completo, en lugar de limitarse a girar un tornillo de ajuste.

Errores frecuentes y comprobaciones rápidas

Una caché demasiado pequeña provoca expulsiones, que puedo detectar en el estado de OPcache o en phpinfo(). Si esto ocurre, aumento gradualmente opcache.memory_consumption y compruebo el efecto a través de la tasa de aciertos. Si los archivos siguen sin acelerarse, establezco opcache.max_accelerated_files por encima de la cantidad real de archivos del proyecto. Si hay problemas de implementación, compruebo validate_timestamps: con 0, el bytecode antiguo permanece activo hasta que vacío explícitamente la caché. Herramientas como Doctrine requieren DocBlocks, por lo que dejo save_comments=1 para Error evitarlo mediante la falta de anotaciones.

Supervisar e interpretar OPcache

Mido la tasa de aciertos y aspiro a alcanzar valores cercanos al 100 % de forma permanente, para que las consultas casi siempre se inicien desde la caché. Además, observo la utilización de la memoria y el número de expulsiones para detectar atascos de forma temprana. Con opcache_get_status() creo pequeños paneles de control o alimento soluciones de monitorización existentes. De este modo, puedo ver inmediatamente las tendencias tras los lanzamientos o las actualizaciones de plugins. Con estas métricas, tomo decisiones fundamentadas. Decisiones y solo adapto lo que es realmente necesario.

Directrices concretas que han demostrado su eficacia:

  • Tasa de aciertos > 99 % bajo carga normal y máxima; por debajo de eso, compruebo la distribución de archivos y el calentamiento.
  • Porcentaje libre de SHM constante > 5-10 %; de lo contrario, escalo la memoria.
  • Evictions a lo largo del tiempo: las fluctuaciones puntuales tras la implementación son aceptables; las evictions continuas indican un dimensionamiento insuficiente o una fragmentación elevada.
  • Vigilar la memoria desperdiciada: si alcanza el límite, planificar una reconstrucción controlada de OPcache (por ejemplo, en ventanas de mantenimiento).

Ejemplo: configuración de WordPress con mucho tráfico

Para sitios web grandes de WordPress, elijo opcache.enable=1 y opcache.enable_cli=1, para que también se beneficien los trabajadores CLI. Me gusta establecer la memoria compartida en 384 MB o más cuando hay muchos plugins y un tema con muchas funciones. Aumento opcache.interned_strings_buffer a 64 MB, porque muchos nombres de clases y funciones se repiten en todas las solicitudes. Para entornos de rendimiento extremo, establezco validate_timestamps=0 y revalidate_freq=0, pero vacío la caché inmediatamente después de cada lanzamiento. Es importante diseñar las implementaciones de manera que no haya antiguos código de bytes permanece en circulación.

Flujo de trabajo práctico para ajustes y despliegues

Trabajo en ciclos fijos: medir, modificar, controlar. Primero, guardo valores de estado como la tasa de visitas, la ocupación y las expulsiones, luego ajusto un parámetro y vuelvo a medir. Antes de un lanzamiento, borro el OPcache de forma selectiva con las marcas de tiempo desactivadas, ya sea reiniciando PHP-FPM o mediante un pequeño script. A continuación, compruebo los picos de carga con tráfico real o benchmarks representativos. Si se produce un comportamiento anómalo, también compruebo Fragmentación de la memoria, porque reducen el espacio útil. Compartido La memoria se deteriora.

Algunas rutinas adicionales que han demostrado su eficacia en equipos:

  • Versiones de los cambios en los parámetros: opcache.ini en el repositorio, cambios mediante solicitud de extracción y registro de cambios.
  • Canary Deploys: primero, solo una parte de los trabajadores/pods carga nuevas versiones y crea una caché; luego, se realiza el despliegue en todas las instancias.
  • Interruptor de emergencia: un punto final de administración interno con acceso seguro que permite llamadas opcache_reset() y opcache_invalidate() específicas, combinadas con opcache.restrict_api.
  • Calcular el orden de magnitud: como regla general, calculo inicialmente entre 1 y 2 MB de OPcache por cada 100-200 archivos PHP y luego lo ajusto en función de las métricas reales. Para WordPress con muchos plugins, añado un margen.

Brevemente resumido

OPcache acelera las aplicaciones PHP al almacenar el código compilado código de bytes en la RAM. Con los ajustes adecuados para la memoria, el número de archivos y la estrategia de marcas de tiempo, se consiguen tiempos de respuesta constantemente cortos. Asegúrese de que todo esté sincronizado con PHP-FPM y otras capas de caché para que toda la pila funcione correctamente. Supervise la tasa de aciertos, la ocupación y las expulsiones para poder realizar ajustes específicos. De este modo, se asegurará un rendimiento alto y fiable. Plataforma Para cargas elevadas y crecimiento.

Artículos de actualidad