Tácticas para usar PHP en un sitio de alta carga

242

Antes de contestar esto, nunca he desarrollado algo lo suficientemente popular como para alcanzar altas cargas de servidor. Trátame como (suspiro) un alienígena que acaba de aterrizar en el planeta, aunque conozca PHP y algunas técnicas de optimización.


Estoy desarrollando una herramienta en PHP que podría llegar a muchos usuarios, si funciona correctamente. Sin embargo, si bien soy completamente capaz de desarrollar el programa, no tengo ni idea cuando se trata de hacer algo que pueda manejar un tráfico enorme. Aquí hay algunas preguntas al respecto (siéntase libre de convertir esta pregunta en un hilo de recursos también).

Bases de datos

Por el momento planeo usar las características de MySQLi en PHP5. Sin embargo, ¿cómo debo configurar las bases de datos en relación con los usuarios y el contenido? ¿Realmente necesito múltiples bases de datos? Por el momento, todo está mezclado en una base de datos, aunque he estado considerando difundir los datos de los usuarios a uno, el contenido real a otro y finalmente el contenido del sitio central (maestros de plantillas, etc.) a otro. Mi razonamiento detrás de esto es que enviar consultas a diferentes bases de datos facilitará la carga en ellas como una base de datos = 3 fuentes de carga. ¿Esto también sería efectivo si todos estuvieran en el mismo servidor?

Almacenamiento en caché

Tengo un sistema de plantillas que se usa para construir las páginas e intercambiar variables. Las plantillas maestras se almacenan en la base de datos y cada vez que se llama a una plantilla se llama a la copia en caché (un documento html). Por el momento tengo dos tipos de variables en estas plantillas: una variable estática y una variable dinámica. Los vars estáticos suelen ser cosas como nombres de páginas, el nombre del sitio, cosas que no cambian con frecuencia; Las variables dinámicas son cosas que cambian en cada carga de página.

Mi pregunta sobre esto:

Digamos que tengo comentarios sobre diferentes artículos. Cuál es una mejor solución: almacenar la plantilla de comentario simple y presentar comentarios (de una llamada de DB) cada vez que se carga la página o almacenar una copia en caché de la página de comentarios como una página html, cada vez que se agrega / edita / elimina un comentario Se recupera la página.

Finalmente

¿Alguien tiene algún consejo / puntero para ejecutar un sitio de alta carga en PHP? Estoy bastante seguro de que es un lenguaje viable de usar: Facebook y Yahoo! darle una gran prioridad, pero ¿hay alguna experiencia que deba tener en cuenta?

Ross
fuente
99
3.5 años después y ni siquiera puedo recordar en qué estaba trabajando, me gustaría saber lo que también pensé que era genial :)
Ross
8
Que esto sea una lección sobre la optimización prematura :)
Rimu Atkinson

Respuestas:

89

No hay dos sitios iguales. Realmente necesita obtener una herramienta como jmeter y benchmark para ver dónde estarán sus puntos problemáticos. Puede pasar mucho tiempo adivinando y mejorando, pero no verá resultados reales hasta que mida y compare sus cambios.

Por ejemplo, durante muchos años, el caché de consultas MySQL fue la solución a todos nuestros problemas de rendimiento. Si su sitio era lento, los expertos de MySQL sugirieron activar el caché de consultas. Resulta que si tienes una alta carga de escritura, el caché es realmente paralizante. Si lo encendiste sin probar, nunca lo sabrías.

Y no olvides que nunca has terminado de escalar. Un sitio que maneja 10req / s necesitará cambios para soportar 1000req / s. Y si tiene la suficiente suerte como para admitir 10,000 req / s, su arquitectura probablemente también se verá completamente diferente.

Bases de datos

  • No use MySQLi: PDO es la capa de acceso a la base de datos OO 'moderna'. La característica más importante para usar son los marcadores de posición en sus consultas. Es lo suficientemente inteligente como para usar preparaciones del lado del servidor y otras optimizaciones para usted también.
  • Probablemente no desee dividir su base de datos en este momento. Si encuentra que una base de datos no está cortando, existen varias técnicas para escalar, dependiendo de su aplicación. La replicación a servidores adicionales generalmente funciona bien si tiene más lecturas que escrituras. Sharding es una técnica para dividir sus datos en muchas máquinas.

