tuning too speed slow php optimization performance scalability kohana

too - speed up php



Optimización de sitios web basados en Kohana para velocidad y escalabilidad (6)

Un sitio que construí con Kohana recibió ayer una gran cantidad de tráfico, lo que me hizo dar un paso atrás y evaluar parte del diseño. Tengo curiosidad por saber cuáles son algunas de las técnicas estándar para optimizar las aplicaciones basadas en Kohana.

También estoy interesado en la evaluación comparativa. ¿Debo configurar Benchmark::start() y Benchmark::stop() para cada método de controlador para ver los tiempos de ejecución de todas las páginas, o puedo aplicar el benchmarking de forma global y rápida?

Usaré la biblioteca de caché más a tiempo, pero estoy abierto a más sugerencias ya que estoy seguro de que puedo hacer muchas cosas de las que simplemente no estoy consciente en este momento.


Código de perfil con XDebug .

Usa mucho almacenamiento en caché Si sus páginas son relativamente estáticas, entonces el proxy inverso podría ser la mejor manera de hacerlo.


Estoy totalmente de acuerdo con XDebug y las respuestas de almacenamiento en caché. No mire en la capa de Kohana para la optimización hasta que haya identificado su mayor velocidad y cuellos de botella en la escala.

XDebug te dirá si pasaste la mayor parte de tu tiempo e identificas los "puntos de acceso" en tu código. Mantenga esta información de perfil para que pueda basar y medir las mejoras de rendimiento.

Problema de ejemplo y solución: si encuentra que está construyendo objetos caros de la base de datos cada vez, eso realmente no cambia a menudo, entonces puede verlos en caché con memcached u otro mecanismo. Todas estas correcciones de rendimiento toman tiempo y le agregan complejidad a su sistema, por lo que debe estar seguro de los cuellos de botella antes de comenzar a corregirlos.


Estrictamente relacionado con Kohana (probablemente ya haya hecho esto, o no):

En modo de producción:

  1. Habilite el almacenamiento en caché interno (esto solo almacenará en caché los resultados de Kohana :: find_file, pero esto en realidad puede ayudar mucho.
  2. Deshabilitar Profiler

Solo mis 2 centavos :)


Kohana está fuera de la caja muy rápido, excepto por el uso de objetos de base de datos. Para citar a Zombor, "puedes reducir el uso de la memoria asegurándote de estar utilizando el objeto de resultados de la base de datos en lugar de las matrices de resultados". Esto hace una diferencia de rendimiento HUGEE en un sitio que se está criticando. No solo usa más memoria, sino que ralentiza la ejecución de los scripts.

Además, debe usar el almacenamiento en caché. Prefiero Memcache y lo uso en mis modelos de esta manera:

