Tattica per l'utilizzo di PHP in un sito ad alto carico


242

Prima di rispondere a questa domanda, non ho mai sviluppato nulla di abbastanza popolare da raggiungere carichi elevati di server. Trattami come (sospiro) un alieno che è appena atterrato sul pianeta, sebbene conosca PHP e alcune tecniche di ottimizzazione.


Sto sviluppando uno strumento in PHP che potrebbe raggiungere molti utenti, se funziona bene. Tuttavia, mentre sono pienamente in grado di sviluppare il programma, sono praticamente all'oscuro quando si tratta di creare qualcosa che possa gestire un traffico enorme. Quindi, ecco alcune domande (sentiti libero di trasformare anche questa domanda in un thread di risorse).

Banche dati

Al momento ho intenzione di utilizzare le funzionalità di MySQLi in PHP5. Tuttavia, come devo impostare i database in relazione a utenti e contenuti? Ho davvero bisogno di più database? Al momento tutto è confuso in un database, anche se ho preso in considerazione la possibilità di diffondere i dati degli utenti in uno, il contenuto effettivo in un altro e infine il contenuto del sito principale (master template ecc.) In un altro. Il mio ragionamento alla base di questo è che l'invio di query a database diversi faciliterà il carico su di essi come un database = 3 origini di caricamento. Inoltre sarebbe ancora efficace se fossero tutti sullo stesso server?

caching

Ho un sistema di template che viene utilizzato per costruire le pagine e scambiare le variabili. I modelli master vengono archiviati nel database e ogni volta che viene chiamato un modello viene chiamato copia cache (un documento HTML). Al momento ho due tipi di variabili in questi modelli: una var statica e una var dinamica. I Var statici sono di solito cose come i nomi delle pagine, il nome del sito - cose che non cambiano spesso; i var dinamici sono cose che cambiano ad ogni caricamento della pagina.

La mia domanda su questo:

Supponiamo di avere commenti su diversi articoli. Quale è una soluzione migliore: archivia il modello di commento semplice e visualizza i commenti (da una chiamata DB) ogni volta che la pagina viene caricata o memorizza una copia cache della pagina dei commenti come pagina html - ogni volta che un commento viene aggiunto / modificato / eliminato la pagina viene ricollegata.

Finalmente

Qualcuno ha qualche suggerimento / puntatore per l'esecuzione di un sito ad alto carico su PHP. Sono abbastanza sicuro che sia un linguaggio praticabile da usare: Facebook e Yahoo! dare la precedenza - ma ci sono esperienze a cui dovrei fare attenzione?


9
3,5 anni dopo e non riesco nemmeno a ricordare a cosa stavo lavorando, mi piacerebbe sapere anche quello che pensavo fosse così figo :)
Ross,

8
Lascia che questa sia una lezione per te sull'ottimizzazione prematura :)
Rimu Atkinson,

Risposte:


89

Non esistono due siti uguali. Hai davvero bisogno di ottenere uno strumento come jmeter e benchmark per vedere dove saranno i tuoi punti problematici. Puoi dedicare molto tempo a indovinare e migliorare, ma non vedrai risultati reali fino a quando non misurerai e confronterai le modifiche.

Ad esempio, per molti anni, la cache delle query MySQL è stata la soluzione a tutti i nostri problemi di prestazioni. Se il tuo sito è stato lento, gli esperti di MySQL hanno suggerito di attivare la cache delle query. Si scopre che se si ha un carico di scrittura elevato, la cache è in realtà paralizzante. Se lo accendessi senza test, non lo sapresti mai.

E non dimenticare che non hai mai fatto il ridimensionamento. Un sito che gestisce 10req / s avrà bisogno di modifiche per supportare 1000req / s. E se sei abbastanza fortunato da dover supportare 10.000 req / s, probabilmente anche la tua architettura apparirà completamente diversa.

Banche dati

  • Non usare MySQLi - PDO è il livello di accesso al database OO "moderno". La caratteristica più importante da utilizzare sono i segnaposto nelle query. È abbastanza intelligente da utilizzare anche i preparativi lato server e altre ottimizzazioni.
  • Probabilmente non vorrai interrompere il tuo database a questo punto. Se scopri che un database non sta tagliando, ci sono diverse tecniche per ridimensionare, a seconda della tua app. La replica su server aggiuntivi in ​​genere funziona bene se si hanno più letture che scritture. La frammentazione è una tecnica per suddividere i dati su più macchine.