Almacenamiento en caché

  • Probablemente no desee almacenar en caché en su base de datos. La base de datos suele ser su cuello de botella, por lo que agregarle más IO suele ser algo malo. Hay varios cachés PHP por ahí que logran cosas similares como APC y Zend.
  • Mida su sistema con el almacenamiento en caché activado y desactivado. Apuesto a que su caché es más pesado que servir las páginas directamente.
  • Si toma mucho tiempo construir sus comentarios y datos del artículo desde la base de datos, integre memcache en su sistema. Puede almacenar en caché los resultados de la consulta y almacenarlos en una instancia de memcached. Es importante recordar que recuperar los datos de Memcache debe ser más rápido que ensamblarlos desde la base de datos para ver algún beneficio.
  • Si sus artículos no son dinámicos, o si tiene cambios dinámicos simples después de que se generan, considere escribir html o php en el disco. Podría tener una página index.php que busque en el disco el artículo, si está allí, lo transmite al cliente. Si no es así, genera el artículo, lo escribe en el disco y lo envía al cliente. Eliminar archivos del disco provocaría que las páginas se reescriban. Si se agrega un comentario a un artículo, elimine la copia en caché, se regenerará.
Gary Richardson
fuente
10
@ Escribiendo en el disco. Incluso podría deshacerse de index.php y dejar que Apache haga el trabajo por usted, de modo que index.php solo se llame si la ruta no existe. Usarías mode_rewrite para esto.
troelskn
55
-1, PDO es significativamente más lento que MySQLi o incluso la extensión MySQL.
Alix Axel
44
PDO fue mucho más lento que mysqli y no funcionó bien para consultas anidadas para mí. Mysqli también es compatible con preparaciones del lado del servidor y parámetros vinculados al igual que PDO.
Daren Schwenke
55
No puedo creer que esto haya sido aceptado como respuesta. No es muy bueno.
symcbean
1
sobre: ​​almacenamiento en caché: las imágenes, css, htm y js ayudarán, ¡apague las cookies en las imágenes también!
Talvi Watia
61

Soy desarrollador principal en un sitio con más de 15 millones de usuarios. Hemos tenido muy pocos problemas de escalado porque lo planeamos TEMPRANO y lo escalamos cuidadosamente. Estas son algunas de las estrategias que puedo sugerir a partir de mi experiencia.

ESQUEMA Primero, desnormalice sus esquemas. Esto significa que, en lugar de tener varias tablas relacionales, debería optar por tener una tabla grande. En general, las uniones son un desperdicio de recursos valiosos de la base de datos porque hacer múltiples preparaciones y colaciones quema las E / S del disco. Evítalos cuando puedas.

La desventaja aquí es que almacenará / extraerá datos redundantes, pero esto es aceptable porque los datos y el ancho de banda dentro de la jaula son muy baratos (discos más grandes), mientras que las E / S de preparación múltiple son mucho más caras (más servidores) .

ÍNDICE Asegúrese de que sus consultas utilizan al menos un índice. Sin embargo, tenga en cuenta que los índices le costarán si escribe o actualiza con frecuencia. Hay algunos trucos experimentales para evitar esto.

Puede intentar agregar columnas adicionales que no estén indexadas que se ejecutan paralelas a las columnas que están indexadas. Entonces puede tener un proceso fuera de línea que escribe las columnas no indexadas sobre las columnas indexadas en lotes. De esta manera, puede controlar mejor cuándo mySQL necesitará volver a calcular el índice.

Evite consultas calculadas como una plaga. Si debe calcular una consulta, intente hacerlo una vez en el momento de la escritura.

CACHING Recomiendo encarecidamente Memcached. Ha sido probado por los jugadores más importantes en la pila de PHP (Facebook) y es muy flexible. Hay dos métodos para hacerlo, uno es el almacenamiento en caché en la capa de base de datos, el otro es el almacenamiento en caché en la capa de lógica de negocios.

La opción de capa de base de datos requeriría almacenar en caché el resultado de las consultas recuperadas de la base de datos. Puede hacer hash en su consulta SQL usando md5 () y usar eso como una clave de búsqueda antes de ir a la base de datos. La ventaja de esto es que es bastante fácil de implementar. La desventaja (dependiendo de la implementación) es que pierde flexibilidad porque trata a todos los cachés de la misma manera con respecto a la caducidad del caché.

En la tienda en la que trabajo, utilizamos el almacenamiento en caché de la capa empresarial, lo que significa que cada clase concreta en nuestro sistema controla su propio esquema de almacenamiento en caché y tiempos de espera de caché. Esto ha funcionado bastante bien para nosotros, pero tenga en cuenta que los elementos recuperados de DB pueden no ser los mismos que los elementos de la memoria caché, por lo que deberá actualizar la memoria caché y la base de datos juntas.

RECUBRIMIENTO DE DATOS La replicación solo te lleva muy lejos. Antes de lo esperado, sus escritos se convertirán en un cuello de botella. Para compensar, asegúrese de admitir el fragmentación de datos lo antes posible. Es probable que quieras dispararte más tarde si no lo haces.