public function get($e_id) { $event_data = $this->cache->get(''event_get_''.$e_id.Kohana::config(''config.site_domain'')); if ($event_data === NULL) { $this->db_slave ->select(''e_id,e_name'') ->from(''Events'') ->where(''e_id'', $e_id); $result = $this->db_slave->get(); $event_data = ($result->count() ==1)? $result->current() : FALSE; $this->cache->set(''event_get_''.$e_id.Kohana::config(''config.site_domain''), $event_data, NULL, 300); // 5 minutes } return $event_data; }

Esto también aumentará dramáticamente el rendimiento. Las dos técnicas anteriores mejoraron el rendimiento de un sitio en un 80%.

Si proporcionó más información acerca de dónde cree que está el cuello de botella, estoy seguro de que podríamos dar algunas mejores ideas.

Consulte también yslow (google it) para conocer otros consejos de rendimiento.



Lo que diré en esta respuesta no es específico de Kohana, y probablemente se pueda aplicar a muchos proyectos de PHP.

Aquí hay algunos puntos que me vienen a la mente cuando hablo de rendimiento, escalabilidad, PHP, ...
He utilizado muchas de esas ideas mientras trabajaba en varios proyectos, y me ayudaron; por lo que probablemente podrían ayudar aquí también.


En primer lugar, cuando se trata de actuaciones, hay muchos aspectos / preguntas que deben tenerse en cuenta :

  • configuración del servidor (tanto Apache, PHP, MySQL, otros daemons posibles, y sistema) ; es posible que obtenga más ayuda sobre eso en ServerFault , supongo,
  • Código PHP,
  • Consultas de bases de datos
  • ¿Utilizas o no tu servidor web?
  • ¿Puedes usar cualquier tipo de mecanismo de caché? ¿O necesita siempre más datos actualizados en el sitio web?


Usando un proxy inverso

Lo primero que podría ser realmente útil es usar un proxy inverso , como varnish , en frente de su servidor web: deje que cachee tantas cosas como sea posible , de modo que solo las solicitudes que realmente necesiten cálculos de PHP / MySQL (y, por supuesto, algún otro las solicitudes, cuando no están en la memoria caché del proxy) llegan a Apache / PHP / MySQL.

  • En primer lugar, su CSS / Javascript / Images , bueno, todo lo que es estático, probablemente no necesite ser servido por Apache.
    • Por lo tanto, puede tener el caché de proxy inverso todos esos.
    • Servir esos archivos estáticos no es gran cosa para Apache, pero cuanto menos tenga que funcionar para ellos, más podrá hacer con PHP.
    • Recuerde: Apache solo puede server una cantidad finita y limitada de solicitudes a la vez.
  • Luego, haga que el proxy inverso sirva tantas páginas PHP como sea posible de la memoria caché: es probable que haya algunas páginas que no cambian con tanta frecuencia y que se pueden servir desde la memoria caché. En lugar de usar un caché basado en PHP, ¿por qué no dejar que otro servidor más liviano sirva esos (y buscarlos del servidor PHP de vez en cuando, para que estén siempre actualizados) ?
    • Por ejemplo, si tiene algunos canales RSS (generalmente los olvidamos cuando tratamos de optimizar el rendimiento) que se solicitan con mucha frecuencia , tenerlos en caché durante un par de minutos podría ahorrar cientos de miles de solicitudes a Apache + PHP. + MySQL!
    • Lo mismo para las páginas más visitadas de su sitio, si no cambian durante al menos un par de minutos (por ejemplo, ¿página de inicio?) , Entonces, no es necesario desperdiciar la CPU volviéndolas a generar cada vez que un usuario las solicite.
  • Tal vez haya una diferencia entre las páginas servidas para usuarios anónimos (la misma página para todos los usuarios anónimos) y las páginas servidas para los usuarios identificados ("Hola, señor X, tienes nuevos mensajes", por ejemplo) .
    • Si es así, probablemente pueda configurar el proxy inverso para almacenar en caché la página que se sirve para los usuarios anónimos (en función de una cookie, como la cookie de sesión, por lo general)
    • Significará que Apache + PHP tiene menos con qué lidiar: solo usuarios identificados, que podrían ser solo una pequeña parte de sus usuarios.

Sobre el uso de un proxy inverso como caché , para una aplicación PHP, puede, por ejemplo, echar un vistazo a los resultados de Benchmark. Mostrar un aumento del 400% -700% en las capacidades del servidor con APC y Squid Cache .
(Sí, están usando Squid, y yo estaba hablando de barniz; esa es solo otra posibilidad ^^ El barniz es más reciente, pero más dedicado al almacenamiento en caché)

Si lo haces lo suficientemente bien y logras dejar de volver a generar demasiadas páginas una y otra vez, tal vez ni siquiera tengas que optimizar ninguno de tus códigos ;-)
Al menos, tal vez no con ningún tipo de apuro ... Y siempre es mejor realizar optimizaciones cuando no está bajo demasiada presión ...


Como nota al margen: estás diciendo en el OP:

Un sitio que construí con Kohana recibió ayer una enorme cantidad de tráfico,

Este es el tipo de situación repentina donde un proxy inverso puede literalmente salvar el día , si su sitio web puede tratar de no estar actualizado por el segundo:

  • instálalo, configúralo, déjalo siempre , cada día normal, ejecuta:
    • Configurarlo para no mantener páginas PHP en caché; o solo por una corta duración; de esta manera, siempre tienes datos actualizados
  • Y, el día que tome un efecto slashdot o digg:
    • Configure el proxy inverso para mantener las páginas PHP en caché; o por un período de tiempo más largo; ¡quizás tus páginas no estén actualizadas por segundo, pero permitirán que tu sitio web sobreviva al efecto digg!

Acerca de eso, ¿cómo puedo detectar y sobrevivir siendo "Slashdotted"? podría ser una lectura interesante.


En el lado de PHP de las cosas:

Antes que nada: ¿estás usando una versión reciente de PHP ? Hay mejoras regulares en la velocidad, con nuevas versiones ;-)
Por ejemplo, eche un vistazo a Benchmark of PHP Branches 3.0 a 5.3-CVS .

Tenga en cuenta que el rendimiento es una buena razón para usar PHP 5.3 ( hice algunos benchmarks (en francés) , y los resultados son geniales) ...
Otra buena razón es, por supuesto, que PHP 5.2 ha llegado al final de su vida y ya no se mantiene.