caching

  • Probabilmente non vuoi memorizzare nella cache del tuo database. Il database è in genere il collo di bottiglia, quindi aggiungere più I / O ad esso è in genere una cosa negativa. Esistono diverse cache PHP là fuori che realizzano cose simili come APC e Zend.
  • Misura il tuo sistema con la cache attivata e disattivata. Scommetto che la tua cache è più pesante della pubblicazione diretta delle pagine.
  • Se ci vuole molto tempo per compilare i tuoi commenti e dati dell'articolo dal db, integra memcache nel tuo sistema. È possibile memorizzare nella cache i risultati della query e archiviarli in un'istanza memcached. È importante ricordare che il recupero dei dati da memcache deve essere più veloce dell'assemblaggio dal database per vedere qualsiasi beneficio.
  • Se i tuoi articoli non sono dinamici o dopo che sono stati generati semplici cambiamenti dinamici, prendi in considerazione la possibilità di scrivere html o php sul disco. Potresti avere una pagina index.php che cerca sul disco l'articolo, se è lì, lo trasmette al client. In caso contrario, genera l'articolo, lo scrive sul disco e lo invia al client. L'eliminazione dei file dal disco comporterebbe la riscrittura delle pagine. Se un commento viene aggiunto a un articolo, elimina la copia memorizzata nella cache: verrebbe rigenerata.

10
@writing su disco. Puoi anche abbandonare index.php e lasciare che Apache faccia il lavoro per te, in modo che index.php venga chiamato solo se il percorso non esiste. Per questo useresti mode_rewrite.
troelskn,

5
-1, PDO è significativamente più lento di MySQLi o persino dell'estensione MySQL.
Alix Axel,

4
DOP è stato molto più lento di mysqli e non ha funzionato bene per le query nidificate per me. Mysqli supporta anche i preparativi lato server e i parametri associati proprio come DOP.
Daren Schwenke,

5
Non riesco a credere che questo sia stato accettato come risposta. Non è molto buono.
symcbean,

1
about: caching - images, css, htm e js ti aiuteranno, spegni anche i cookie sulle immagini!
Talvi Watia,

61

Sono uno sviluppatore principale in un sito con oltre 15 milioni di utenti. Abbiamo avuto pochissimi problemi di ridimensionamento perché l'abbiamo pianificato EARLY e ridimensionato in modo ponderato. Ecco alcune delle strategie che posso suggerire dalla mia esperienza.

SCHEMA Prima di tutto, denormalizza i tuoi schemi. Ciò significa che invece di avere più tabelle relazionali, si dovrebbe invece optare per una grande tabella. In generale, i join sono uno spreco di preziose risorse DB perché la preparazione multipla e le regole di confronto bruciano gli I / O del disco. Evitali quando puoi.

Il compromesso qui è che verranno archiviati / estratti dati ridondanti, ma questo è accettabile perché la larghezza di banda dei dati e all'interno della gabbia è molto economica (dischi più grandi) mentre gli I / O di preparazione multipla sono ordini di grandezza più costosi (più server) .

INDICAZIONE Assicurarsi che le query utilizzino almeno un indice. Attenzione, però, che gli indici ti costeranno se scrivi o aggiorni frequentemente. Ci sono alcuni trucchi sperimentali per evitare questo.

Puoi provare ad aggiungere colonne aggiuntive non indicizzate che vengono eseguite parallelamente alle colonne che sono indicizzate. Quindi è possibile avere un processo offline che scrive le colonne non indicizzate sulle colonne indicizzate in batch. In questo modo, puoi controllare meglio quando mySQL dovrà ricalcolare l'indice.

Evita le query calcolate come una pestilenza. Se è necessario calcolare una query, provare a farlo una volta al momento della scrittura.

CACHING Consiglio vivamente Memcached. È stato dimostrato dai più grandi giocatori dello stack PHP (Facebook) ed è molto flessibile. Esistono due metodi per eseguire questa operazione, uno è la memorizzazione nella cache nel livello DB, l'altro è la memorizzazione nella cache nel livello della logica aziendale.