Es bastante simple de implementar. Básicamente, desea separar la autoridad clave del almacenamiento de datos. Use una base de datos global para almacenar una asignación entre las claves principales y los identificadores de clúster. Consulta esta asignación para obtener un clúster y luego consulta el clúster para obtener los datos. Puede almacenar en caché esta operación de búsqueda, lo que la convertirá en una operación insignificante.

La desventaja de esto es que puede ser difícil juntar datos de múltiples fragmentos. Pero también puedes diseñar tu camino alrededor de eso.

PROCESAMIENTO SIN CONEXIÓN No haga que el usuario espere su backend si no tiene que hacerlo. Cree una cola de trabajos y mueva cualquier procesamiento que pueda sin conexión, separándolo de la solicitud del usuario.

el inteligente
fuente
99
Sin duda, esta debería ser la respuesta aceptada. Es interesante que todo lo que he leído sobre la creación de bases de datos siempre dice "normalice todos los datos tanto como sea posible" sin mencionar el impacto en el rendimiento de hacer uniones. Siempre he sentido intuitivamente que las uniones (especialmente múltiples) agregaron mucha sobrecarga, pero hasta ahora no he escuchado a nadie decirlo explícitamente. Ojalá entendiera mejor de qué estaba hablando controlar cuando MySQL calcula los índices, parece un truco muy interesante.
Evan Plaice
La división de datos es esencial para las bases de datos que crecen demasiado. Google (la compañía no es el motor de búsqueda) tiene muchas cosas interesantes que decir sobre la implementación de esquemas de fragmentación. El procesamiento sin conexión también es enorme cuando se trata de limitar el número de escrituras de la base de datos (y limitar el número de recálculos de índice de tabla). He visto muchos blogs (y creo que incluso Stack Overflow) usan esta técnica para sus sistemas de comentarios / comentarios generados por los usuarios.
Evan Plaice
1
Gracias por los comentarios. Es sorprendente que algunos argumentan a favor de la creación de perfiles de código de nivel medio cuando la gran cantidad de tiempo de ejecución se gasta en E / S de datos o E / S cliente-servidor. Una optimización súper complicada que ahorra un 20% de tiempo de ejecución de un proceso PHP que tarda 40 ms no tiene sentido en comparación con un simple ahorro del 5% de una consulta de base de datos de 1s.
thesmart
42

He trabajado en algunos sitios que obtienen millones / visitas / mes respaldados por PHP y MySQL. Aquí hay algunos conceptos básicos:

  1. Caché, caché, caché. El almacenamiento en caché es una de las formas más simples y efectivas para reducir la carga en su servidor web y base de datos. Contenido de la página de caché, consultas, cálculo costoso, cualquier cosa que esté vinculada a E / S. Memcache es muy simple y efectivo.
  2. Use múltiples servidores una vez que esté al máximo. Puede tener múltiples servidores web y múltiples servidores de bases de datos (con replicación).
  3. Reduzca el número total de solicitudes a sus servidores web. Esto implica el almacenamiento en caché de JS, CSS e imágenes utilizando encabezados caducados. También puede mover su contenido estático a un CDN, lo que acelerará la experiencia de su usuario.
  4. Medida y punto de referencia. Ejecute Nagios en sus máquinas de producción y cargue pruebas en su servidor dev / qa. Debe saber cuándo se incendiará el servidor para poder evitarlo.

Recomiendo leer Creación de sitios web escalables , fue escrito por uno de los ingenieros de Flickr y es una gran referencia.

Consulte también mi publicación de blog sobre escalabilidad, tiene muchos enlaces a presentaciones sobre escalado con múltiples idiomas y plataformas: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/

Ryan Doherty
fuente
1
+1 Hay mucha buena información aquí. He estado investigando más sobre este tema últimamente y su respuesta coincide con todo lo que he leído. Memcache, almacenamiento en caché, CDN para contenido estático, reducción de solicitudes; todo bien También agregaría, generar hashes en archivos de contenido estático (si está detrás de un CDN / caché) del lado del servidor para que los archivos actualizados tengan una firma única en el caché. Además, combine archivos de origen estáticos (css, javascript) sobre la marcha (y almacénelos en caché con hashes de nombre de archivo) para reducir las solicitudes. Además, genere pulgares dinámicamente (y guárdelos en el caché)
Evan Plaice
Google ha creado un módulo de apache llamado mod_pagespeed que puede manejar todas las concatenaciones de archivos, minificación, cambio de nombre de archivos para incluir hash, etc. para todo el contenido estático. Solo debería agregar un poco de sobrecarga de procesamiento a los servidores inicialmente hasta que las cachés (y CDN (s)) se llenen con la mayor parte del contenido. Además, por seguridad, generalmente es una mala idea colocar tablas de acceso público (usuarios) en la misma base de datos que las tablas que manejan el back-end (si por alguna razón una de las tablas fuera pirateada).
Evan Plaice
39