¿Estás usando algún caché de código de operación?

  • Estoy pensando en APC - Alternative PHP Cache , por ejemplo ( pecl , manual ) , que es la solución que he visto más utilizada, y que se usa en todos los servidores en los que he trabajado.
  • Realmente puede reducir mucho la carga de CPU de un servidor, en algunos casos (¡he visto que la carga de CPU en algunos servidores pasa del 80% al 40%, simplemente instalando APC y activando su funcionalidad de caché de código de operación!)
  • Básicamente, la ejecución de un script PHP va en dos pasos:
    • Compilación del código fuente de PHP para códigos de operación (tipo de equivalente del código byte de JAVA)
    • Ejecución de esos códigos de operación
    • APC mantiene esos en la memoria, por lo que hay menos trabajo por hacer cada vez que se ejecuta un script / archivo PHP: solo busca los códigos de operación de la RAM y ejecútalos.
  • Es posible que tenga que echar un vistazo a las opciones de configuración de APC , por cierto
    • hay bastantes de ellos, y algunos pueden tener un gran impacto en la velocidad / carga de la CPU / facilidad de uso para usted
    • Por ejemplo, deshabilitar [apc.stat](http://php.net/manual/en/apc.configuration.php#ini.apc.stat) puede ser bueno para la carga del sistema; pero significa que las modificaciones realizadas a los archivos PHP no se tendrán en cuenta a menos que vacíe todo el código de operación-caché; sobre eso, para más detalles, ver por ejemplo A stat () O No a stat ()?


Usar caché para datos

Tanto como sea posible, es mejor evitar hacer lo mismo una y otra vez .

Lo principal que estoy pensando es, por supuesto, las consultas SQL: muchas de sus páginas probablemente hagan las mismas consultas, y los resultados de algunas de ellas probablemente sean casi siempre las mismas ... lo que significa muchas consultas "inútiles" hecho a la base de datos, que tiene que pasar tiempo sirviendo los mismos datos una y otra vez.
Por supuesto, esto es cierto para otras cosas, como llamadas a servicios web, búsqueda de información de otros sitios web, cálculos pesados, ...

Puede ser muy interesante para ti identificar:

  • Qué consultas se ejecutan muchas veces, siempre devolviendo los mismos datos
  • ¿Qué otros cálculos (pesados) se realizan mucho tiempo, siempre devolviendo el mismo resultado?

Y almacene estos datos / resultados en algún tipo de caché, para que sean más fáciles de obtener, más rápidos , y no tiene que ir a su servidor SQL por "nada".

Los grandes mecanismos de almacenamiento en caché son, por ejemplo:

  • APC : además de la caché de código de operación que mencioné anteriormente, te permite almacenar datos en la memoria,
  • Y / o memcached ( ver también ) , que es muy útil si literalmente tienes muchos datos y / o estás usando varios servidores , a medida que se distribuyen.
  • por supuesto, puedes pensar en archivos; y probablemente muchas otras ideas.

Estoy bastante seguro de que su marco viene con algunas cosas relacionadas con la caché; probablemente ya lo sepas, como dijiste "Usaré la biblioteca de caché más a tiempo" en el OP ;-)


Perfilado

Ahora, una buena cosa sería usar la extensión Xdebug para perfilar su aplicación : a menudo permite encontrar un par de puntos débiles con bastante facilidad, al menos, si hay alguna función que lleve mucho tiempo.

Configurado correctamente , generará perfiles de archivos que se pueden analizar con algunas herramientas gráficas, tales como:

  • KCachegrind : mi favorito, pero solo funciona en Linux / KDE
  • Wincachegrind para Windows; hace un poco menos cosas que KCacheGrind, desafortunadamente - no muestra callgraphs, típicamente.
  • Webgrind que se ejecuta en un servidor web PHP, funciona en cualquier lugar, pero probablemente tenga menos funciones.

Por ejemplo, aquí hay un par de capturas de pantalla de KCacheGrind:

KCacheGrind: pantalla principal http://extern.pascal-martin.fr/so/kcachegrind/kcachegrind-1-small.png KCacheGrind: Callgraph exportado como una imagen http://extern.pascal-martin.fr/so/kcachegrind/ kcachegrind-2-small.png

(Por cierto, el callgraph presentado en la segunda captura de pantalla es algo que ni WinCacheGrind ni Webgrind pueden hacer, si mal no recuerdo ^^)


(Gracias @Mikushi por el comentario) Otra posibilidad que no he usado mucho es la extensión xhprof : también ayuda con la creación de perfiles, puede generar callgraphs, pero es más liviana que Xdebug, lo que significa que debe poder instalarla en un servidor de producción

Debería poder usarlo junto a XHGui , lo que ayudará a la visualización de los datos.


En el lado SQL de las cosas:

Ahora que hemos hablado un poco sobre PHP, tenga en cuenta que es más que posible que su cuello de botella no sea del lado de PHP , sino de la base de datos uno ...

Al menos dos o tres cosas, aquí:

  • Debes determinar:
    • ¿Cuáles son las consultas más frecuentes que hace su aplicación?
    • Si están optimizados (usando los índices correctos , ¿sobre todo?) , Usando la instrucción EXPLAIN , si está utilizando MySQL
    • si podría almacenar en caché algunas de estas consultas (vea lo que dije antes)
  • ¿Está bien configurado tu MySQL? No sé mucho sobre eso, pero hay algunas opciones de configuración que pueden tener algún impacto.

Aún así, las dos cosas más importantes son:

  • No vaya a la base de datos si no necesita: almacenar en caché todo lo que pueda .
  • Cuando tenga que ir al DB, use consultas eficientes: use índices; y perfil!


¿Y ahora qué?

Si todavía estás leyendo, ¿qué más se puede optimizar?

Bueno, todavía hay espacio para mejoras ... Un par de ideas orientadas a la arquitectura podrían ser:

  • Cambiar a una arquitectura de n niveles:
    • Ponga MySQL en otro servidor (2 niveles: uno para PHP, el otro para MySQL)
    • Use varios servidores PHP (y equilibre la carga de los usuarios entre ellos)
    • Use otras máquinas para archivos estáticos, con un servidor web más liviano, como:
    • Use varios servidores para MySQL, varios servidores para PHP y varios proxies inversos frente a aquellos
    • Por supuesto: instale memcached daemons en cualquier servidor que tenga cualquier cantidad de RAM libre, y úselos para almacenar tanto como pueda / tenga sentido.
  • Utiliza algo "más eficiente" que Apache?
    • Cada vez escucho más sobre nginx , que se supone que es excelente cuando se trata de PHP y sitios web de alto volumen; Nunca lo he usado, pero puede encontrar algunos artículos interesantes sobre él en la red;

Bueno, tal vez algunas de esas ideas son un poco exageradas en su situación ^^
Pero, aún así ... ¿Por qué no estudiarlos un poco, por si acaso? ;-)


¿Y qué hay de Kohana?

Su pregunta inicial fue sobre la optimización de una aplicación que utiliza Kohana ... Bueno, he publicado algunas ideas que son ciertas para cualquier aplicación de PHP ... Lo que significa que son verdad para Kohana también ;-)
(Incluso si no es específico para eso ^^)

Yo dije: use caché; Kohana parece ser compatible con algunas cosas del almacenamiento en caché (Usted mismo lo mencionó, así que no hay nada nuevo aquí ...)
Si hay algo que se puede hacer rápidamente, pruébalo ;-)

También dije que no debes hacer nada que no sea necesario; ¿hay algo habilitado por defecto en Kohana que no necesites?
Al navegar por la red, parece que al menos hay algo sobre el filtrado XSS; ¿lo necesitas?

Aún así, aquí hay un par de enlaces que pueden ser útiles:


¿Conclusión?

Y, para concluir, un pensamiento simple:

  • ¿Cuánto le costará a su compañía pagarle 5 días? - considerando que es una cantidad de tiempo razonable para hacer algunas optimizaciones excelentes
  • ¿Cuánto le costará a su empresa comprar (pagar?) Un segundo servidor y su mantenimiento?
  • ¿Qué pasa si tienes que escalar más grande?
    • ¿Cuánto costará gastar 10 días? ¿Más? optimizar cada bit de su aplicación?
    • ¿Y cuánto por un par de servidores más?

No digo que no deberías optimizar: ¡definitivamente deberías!
Pero opte por optimizaciones "rápidas" que le darán grandes recompensas primero: el uso de un caché de opcode podría ayudarlo a obtener entre un 10 y un 50 por ciento de la carga de CPU de su servidor ... Y lleva solo unos minutos configurarlo; ) Por otro lado, pasar 3 días por 2 por ciento ...

Ah, y, btw: antes de hacer nada: ponga algo de monitoreo en su lugar , para que sepa qué mejoras se han realizado y cómo.
Sin supervisión, no tendrá idea del efecto de lo que hizo ... ¡Ni siquiera si es una optimización real o no!

Por ejemplo, podrías usar algo como RRDtool + cacti .
Y mostrarle a tu jefe algunos buenos gráficos con una caída de carga de CPU del 40% siempre es genial ;-)


De todos modos, y para concluir realmente: ¡diviértete!
(Sí, optimizar es divertido!)
(Ergh, no pensé que escribiría tanto ... Espero que al menos algunas partes de esto sean útiles ... Y debería recordar esta respuesta: podría ser útil en otras ocasiones ...)