L'opzione di livello DB richiederebbe la memorizzazione nella cache del risultato delle query recuperate dal DB. È possibile eseguire l'hashing della query SQL utilizzando md5 () e utilizzarlo come chiave di ricerca prima di accedere al database. Il vantaggio di questo è che è abbastanza facile da implementare. Il rovescio della medaglia (a seconda dell'implementazione) è che perdi flessibilità perché stai trattando la stessa memorizzazione nella cache per quanto riguarda la scadenza della cache.

Nel negozio in cui lavoro, utilizziamo la cache del livello aziendale, il che significa che ogni classe concreta nel nostro sistema controlla il proprio schema di cache e i timeout della cache. Questo ha funzionato abbastanza bene per noi, ma tieni presente che gli elementi recuperati dal DB potrebbero non essere gli stessi degli elementi dalla cache, quindi dovrai aggiornare cache e DB insieme.

DATA SHARDING La replica ti arriva solo finora. Prima di quanto ti aspetti, le tue scritture diventeranno un collo di bottiglia. Per compensare, assicurati di supportare la condivisione dei dati il ​​prima possibile. Probabilmente vorrai spararti più tardi se non lo fai.

È abbastanza semplice da implementare. Fondamentalmente, si desidera separare l'autorità chiave dall'archiviazione dei dati. Utilizzare un DB globale per archiviare un mapping tra chiavi primarie e ID cluster. Si richiede questa mappatura per ottenere un cluster, quindi si esegue una query sul cluster per ottenere i dati. È possibile memorizzare al diavolo questa operazione di ricerca che la renderà un'operazione trascurabile.

L'aspetto negativo di questo è che potrebbe essere difficile mettere insieme i dati da più frammenti. Ma puoi anche farti strada.

ELABORAZIONE OFFLINE Non far aspettare l'utente per il tuo backend se non è necessario. Crea una coda di lavoro e sposta qualsiasi elaborazione che puoi offline, facendola separata dalla richiesta dell'utente.


9
+1 Giù le mani, questa dovrebbe essere la risposta accettata. È interessante notare che tutto ciò che ho mai letto sulla costruzione di database dice sempre "normalizzare tutti i dati il ​​più possibile" senza menzionare l'hit di prestazioni di unire i join. Ho sempre intuitivamente sentito che i join (soprattutto multipli) hanno aggiunto un sacco di costi generali, ma finora non ho sentito nessuno dirlo esplicitamente. Vorrei capire meglio di cosa stavi parlando controllando quando MySQL calcola gli indici, sembra un hack molto interessante.
Evan Plaice,

La condivisione dei dati è essenziale per i database che diventano troppo grandi. Google (la società non è il motore di ricerca) ha molte cose interessanti da dire sull'implementazione di schemi di sharding. Anche l'elaborazione offline è enorme quando si tratta di limitare il numero di scritture di database (e di limitare il numero di ricalcoli dell'indice di tabelle). Ho visto molti blog (e penso persino Stack Overflow) utilizzare questa tecnica per i loro sistemi di commenti / feedback generati dagli utenti.
Evan Plaice,

1
Grazie per i commenti È sorprendente che alcuni sostengano la profilazione del codice di livello intermedio quando il tempo VAST è trascorso in I / O di dati o I / O client-server. Un'ottimizzazione complicata ubber che consente di risparmiare il 20% sui tempi di esecuzione di un processo PHP che impiega 40 ms è inutile rispetto al semplice risparmio del 5% su una query del database 1s.
thesmart

42

Ho lavorato su alcuni siti che ottengono milioni / hit / mese supportati da PHP e MySQL. Ecco alcune nozioni di base:

  1. Cache, cache, cache. La memorizzazione nella cache è uno dei modi più semplici ed efficaci per ridurre il carico sul server Web e sul database. Contenuto della pagina della cache, query, calcolo costoso, tutto ciò che è associato I / O. Memcache è morto semplice ed efficace.
  2. Utilizzare più server dopo aver raggiunto il limite massimo. È possibile disporre di più server Web e più server di database (con replica).
  3. Riduci il numero complessivo di richieste ai tuoi server web. Ciò comporta la memorizzazione nella cache di JS, CSS e immagini utilizzando le intestazioni di scadenza. Puoi anche spostare i tuoi contenuti statici su una CDN, il che velocizzerà l'esperienza dell'utente.
  4. Misura e benchmark. Esegui Nagios sulle tue macchine di produzione e carica i test sul tuo server dev / qa. Devi sapere quando il tuo server prenderà fuoco in modo da poterlo prevenire.

Consiglio di leggere siti web scalabili , è stato scritto da uno degli ingegneri di Flickr ed è un ottimo riferimento.

Dai un'occhiata anche al mio post sul blog sulla scalabilità, ha molti collegamenti a presentazioni sul ridimensionamento con più lingue e piattaforme: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1 Ci sono molte buone informazioni qui. Ho fatto ricerche più approfondite su questo argomento ultimamente e la tua risposta è in linea con tutto ciò che ho letto. Memcache, cache, CDN per contenuto statico, riduzione delle richieste; tutte cose buone. Vorrei anche aggiungere, generare hash su file di contenuto statico (se il tuo dietro una CDN / cache) sul lato server in modo che i file aggiornati abbiano una firma univoca nella cache. Inoltre, combinare i file di origine statici (css, javascript) al volo (e memorizzarli nella cache con hash dei nomi di file) per ridurre le richieste. Inoltre, genera i pollici in modo dinamico (e memorizzali nella cache)
Evan Plaice,

Google ha creato un modulo apache chiamato mod_pagespeed in grado di gestire tutte le concatenazioni, la minimizzazione, la ridenominazione dei file per includere l'hash, ecc. Per tutto il contenuto statico. Dovrebbe solo aggiungere un po 'di sovraccarico di elaborazione ai server inizialmente fino a quando le cache (e CDN) saranno popolate con la maggior parte del contenuto. Inoltre, per motivi di sicurezza, è generalmente una cattiva idea inserire le tabelle accessibili al pubblico (utenti) nello stesso database delle tabelle piuttosto che gestire il back-end (se per qualche motivo una delle tabelle dovesse essere compromessa).
Evan Plaice,

39

Ri: DOP / MySQLi / MySQLND

@ gary

Non puoi semplicemente dire "non usare MySQLi" in quanto hanno obiettivi diversi. PDO è quasi come uno strato di astrazione (anche se in realtà non lo è) ed è progettato per semplificare l'utilizzo di più prodotti di database mentre MySQLi è specifico per le connessioni di MySQL. È sbagliato affermare che il PDO è il livello di accesso moderno nel contesto del confronto con MySQLi perché la tua affermazione implica che la progressione è stata mysql -> mysqli -> PDO che non è il caso.

La scelta tra MySQLi e PDO è semplice: se è necessario supportare più prodotti di database, si utilizza PDO. Se stai solo usando MySQL, puoi scegliere tra DOP e MySQLi.

Quindi perché dovresti scegliere MySQLi rispetto a DOP? Vedi sotto...

@ross

Hai ragione su MySQLnd, che è la più recente libreria a livello di linguaggio di base di MySQL, tuttavia non è un sostituto di MySQLi. MySQLi (come con PDO) rimane il modo in cui interagiresti con MySQL attraverso il tuo codice PHP. Entrambi utilizzano libmysql come client C dietro il codice PHP. Il problema è che libmysql è al di fuori del motore PHP principale ed è qui che entra in gioco mysqlnd, ovvero è un driver nativo che utilizza i core PHP interni per massimizzare l'efficienza, in particolare per quanto riguarda l'utilizzo della memoria.

MySQLnd è stato sviluppato dagli stessi MySQL ed è recentemente arrivato al ramo PHP 5.3 che è in fase di test RC, pronto per essere rilasciato entro la fine dell'anno. Sarai quindi in grado di utilizzare MySQLnd con MySQLi ... ma non con PDO. Ciò darà a MySQLi un aumento delle prestazioni in molte aree (non tutte) e lo renderà la scelta migliore per l'interazione con MySQL se non hai bisogno delle capacità di astrazione del PDO.

Detto questo, MySQLnd è ora disponibile in PHP 5.3 per PDO e quindi puoi ottenere i vantaggi dei miglioramenti delle prestazioni da ND a PDO, tuttavia, PDO è ancora un livello di database generico e quindi è improbabile che trarrà beneficio da i miglioramenti in ND come MySQLi può .

Alcuni utili parametri di riferimento possono essere trovati qui sebbene siano del 2006. È inoltre necessario essere consapevoli di cose come questa opzione .

Ci sono molte considerazioni che devono essere prese in considerazione quando si decide tra MySQLi e DOP. La realtà non avrà importanza fino a quando non arriverai a numeri di richiesta ridicolmente alti e in quel caso, ha più senso usare un'estensione che è stata appositamente progettata per MySQL piuttosto che una che astrasse le cose e capita di fornire un driver MySQL .

Non è una questione semplice quale sia la migliore perché ognuna ha vantaggi e svantaggi. Devi leggere i link che ho fornito e trovare la tua decisione, quindi testarlo e scoprirlo. Ho usato PDO in progetti passati ed è una buona estensione, ma la mia scelta per prestazioni pure sarebbe MySQLi con la nuova opzione MySQLND compilata (quando PHP 5.3 verrà rilasciato).


6
Sono passato da DOP a mysqli e le query regolari hanno iniziato a essere eseguite esattamente 2 volte più velocemente.
serg

5
@serg: ti interessa pubblicare alcuni test per confermarlo? Perché dubito seriamente che il semplice passaggio da DOP a mysqli ti darebbe un tale aumento di velocità.
Stann,

23

Generale

  • Non provare a ottimizzare prima di iniziare a vedere il carico del mondo reale. Potresti indovinare, ma se non lo fai, hai perso tempo.
  • Usa jmeter , xdebug o un altro strumento per confrontare il sito.
  • Se il caricamento inizia a rappresentare un problema, sarà probabilmente coinvolta la memorizzazione nella cache di oggetti o dati, quindi generalmente leggi le opzioni di memorizzazione nella cache (memcached, opzioni di cache MySQL)

Codice

  • Profilare il codice in modo da sapere dove si trova il collo di bottiglia e se si trova nel codice o nel database

Banche dati

  • Utilizzare MYSQLi se la portabilità ad altri database non è vitale, altrimenti DOP
  • Se i benchmark rivelano che il problema è il database, controllare le query prima di iniziare la memorizzazione nella cache. Usa EXPLAIN per vedere dove le tue query rallentano.
  • Dopo l'ottimizzazione delle query e la memorizzazione nella cache del database in qualche modo, è possibile che si desideri utilizzare più database. La replica su più server o la condivisione (suddivisione dei dati su più database / server) può essere appropriata, a seconda dei dati, delle query e del tipo di comportamento di lettura / scrittura.

caching

  • Sono state fatte molte scritture su codice di cache, oggetti e dati. Cerca articoli su APC , Zend Optimizer , memcached , QuickCache , JPCache . Fai un po 'di questo prima che tu ne abbia davvero bisogno e sarai meno preoccupato di iniziare in modo non ottimizzato.
  • APC e Zend Optimizer sono cache opcode, accelerano il codice PHP evitando la re-compilazione e la ricompilazione del codice. Generalmente semplice da installare, vale la pena farlo presto.
  • Memcached è una cache generica che puoi utilizzare per memorizzare nella cache query, funzioni o oggetti PHP o intere pagine. Il codice deve essere scritto in modo specifico per usarlo, che può essere un processo coinvolto se non ci sono punti centrali per gestire la creazione, l'aggiornamento e la cancellazione di oggetti memorizzati nella cache.
  • QuickCache e JPCache sono cache di file, altrimenti simili a Memcached. Il concetto di base è semplice, ma richiede anche codice ed è più facile con i punti centrali di creazione, aggiornamento ed eliminazione.

miscellaneo

  • Prendi in considerazione server Web alternativi per carichi elevati. Server come lighthttp e nginx possono gestire grandi quantità di traffico in molta meno memoria di Apache , se puoi sacrificare la potenza e la flessibilità di Apache (o se semplicemente non hai bisogno di quelle cose, cosa che spesso non ti serve).
  • Ricorda che l'hardware è sorprendentemente economico in questi giorni, quindi assicurati di costare lo sforzo di ottimizzare un grande blocco di codice rispetto a "compriamo un server mostruoso".
  • Valuta di aggiungere i tag "MySQL" e "ridimensionamento" a questa domanda

9

APC è un must assoluto. Non solo è un ottimo sistema di memorizzazione nella cache, ma il guadagno dai file PHP con memorizzazione automatica nella cache è una manna dal cielo. Per quanto riguarda l'idea di database multipli, non penso che otterresti molto dall'avere database diversi sullo stesso server. Potrebbe darti un po 'di guadagno in termini di velocità durante il tempo delle query, ma dubito che lo sforzo che sarebbe necessario per distribuire e mantenere il codice per tutti e tre, assicurandoti che ne valesse la pena.

Consiglio vivamente di eseguire Xdebug per trovare colli di bottiglia nel tuo programma. Ha reso l'ottimizzazione un gioco da ragazzi per me.


9

In primo luogo, come penso Knuth, "l'ottimizzazione prematura è la radice di tutti i mali". Se non devi affrontare questi problemi in questo momento, non concentrarti sulla fornitura di qualcosa che funzioni correttamente prima. Detto questo, se le ottimizzazioni non possono attendere.

Prova a profilare le query del tuo database, scopri cosa è lento e cosa succede molto e escogita una strategia di ottimizzazione.

Vorrei indagare su Memcached poiché è quello che usano molti siti a carico più elevato per memorizzare in modo efficiente il contenuto di tutti i tipi, e l'interfaccia dell'oggetto PHP è abbastanza carina.

Suddividere i database tra i server e utilizzare una sorta di tecnica di bilanciamento del carico (ad esempio generare un numero casuale tra 1 e # database ridondanti con i dati necessari - e utilizzare quel numero per determinare a quale server di database connettersi) può anche essere un ottimo modo per aumentare efficienza.

Questi hanno funzionato abbastanza bene in passato per alcuni siti di carico piuttosto elevato. Spero che questo ti aiuti a iniziare :-)


1
RequiredFullQuote: "Dovremmo dimenticare le piccole efficienze, diciamo circa il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali"
Alister Bulman,

RequiredReallyFullQuote: "I programmatori sprecano enormi quantità di tempo pensando o preoccupandosi della velocità delle parti non critiche dei loro programmi e questi tentativi di efficienza hanno effettivamente un forte impatto negativo quando si considerano il debug e la manutenzione. Dovremmo dimenticare piccole efficienze, diciamo circa il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali. Eppure non dovremmo rinunciare alle nostre opportunità in quel 3% critico ".
cHao,

6

Profilare la tua app con qualcosa come Xdebug (come consigliato da tj9991) sarà sicuramente un must. Non ha molto senso andare in giro a ottimizzare ciecamente le cose. Xdebug ti aiuterà a trovare i veri colli di bottiglia nel tuo codice in modo da poter dedicare saggiamente il tuo tempo di ottimizzazione e correggere blocchi di codice che stanno effettivamente causando rallentamenti.

Se stai usando Apache, un'altra utility che può aiutare nei test è Siege . Ti aiuterà a prevedere in che modo il tuo server e l'applicazione reagiranno ai carichi elevati mettendoli davvero alla prova.

Qualsiasi tipo di cache del codice operativo per PHP (come APC o uno dei tanti altri) sarà di grande aiuto.


6

Gestisco un sito Web con 7-8 milioni di pagine visualizzate al mese. Non eccessivamente, ma abbastanza che il nostro server ha sentito il carico. La soluzione che abbiamo scelto era semplice: Memcache a livello di database. Questa soluzione funziona bene se il problema principale è il caricamento del database.

Abbiamo iniziato a utilizzare Memcache per memorizzare nella cache interi oggetti e i risultati del database utilizzati più di frequente. Ha funzionato, ma ha anche introdotto dei bug (avremmo potuto evitare alcuni di quelli se fossimo stati più attenti).

Quindi abbiamo cambiato il nostro approccio. Abbiamo creato un wrapper di database (con gli stessi identici metodi del nostro vecchio database, quindi è stato facile passare da uno all'altro), quindi l'abbiamo sottoclassato per fornire metodi di accesso al database memcached.

Ora tutto ciò che devi fare è decidere se una query può utilizzare o meno i risultati memorizzati nella cache. La maggior parte delle query eseguite dagli utenti vengono ora recuperate direttamente da Memcache. Le eccezioni sono gli aggiornamenti e gli inserti, che per il sito Web principale si verificano solo a causa della registrazione. Questa misura piuttosto semplice ha ridotto il carico del nostro server di circa l'80%.


6

Per quello che vale, la memorizzazione nella cache è DIRT SEMPLICE in PHP anche senza un pacchetto di estensione / supporto come memcached.

Tutto quello che devi fare è creare un buffer di output usando ob_start().

Creare una funzione di cache globale. Chiama ob_start, passa la funzione come richiamata. Nella funzione, cerca una versione cache della pagina. Se esiste, servilo e termina.

Se non esiste, lo script continuerà l'elaborazione. Quando raggiunge l'ob_end () corrispondente, chiamerà la funzione specificata. In quel momento, è sufficiente ottenere il contenuto del buffer di output, rilasciarlo in un file, salvare il file e terminare.

Aggiungi qualche scadenza / garbage collection.

E molte persone non si rendono conto che puoi nidificare ob_start()/ ob_end()chiamare. Quindi, se stai già utilizzando un buffer di output per, ad esempio, analizzare nelle pubblicità o eseguire l'evidenziazione della sintassi o altro, puoi semplicemente nidificare un'altra ob_start/ob_endchiamata.


+1 perché sembra un'idea interessante. Non so quanto funzioni bene dal punto di vista delle prestazioni
Sylverdrag,

+1 perché questa è un'idea interessante. Quei callback potrebbero chiamare la mia classe di cache per me!
Xeoncross,

5

Grazie per il consiglio sulle estensioni di cache di PHP - potresti spiegare i motivi per usarne uno rispetto all'altro? Ho sentito grandi cose su memcached tramite IRC ma non ho mai sentito parlare di APC - quali sono le tue opinioni su di loro? Suppongo che l'utilizzo di più sistemi di memorizzazione nella cache sia piuttosto efficace.

In realtà, molti usano APC e memcached insieme ...


4

Sembra che mi sbagliassi . MySQLi è ancora in fase di sviluppo. Ma secondo l'articolo, PDO_MySQL viene ora fornito dal team MySQL. Dall'articolo:

L'estensione migliorata di MySQL - mysqli - è il fiore all'occhiello. Supporta tutte le funzionalità del server MySQL inclusi set di caratteri, istruzioni preparate e procedure memorizzate. Il driver offre un'API ibrida: è possibile utilizzare uno stile di programmazione procedurale o orientato agli oggetti in base alle proprie preferenze. mysqli viene fornito con PHP 5 e versioni successive. Nota che End of life per PHP 4 è 2008-08-08.

PHP Data Objects (PDO) è un livello di astrazione dell'accesso al database. PDO consente di utilizzare le stesse chiamate API per vari database. DOP non offre alcun grado di astrazione SQL. PDO_MYSQL è un driver MySQL per PDO. PDO_MYSQL viene fornito con PHP 5. A partire da PHP 5.3, gli sviluppatori MySQL contribuiscono attivamente ad esso. Il vantaggio DOP di un'API unificata ha il prezzo che le funzionalità specifiche di MySQL, ad esempio dichiarazioni multiple, non sono completamente supportate tramite l'API unificata.

Smetti di usare il primo driver MySQL per PHP mai pubblicato: ext / mysql. Dall'introduzione dell'estensione migliorata MySQL - mysqli - nel 2004 con PHP 5 non c'è motivo di usare ancora il driver più vecchio in circolazione. ext / mysql non supporta set di caratteri, istruzioni preparate e procedure memorizzate. È limitato al set di funzionalità di MySQL 4.0. Si noti che il supporto esteso per MySQL 4.0 termina il 2008-12-31. Non limitarti al set di funzionalità di un software così vecchio! Esegui l'upgrade a mysqli, vedi anche Converting_to_MySQLi. mysql è in modalità di sola manutenzione dal nostro punto di vista.

A me sembra che l'articolo sia distorto verso MySQLi. Suppongo di essere di parte nei confronti del DOP. Mi piace molto il DOP su MySQLi. Per me è semplice. L'API è molto più vicina alle altre lingue in cui ho programmato. Le interfacce del database OO sembrano funzionare meglio.

Non ho riscontrato alcuna funzionalità MySQL specifica che non fosse disponibile tramite PDO. Sarei sorpreso se mai lo facessi.


3

Anche la DOP è molto lenta e la sua API è piuttosto complicata. Nessuno nella loro mente sana dovrebbe usarlo se la portabilità non è un problema. E ammettiamolo, nel 99% di tutte le webapp non lo è. Ti basta restare con MySQL o PostrgreSQL o con qualunque cosa tu stia lavorando.

Per quanto riguarda la domanda PHP e cosa prendere in considerazione. Penso che l'ottimizzazione prematura sia la radice di tutti i mali. ;) Esegui prima l'applicazione, prova a mantenerla pulita durante la programmazione, fai un po 'di documentazione e scrivi test unitari. Con tutto quanto sopra non avrai problemi con il codice di refactoring quando sarà il momento. Ma prima vuoi essere fatto e spingilo fuori per vedere come le persone reagiscono ad esso.


2

Sicuramente il pdo è bello, ma ci sono state alcune controversie sulla sua performance rispetto a mysql e mysqli, anche se ora sembra risolto.

Dovresti usare pdo se prevedi la portabilità, ma in caso contrario, mysqli dovrebbe essere la strada giusta. Ha un'interfaccia OO, dichiarazioni preparate e la maggior parte di ciò che offre pdo (tranne, beh, portabilità).

Inoltre, se le prestazioni sono davvero necessarie, preparati per il driver (mysql nativo) MysqLnd in PHP 5.3, che sarà molto più strettamente integrato con php, con prestazioni migliori e un migliore utilizzo della memoria (e statistiche per l'ottimizzazione delle prestazioni).

Memcache è bello se hai server in cluster (e carico simile a YouTube), ma prima proverei anche APC .


2

Sono già state fornite molte buone risposte, ma vorrei indicarti una cache opcode alternativa chiamata XCache . È stato creato da un collaboratore leggero.

Inoltre, se in futuro potresti aver bisogno di bilanciare il carico del tuo server di database, MySQL Proxy potrebbe davvero aiutarti a raggiungere questo obiettivo.

Entrambi questi strumenti dovrebbero collegarsi a un'applicazione esistente abbastanza facilmente, quindi questa ottimizzazione può essere eseguita quando ne hai bisogno, senza troppi problemi.


2

La prima domanda è: quanto ti aspetti davvero che sia? E quanto prevedi di investire nella tua infrastruttura. Dato che senti la necessità di porre la domanda qui, immagino che ti aspetti di iniziare con un budget limitato.

Le prestazioni sono irrilevanti se il sito non è disponibile. E per la disponibilità è necessario il ridimensionamento orizzontale. Il minimo che puoi sensibilmente cavartela è 2 server, entrambi con apache, php e mysql. Impostare un DBMS come slave sull'altro. Esegui tutte le scritture sul master e tutte le letture sul database locale (qualunque esso sia) - a meno che per qualche motivo non sia necessario rileggere i dati che hai appena letto (usa master). Assicurati di avere i macchinari in atto per promuovere automaticamente lo schiavo e recintare il padrone. Utilizzare il DNS round robin per gli indirizzi del server Web per fornire maggiore affinità per il nodo slave.

Partizionare i tuoi dati su diversi nodi di database in questa fase è una pessima idea, tuttavia potresti prendere in considerazione la possibilità di dividerli su database diversi sullo stesso server (che faciliterà il partizionamento su nodi quando sorpassi Facebook).

Assicurati di disporre degli strumenti di monitoraggio e analisi dei dati per misurare le prestazioni dei siti e identificare i colli di bottiglia. La maggior parte dei problemi di prestazioni può essere risolta scrivendo meglio SQL / correggendo lo schema del database.

Mantenere la cache dei modelli nel database è un'idea stupida: il database dovrebbe essere un archivio comune centrale per i dati strutturati. Conserva la cache dei modelli sul filesystem locale dei tuoi server web: sarà disponibile più velocemente e non rallenterà l'accesso al database.

Utilizzare una cache con codice operativo.

Trascorri molto tempo a studiare il tuo sito e i suoi registri per capire perché sta andando così lentamente.

Invia il maggior numero possibile di cache sul client.

Usa mod_gzip per comprimere tutto ciò che puoi.

C.


2

Il mio primo consiglio è di pensare a questo problema e tenerlo a mente durante la progettazione del sito, ma non esagerare . È spesso difficile prevedere il successo di un nuovo sito e il tuo tempo verrà speso meglio alzandoti presto finito e ottimizzandolo in seguito.

In generale, Simple è veloce . I modelli ti rallentano. I database ti rallentano. Biblioteche complesse ti rallentano. Livellando i modelli uno sopra l'altro recuperandoli dai database e analizzandoli in una libreria complessa -> i ritardi si moltiplicano tra loro.

Una volta che il sito di base è attivo e funzionante, fai dei test per mostrarti dove spendere i tuoi sforzi. È difficile capire dove rivolgersi. Spesso per accelerare le cose dovrai svelare la complessità del codice, questo lo rende più grande e più difficile da mantenere, quindi vuoi farlo solo dove necessario.

Nella mia esperienza, stabilire la connessione al database era relativamente costoso. Se riesci a cavartela, non collegarti al database per i visitatori generici sulle pagine più trafficate come la prima pagina del sito. Creare connessioni multiple al database è una follia con pochissimi benefici.


1

@ Gary

Non usare MySQLi - PDO è il livello di accesso al database OO "moderno". La caratteristica più importante da utilizzare sono i segnaposto nelle query. È abbastanza intelligente da utilizzare anche i preparativi lato server e altre ottimizzazioni.

Al momento sto cercando il PDO e sembra che tu abbia ragione - tuttavia so che MySQL sta sviluppando l'estensione MySQLd per PHP - Penso che riuscirò sia a MySQL che a MySQLi - cosa ne pensi?


@ Ryan , Eric , tj9991

Grazie per il consiglio sulle estensioni di cache di PHP - potresti spiegare i motivi per usarne uno rispetto all'altro? Ho sentito grandi cose su memcached tramite IRC ma non ho mai sentito parlare di APC - quali sono le tue opinioni su di loro? Suppongo che l'utilizzo di più sistemi di memorizzazione nella cache sia piuttosto efficace.

Definirò sicuramente alcuni tester di profilazione - grazie mille per i tuoi consigli su questi.


1

Non mi vedo passare da MySQL in qualsiasi momento presto, quindi credo di non aver bisogno delle capacità di astrazione del PDO. Grazie per quegli articoli DavidM, mi hanno aiutato molto.


1

Cerca in mod_cache , una cache di output per il web server Apache, simile alla cache di output in ASP.NET.

Sì, posso vedere che è ancora sperimentale ma un giorno sarà definitivo.


1

Non posso credere che nessuno lo abbia già menzionato: modularizzazione e astrazione. Se pensi che il tuo sito debba crescere su molte macchine, devi progettarlo in modo che possa farlo! Ciò significa cose stupide come non dare per scontato che il database sia su localhost. Significa anche cose che all'inizio daranno fastidio, come scrivere un livello di astrazione del database (come PDO, ma molto più leggero perché fa solo quello che ti serve).

E significa cose come lavorare con un framework. Avrai bisogno di livelli per il tuo codice in modo da poter ottenere successivamente prestazioni refactoring del livello di astrazione dei dati, ad esempio insegnandogli che alcuni oggetti si trovano in un database diverso e che il codice non deve conoscere o preoccuparsene .

Infine, prestare attenzione alle operazioni che richiedono molta memoria, ad esempio la copia di stringhe non necessaria. Se riesci a ridurre l'utilizzo della memoria di PHP, otterrai maggiori prestazioni dal tuo server web e questo è qualcosa che si ridimensionerà quando vai a una soluzione con bilanciamento del carico.


1

Se stai lavorando con grandi quantità di dati e la memorizzazione nella cache non sta tagliando, esamina Sphinx. Abbiamo ottenuto ottimi risultati con l'utilizzo di SphinxSearch non solo per una migliore ricerca del testo, ma anche come sostituto del recupero dei dati per MySQL quando si trattano tabelle più grandi. Se si utilizza SphinxSE (plug-in MySQL), ha superato le nostre prestazioni ottenute dalla memorizzazione nella cache più volte e l'implementazione dell'applicazione è un peccato.


1

I punti sulla cache sono chiari; è la parte meno complicata e più importante della creazione di un'applicazione efficiente. Vorrei aggiungere che mentre memcached è fantastico, APC è circa cinque volte più veloce se l'applicazione risiede su un singolo server.

Il post "Confronto delle prestazioni della cache" nel blog sulle prestazioni di MySQL contiene alcuni parametri di riferimento interessanti sull'argomento: http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.