Re: PDO / MySQLi / MySQLND

@ @ gary

No puede simplemente decir "no use MySQLi", ya que tienen objetivos diferentes. PDO es casi como una capa de abstracción (aunque en realidad no lo es) y está diseñado para facilitar el uso de múltiples productos de bases de datos, mientras que MySQLi es específico para las conexiones de MySQL. Es incorrecto decir que PDO es la capa de acceso moderna en el contexto de compararla con MySQLi porque su declaración implica que la progresión ha sido mysql -> mysqli -> PDO, lo cual no es el caso.

La elección entre MySQLi y PDO es simple: si necesita admitir múltiples productos de base de datos, entonces usa PDO. Si solo está utilizando MySQL, puede elegir entre PDO y MySQLi.

Entonces, ¿por qué elegirías MySQLi sobre PDO? Vea abajo...

@ross

Estás en lo cierto acerca de MySQLnd, que es la biblioteca de nivel de lenguaje central más reciente de MySQL, sin embargo, no es un reemplazo para MySQLi. MySQLi (como con PDO) sigue siendo la forma en que interactuaría con MySQL a través de su código PHP. Ambos usan libmysql como el cliente C detrás del código PHP. El problema es que libmysql está fuera del motor central de PHP y ahí es donde entra mysqlnd, es decir, es un controlador nativo que hace uso de los componentes internos centrales de PHP para maximizar la eficiencia, específicamente en lo que respecta al uso de memoria.

MySQLnd está siendo desarrollado por MySQL y recientemente aterrizó en la rama PHP 5.3 que está en pruebas RC, lista para su lanzamiento a finales de este año. Entonces podrá usar MySQLnd con MySQLi ... pero no con PDO. Esto le dará a MySQLi un aumento de rendimiento en muchas áreas (no todas) y lo convertirá en la mejor opción para la interacción de MySQL si no necesita la abstracción como las capacidades de PDO.

Dicho esto, MySQLnd ahora está disponible en PHP 5.3 para PDO y, por lo tanto, puede obtener las ventajas de las mejoras de rendimiento de ND a PDO, sin embargo, PDO sigue siendo una capa de base de datos genérica y, por lo tanto, es poco probable que pueda beneficiarse tanto de las mejoras en ND como MySQLi puede .

Aquí se pueden encontrar algunos puntos de referencia útiles, aunque son de 2006. También debe ser consciente de cosas como esta opción .

Hay muchas consideraciones que deben tenerse en cuenta al decidir entre MySQLi y PDO. En realidad, no va a importar hasta que obtenga números de solicitud ridículamente altos y, en ese caso, tiene más sentido usar una extensión que se haya diseñado específicamente para MySQL en lugar de una que abstraiga cosas y proporcione un controlador MySQL .

No es una simple cuestión de cuál es mejor porque cada uno tiene ventajas y desventajas. Debe leer los enlaces que he proporcionado y llegar a su propia decisión, luego probarlo y averiguarlo. He usado PDO en proyectos anteriores y es una buena extensión, pero mi elección para un rendimiento puro sería MySQLi con la nueva opción MySQLND compilada (cuando se lanza PHP 5.3).

davidmytton
fuente
66
Cambié de PDO a mysqli y las consultas regulares comenzaron a ejecutarse exactamente 2 veces más rápido.
serg
55
@serg: ¿te gustaría publicar algunas pruebas para confirmar esto?, porque dudo seriamente que simplemente cambiar de PDO a mysqli te diera un aumento de velocidad.
Stann
23

General

  • No intente optimizar antes de comenzar a ver la carga del mundo real. Puede acertar, pero si no lo hace, ha perdido el tiempo.
  • Use jmeter , xdebug u otra herramienta para comparar el sitio.
  • Si la carga comienza a ser un problema, es probable que se vea involucrado el almacenamiento en caché de objetos o datos, por lo que generalmente lea sobre las opciones de almacenamiento en caché (memcached, opciones de almacenamiento en caché de MySQL)

Código

  • Perfile su código para que sepa dónde está el cuello de botella y si está en el código o en la base de datos

Bases de datos

  • Utilice MYSQLi si la portabilidad a otras bases de datos no es vital, PDO contrario
  • Si los puntos de referencia revelan que la base de datos es el problema, verifique las consultas antes de comenzar el almacenamiento en caché. Use EXPLAIN para ver dónde se ralentizan sus consultas.
  • Después de que las consultas se optimizan y la base de datos se almacena en caché de alguna manera, es posible que desee utilizar varias bases de datos. Puede ser apropiado replicar a múltiples servidores o fragmentar (dividir los datos en múltiples bases de datos / servidores), dependiendo de los datos, las consultas y el tipo de comportamiento de lectura / escritura.

Almacenamiento en caché

  • Se ha escrito mucho sobre el almacenamiento en caché de código, objetos y datos. Busque artículos sobre APC , Zend Optimizer , memcached , QuickCache , JPCache . Haga algo de esto antes de que realmente lo necesite, y estará menos preocupado por comenzar sin ser optimizado.
  • APC y Zend Optimizer son cachés de código de operación, aceleran el código PHP al evitar volver a analizar y recompilar el código. Generalmente simple de instalar, vale la pena hacerlo temprano.
  • Memcached es un caché genérico, que puede usar para almacenar en caché consultas, funciones u objetos PHP, o páginas enteras. El código debe escribirse específicamente para usarlo, lo que puede ser un proceso complicado si no hay puntos centrales para manejar la creación, actualización y eliminación de objetos en caché.
  • QuickCache y JPCache son cachés de archivos, de lo contrario son similares a Memcached. El concepto básico es simple, pero también requiere código y es más fácil con los puntos centrales de creación, actualización y eliminación.

Diverso

  • Considere servidores web alternativos para alta carga. Los servidores como lighthttp y nginx pueden manejar grandes cantidades de tráfico en mucha menos memoria que Apache , si puede sacrificar el poder y la flexibilidad de Apache (o si simplemente no necesita esas cosas, que a menudo no lo hace).
  • Recuerde que el hardware es sorprendentemente barato en estos días, así que asegúrese de costar el esfuerzo de optimizar un gran bloque de código versus "compremos un servidor monstruo".
  • Considere agregar las etiquetas "MySQL" y "escala" a esta pregunta
Paul Kroll
fuente
9

APC es una necesidad absoluta. No solo es un gran sistema de almacenamiento en caché, sino que la ganancia de los archivos PHP de almacenamiento en caché automático es una bendición. En cuanto a la idea de múltiples bases de datos, no creo que se pueda sacar mucho provecho de tener diferentes bases de datos en el mismo servidor. Puede darle un poco de ganancia de velocidad durante el tiempo de consulta, pero dudo que el esfuerzo que se necesitaría para implementar y mantener el código para los tres mientras se asegura de que estén sincronizados valdría la pena.

También recomiendo ejecutar Xdebug para encontrar cuellos de botella en su programa. Hizo de la optimización una brisa para mí.

tslocum
fuente
9

En primer lugar, como creo que dijo Knuth, "La optimización prematura es la raíz de todo mal". Si no tiene que lidiar con estos problemas ahora, no lo haga, concéntrese en entregar algo que funcione correctamente primero. Dicho esto, si las optimizaciones no pueden esperar.

Intente perfilar las consultas de su base de datos, descubra lo que es lento y lo que sucede mucho, e idee una estrategia de optimización a partir de eso.

Investigaría Memcached ya que es lo que muchos de los sitios de mayor carga usan para almacenar en caché de manera eficiente contenido de todo tipo, y la interfaz de objetos PHP es bastante agradable.

La división de bases de datos entre servidores y el uso de algún tipo de técnica de equilibrio de carga (por ejemplo, generar un número aleatorio entre 1 y # bases de datos redundantes con los datos necesarios, y usar ese número para determinar a qué servidor de bases de datos conectarse) también puede ser una excelente manera de aumentar eficiencia.

Todo esto ha funcionado bastante bien en el pasado para algunos sitios de carga bastante alta. Espero que esto ayude a comenzar :-)

Eric Scrivner
fuente
1
RequiredFullQuote: "Deberíamos olvidarnos de las pequeñas eficiencias, digamos alrededor del 97% del tiempo: la optimización prematura es la raíz de todo mal"
Alister Bulman
RequiredReallyFullQuote: "Los programadores pierden enormes cantidades de tiempo pensando o preocupándose por la velocidad de las partes no críticas de sus programas, y estos intentos de eficiencia en realidad tienen un fuerte impacto negativo cuando se consideran la depuración y el mantenimiento. Debemos olvidar las pequeñas eficiencias, dicen aproximadamente el 97% del tiempo: la optimización prematura es la raíz de todo mal. Sin embargo, no debemos dejar pasar nuestras oportunidades en ese crítico 3% ".
cHao
6

Definir su aplicación con algo como Xdebug (como se recomienda tj9991) definitivamente será imprescindible. No tiene mucho sentido simplemente optimizar las cosas a ciegas. Xdebug lo ayudará a encontrar los cuellos de botella reales en su código para que pueda pasar su tiempo de optimización con prudencia y corregir fragmentos de código que realmente están causando desaceleraciones.

Si está usando Apache, otra utilidad que puede ayudar en las pruebas es Siege . Le ayudará a anticipar cómo su servidor y su aplicación reaccionarán a las altas cargas al realmente ponerlo a prueba.

Cualquier tipo de caché de código de operación para PHP (como APC o uno de los muchos otros) también ayudará mucho.

Bob Somers
fuente
6

Tengo un sitio web con 7-8 millones de visitas al mes. No mucho, pero lo suficiente como para que nuestro servidor sintiera la carga. La solución que elegimos fue simple: Memcache a nivel de base de datos. Esta solución funciona bien si la carga de la base de datos es su principal problema.

Comenzamos usando Memcache para almacenar en caché objetos completos y los resultados de la base de datos que se usaban con mayor frecuencia. Funcionó, pero también introdujo errores (podríamos haber evitado algunos si hubiéramos sido más cuidadosos).

Entonces cambiamos nuestro enfoque. Creamos un contenedor de base de datos (con exactamente los mismos métodos que nuestra base de datos anterior, por lo que fue fácil cambiarlo), y luego lo subclasificamos para proporcionar métodos de acceso a la base de datos memcached.

Ahora todo lo que tiene que hacer es decidir si una consulta puede usar resultados en caché (y posiblemente desactualizados) o no. La mayoría de las consultas ejecutadas por los usuarios ahora se obtienen directamente de Memcache. Las excepciones son las actualizaciones e inserciones, que para el sitio web principal solo ocurren debido al registro. Esta medida bastante simple redujo la carga de nuestro servidor en aproximadamente un 80%.

Vegard Larsen
fuente
6

Por lo que vale, el almacenamiento en caché es DIRT SIMPLE en PHP incluso sin un paquete de extensión / ayuda como memcached.

Todo lo que necesitas hacer es crear un buffer de salida usando ob_start().

Crea una función de caché global. Llamadaob_start , pasa la función como devolución de llamada. En la función, busque una versión en caché de la página. Si existe, sírvela y termina.

Si no existe, el script continuará procesándose. Cuando llegue al ob_end () correspondiente, llamará a la función que especificó. En ese momento, solo obtiene el contenido del búfer de salida, los coloca en un archivo, guarda el archivo y finaliza.

Agregue un poco de vencimiento / recolección de basura.

Y muchas personas no se dan cuenta de que puedes anidar ob_start()/ ob_end()llamar. Entonces, si ya está utilizando un búfer de salida para, por ejemplo, analizar anuncios o resaltar la sintaxis o lo que sea, simplemente puede anidar otra ob_start/ob_endllamada.

AJ
fuente
+1 porque parece una idea interesante. No sé qué tan bien funciona en
términos de
+1 porque esta es una idea interesante. ¡Esas devoluciones de llamada podrían llamarme a mi clase de almacenamiento en caché!
Xeoncross
5

Gracias por el consejo sobre las extensiones de almacenamiento en caché de PHP. ¿Podría explicar las razones para usar una sobre otra? He escuchado grandes cosas sobre memcached a través de IRC, pero nunca he oído hablar de APC, ¿cuáles son sus opiniones sobre ellos? Supongo que usar múltiples sistemas de almacenamiento en caché es bastante contra-efectivo.

En realidad, muchos usan APC y memcached juntos ...

ceejayoz
fuente
4

Parece que me equivoqué . MySQLi aún se está desarrollando. Pero según el artículo, el equipo de MySQL está contribuyendo a PDO_MySQL. Del artículo:

La extensión mejorada de MySQL, mysqli, es el buque insignia. Admite todas las funciones del servidor MySQL, incluidos Charsets, declaraciones preparadas y procedimientos almacenados. El controlador ofrece una API híbrida: puede usar un estilo de programación procesal u orientado a objetos según su preferencia. mysqli viene con PHP 5 y superior. Tenga en cuenta que End of life for PHP 4 es 2008-08-08.

Los PHP Data Objects (PDO) son una capa de abstracción de acceso a la base de datos. PDO le permite usar las mismas llamadas API para varias bases de datos. PDO no ofrece ningún grado de abstracción de SQL. PDO_MYSQL es un controlador MySQL para PDO. PDO_MYSQL viene con PHP 5. A partir de PHP 5.3, los desarrolladores de MySQL contribuyen activamente a él. El beneficio PDO de una API unificada tiene el precio de que las características específicas de MySQL, por ejemplo, múltiples declaraciones, no son totalmente compatibles a través de la API unificada.

Deje de usar el primer controlador MySQL para PHP publicado: ext / mysql. Desde la introducción de MySQL Improved Extension (mysqli) en 2004 con PHP 5, no hay razón para seguir utilizando el controlador más antiguo. ext / mysql no admite Charsets, declaraciones preparadas y procedimientos almacenados. Está limitado al conjunto de características de MySQL 4.0. Tenga en cuenta que el Soporte extendido para MySQL 4.0 finaliza el 31/12/2008. ¡No se limite al conjunto de características de un software tan antiguo! Actualice a mysqli, consulte también Converting_to_MySQLi. mysql está en modo solo mantenimiento desde nuestro punto de vista.

Para mí, parece que el artículo está sesgado hacia MySQLi. Supongo que soy parcial hacia la DOP. Realmente me gusta PDO sobre MySQLi. Es directo para mí. La API está mucho más cerca de otros lenguajes que he programado. Las interfaces de la base de datos OO parecen funcionar mejor.

No he encontrado ninguna característica específica de MySQL que no estuviera disponible a través de PDO. Me sorprendería si alguna vez lo hiciera.

Gary Richardson
fuente
3

PDO también es muy lento y su API es bastante complicada. Nadie en su sano juicio debería usarlo si la portabilidad no es una preocupación. Y seamos sinceros, en el 99% de todas las aplicaciones web no lo es. Simplemente se queda con MySQL o PostrgreSQL, o con lo que sea que esté trabajando.

En cuanto a la pregunta de PHP y qué tener en cuenta. Creo que la optimización prematura es la raíz de todo mal. ;) Primero haga su aplicación, trate de mantenerla limpia cuando se trata de programación, haga un poco de documentación y escriba pruebas unitarias. Con todo lo anterior, no tendrá problemas para refactorizar el código cuando llegue el momento. Pero primero quieres terminar y sacarlo para ver cómo reacciona la gente.

Hasta que
fuente
2

Claro que pdo es bueno, pero ha habido algunos controversia sobre su rendimiento frente a mysql y mysqli, aunque ahora parece arreglado.

Debería usar pdo si visualiza la portabilidad, pero si no, mysqli debería ser el camino. Tiene una interfaz OO, declaraciones preparadas y la mayoría de lo que ofrece pdo (excepto, bueno, portabilidad).

Además, si realmente se necesita rendimiento, prepárese para el controlador MysqLnd (nativo de mysql) en PHP 5.3, que estará mucho más integrado con php, con un mejor rendimiento y un mejor uso de la memoria (y estadísticas para el ajuste del rendimiento).

Memcache es bueno si tienes servidores en clúster (y una carga similar a YouTube), pero también probaría APC primero.

Berzemus
fuente
2

Ya se dieron muchas buenas respuestas, pero me gustaría señalarle un caché de código de operación alternativo llamado XCache . Es creado por un colaborador ligero.

Además, si necesita equilibrar la carga de su servidor de base de datos en el futuro, MySQL Proxy podría ayudarlo a lograrlo.

Ambas herramientas deberían conectarse a una aplicación existente con bastante facilidad, por lo que esta optimización se puede hacer cuando la necesite, sin demasiados problemas.

colgado
fuente
2

La primera pregunta es ¿qué tan grande realmente espera que sea? ¿Y cuánto planea invertir en su infraestructura? Dado que siente la necesidad de hacer la pregunta aquí, supongo que espera comenzar de a poco con un presupuesto limitado.

El rendimiento es irrelevante si el sitio no está disponible. Y para disponibilidad, necesita escala horizontal. El mínimo con el que puede salirse con la suya es 2 servidores, ambos con apache, php y mysql. Configure un DBMS como esclavo del otro. Realice todas las escrituras en el maestro y todas las lecturas en la base de datos local (sea lo que sea), a menos que por alguna razón necesite volver a leer los datos que acaba de leer (use el maestro). Asegúrese de tener la maquinaria en su lugar para promover automáticamente al esclavo y cercar al maestro. Utilice DNS de round-robin para las direcciones del servidor web para dar más afinidad al nodo esclavo.

Particionar sus datos en diferentes nodos de bases de datos en esta etapa es una muy mala idea; sin embargo, es posible que desee considerar dividirlos en diferentes bases de datos en el mismo servidor (lo que facilitará la partición entre nodos cuando supere a Facebook).

Asegúrese de contar con las herramientas de monitoreo y análisis de datos para medir el rendimiento de sus sitios e identificar cuellos de botella. La mayoría de los problemas de rendimiento se pueden solucionar escribiendo un mejor SQL / arreglando el esquema de la base de datos.

Mantener el caché de su plantilla en la base de datos es una idea tonta: la base de datos debe ser un repositorio común central para datos estructurados. Mantenga su caché de plantilla en el sistema de archivos local de sus servidores web: estará disponible más rápido y no ralentizará el acceso a su base de datos.

Utilice un caché de código operativo.

Dedique mucho tiempo a estudiar su sitio y sus registros para comprender por qué va tan lento.

Empuje la mayor cantidad de caché posible en el cliente.

Usa mod_gzip para comprimir todo lo que puedas.

C.

symcbean
fuente
2

Mi primer consejo es pensar en este problema y tenerlo en cuenta al diseñar el sitio, pero no exagerar . A menudo es difícil predecir el éxito de un nuevo sitio y su tiempo será mejor empleado para terminar temprano y optimizarlo más tarde.

En general, simple es rápido . Las plantillas te ralentizan. Las bases de datos te ralentizan. Las bibliotecas complejas te ralentizan. Colocando las plantillas una sobre otra, recuperándolas de las bases de datos y analizándolas en una biblioteca compleja -> los retrasos se multiplican entre sí.

Una vez que tenga el sitio básico en funcionamiento, realice pruebas para mostrarle dónde gastar sus esfuerzos. Es difícil ver a dónde apuntar. A menudo, para acelerar las cosas, tendrá que desentrañar la complejidad del código, esto lo hace más grande y más difícil de mantener, por lo que solo desea hacerlo cuando sea necesario.

En mi experiencia, establecer la conexión de la base de datos fue relativamente costoso. Si puede salirse con la suya, no se conecte a la base de datos para visitantes generales en las páginas más transitadas, como la página principal del sitio. Crear múltiples conexiones de bases de datos es una locura con muy pocos beneficios.

lod
fuente
1

@ Gary

No use MySQLi: PDO es la capa de acceso a la base de datos OO 'moderna'. La característica más importante para usar son los marcadores de posición en sus consultas. Es lo suficientemente inteligente como para usar preparaciones del lado del servidor y otras optimizaciones para usted también.

Estoy buscando PDO en este momento y parece que tienes razón, sin embargo, sé que MySQL está desarrollando la extensión MySQLd para PHP. Creo que MySQL o MySQLi tienen éxito, ¿qué piensas al respecto?


@ Ryan , Eric , tj9991

Gracias por el consejo sobre las extensiones de almacenamiento en caché de PHP. ¿Podría explicar las razones para usar una sobre otra? He escuchado grandes cosas sobre memcached a través de IRC, pero nunca he oído hablar de APC, ¿cuáles son sus opiniones sobre ellos? Supongo que usar múltiples sistemas de almacenamiento en caché es bastante contra-efectivo.

Definitivamente ordenaré algunos probadores de perfiles. Muchas gracias por sus recomendaciones.

Ross
fuente
1

No me veo cambiando de MySQL pronto, así que supongo que no necesito las capacidades de abstracción de PDO. Gracias por esos artículos, DavidM, me han ayudado mucho.

Ross
fuente
1

Mire en mod_cache , un caché de salida para el servidor web Apache, similar al almacenamiento en caché de salida en ASP.NET.

Sí, puedo ver que todavía es experimental, pero algún día será definitivo.

Andrei Rînea
fuente
1

No puedo creer que nadie ya haya mencionado esto: modularización y abstracción. Si cree que su sitio va a tener que crecer en muchas máquinas, debe diseñarlo para que pueda! Eso significa cosas estúpidas como no asumir que la base de datos está en localhost. También significa cosas que serán una molestia al principio, como escribir una capa de abstracción de base de datos (como PDO, pero mucho más ligera porque solo hace lo que necesita hacer).

Y significa cosas como trabajar con un marco. Necesitará capas en su código para que luego pueda obtener un rendimiento refactorizando la capa de abstracción de datos, por ejemplo, enseñándole que algunos objetos están en una base de datos diferente, y que el código no tiene que saberlo ni importarle .

Finalmente, tenga cuidado con las operaciones intensivas en memoria, por ejemplo, la copia innecesaria de cadenas. Si puede mantener bajo el uso de memoria de PHP, obtendrá más rendimiento de su servidor web y esto es algo que escalará cuando vaya a una solución de carga equilibrada.

staticsan
fuente
1

Si está trabajando con grandes cantidades de datos y el almacenamiento en caché no es suficiente, busque en Sphinx. Hemos tenido excelentes resultados con el uso de SphinxSearch no solo para una mejor búsqueda de texto, sino también como un reemplazo de recuperación de datos para MySQL cuando se trata de tablas más grandes. Si usa SphinxSE (complemento MySQL), superó nuestras ganancias de rendimiento que obtuvimos al almacenar en caché varias veces, y la implementación de la aplicación es muy sencilla.


fuente
1

Los puntos hechos sobre el caché son precisos; Es la parte menos complicada y más importante de construir una aplicación eficiente. Me gustaría agregar que si bien memcached es excelente, APC es aproximadamente cinco veces más rápido si su aplicación vive en un solo servidor.

La publicación "Comparación de rendimiento de caché" en el blog de rendimiento de MySQL tiene algunos puntos de referencia interesantes sobre el tema: http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Johannes Gorset
fuente