Rifattorizzare Wordpress per migliorare le prestazioni della memoria [chiuso]


63

Ho visto da vicino il consumo di memoria di Wordpress. Sul mio sito, sembra che per ogni pagina colpita vengano allocati 20 MB di RAM, solo per preparare un ambiente confortevole per l'esecuzione di tutti i plug-in.

Non esiste un singolo punto da ottimizzare, nessun singolo cattivo che mangia la maggior parte della memoria. Il consumo è distribuito su molti molti molti moduli php.

Come possiamo fare in modo che Wordpress inizializzi il suo ambiente in memoria solo una volta, e poi riutilizzalo più volte per ogni hit? Non voglio che PHP lento consumi 20 MB a ogni clic dell'utente - anche su un server con molta memoria, ci vogliono pochi secondi per fare tutto quel lavoro. Avresti sostanzialmente bisogno di blocchi di memoria di sola lettura che possono essere riutilizzati.

Inoltre ... perché 20 MB? Qualcuno può fornire spunti in questo?

Modifica: ecco l'output di WinCacheGrind su Wordpress in esecuzione sul mio computer di sviluppo (molto più veloce dell'hosting condiviso). Come puoi vedere, ci vuole un secondo di scricchiolio solo per produrre l'HTML della pagina principale. Rallenta l'hosting condiviso e hai una ricetta per i problemi. Ho scelto il metodo che richiede la maggior parte del tempo. Come vorresti ottimizzare questo?

Modifica: ecco le statistiche delle query da questo fantastico strumento di profilazione di Functions.php .

Caricamento: 12 query - 532 ms - 19,1 MB - 43 hit della cache / 53
Query: 15 query - 563 ms - 19,0 MB - 72 hit della cache / 86
Display: 21 query - 705 ms - 19,2 MB - 234 riscontri cache / 257

Modifica: vuoi vedere qualcosa garantito per farti impazzire? Inserisci queste righe alla fine di index.php:


echo "<pre>\n";
print_r(get_defined_vars());
echo "</pre>\n";

Ho provato a contare quante volte il corpo del post corrente è archiviato nella memoria. Ho contato 20 casi. Poi ho capito che PHP ha il conteggio dei riferimenti, quindi la quantità di copie ridotta a soli tre: due sembrano essere in WP_Query, uno nella cache degli oggetti. Sto indagando ulteriormente.

Questo è il motivo per cui penso che WordPress abbia bisogno di refactoring mirato ai problemi di memoria. Non puoi più incolpare il suo consumo di memoria sulla pura complessità di ciò che fa. Fa semplicemente un sacco di cose sbagliate .

Modifica: dopo una giornata di tentativi per capirlo, ecco i miei risultati:

1) L'88% di tutta la memoria proviene dal tipo di chiamate richiesto o incluso o include_once:

2) Il file php include si verifica principalmente durante la prima parte di servire una richiesta (non a caso), che è anche dove tutta la memoria viene consumata:

3) È abbastanza interessante tracciare tutte le funzioni che vengono eseguite durante una richiesta. Ci sono oltre 12000 chiamate in totale. Li ho agitati per renderlo più visibile (l'asse Level è sostanzialmente la profondità di pila):

4) L'unica strada che mi viene in mente è minimizzare la quantità di file .php inclusi. Se divido le funzioni per file da cui provengono, puoi vedere che molti file vengono colpiti una o due volte al massimo. Abbiamo bisogno di un modo per saltare quelli quando non sono necessari. Ad esempio, il mio plug-in di backup del database remoto viene caricato e registrato, per non essere mai utilizzato. Ecco la trama sopra divisa per nome file:

Offro una taglia degna di tutta la mia reputazione :) per i refactoring che porterebbero a ridurre il footprint di memoria dei miei blog del 30% o più.

Modifica: ho installato WP 3.1, ecco il confronto con la vecchia versione.

Il blu è WP 3.1, il rosso è 3.0.4. Il nuovo WP è più veloce, ma consuma anche più memoria.

Ecco un elenco per includere file.

Questo mi permette di capire quanta memoria viene consumata da "All In One SEO pack" - una strada sarebbe quella di utilizzare solo una frazione delle funzionalità del plugin per ottenere ciò che voglio. Inoltre, i miei plugin sembrano essere piuttosto male.

Vorrei provare il caricamento condizionale, ad esempio comment.php (non autorizzo commenti sul mio blog) e molti altri. Ho eliminato tutto il codice obsoleto. Ho tagliato kses.php per caricare solo le sue tabelle globali su richiesta. Ho semplificato l10n (non faccio localizzazione), facendo in modo che le sue funzioni restituiscano immediatamente le stringhe, senza ricerche. Sono ancora lontano dal segno del 30% che ho impostato arbitrariamente.

Modifica: ho scaricato e abilitato APC con impostazioni predefinite (32 MB di cache del codice operativo). Ecco il confronto:

Puoi vedere che il caricamento del codice ha subito un'enorme accelerazione e che il codice occupa anche meno spazio in memoria (probabilmente perché abbiamo a che fare solo con i codici operativi, non con l'origine originale). Il consumo di memoria è comunque ancora piuttosto elevato.


Potresti caricare il file cachegrind stesso da qualche parte? Nota solo che non ricordo se qualcosa che vale la pena tenere privato è incluso, se lo è - allora non farlo.
Rarst


1
hm, sono d'accordo con la tua conclusione - nulla salta davvero fuori, chiedendo di essere risolto. Ho scaricato un nuovo profilo sul mio stack di test locale (3.1, MS, Twenty Ten, dati dell'unità di test del tema) e ho ottenuto 1,5 secondi (la maggior parte della differenza sembra essere dovuta al menu personalizzato - la cosa è slooow). Quindi suppongo che non ci sia nulla da correggere = ricerca nella cache.
Rarst

@Rarst Grazie mille per il tuo aiuto. Penso che ci siano cose da sistemare, ma richiederebbe di cambiare l'architettura di Wordpress in una filosofia completamente diversa, e questo è troppo lavoro.
Roman Zenka,

Risposte:


25

Non vale la pena. WordPress non consuma molta memoria solo perché. Mangia molta memoria perché esegue molte funzionalità sotto il cofano.

È molto più semplice ed efficiente memorizzare nella cache i risultati (pagina generata) con plug-in di cache statica e servirli. In questo modo la maggior parte dei visitatori non colpirà nemmeno WP stesso.


2
Sto già utilizzando una cache, ma ho ancora alcune pagine di natura veramente dinamica (ad esempio un carrello). E quando le stelle non sono allineate correttamente, l'utente può attendere 20 secondi - ovvero, concesso, su GoDaddy, ma anche in caso contrario, penso che sarebbe almeno 3 secondi. Semplicemente non posso fornire il tipo di esperienza davvero scattante a cui le persone sono abituate da Google.
Roman Zenka,

8
@Roman Zenka se hai esigenze prestazionali specifiche, allora sei meglio cercare soluzioni specifiche, piuttosto che sperare che WordPress stesso diventi magicamente super veloce e leggero sulle risorse. Le prime cose che suggerirei di esaminare sono la cache dell'opcode e la frammentazione della cache statica ... Ma prima è necessario fare un benchmark del diavolo e determinare non solo dove sta andando la memoria, ma anche dove passa il tempo. WordPress è un ambiente, non un collo di bottiglia da solo. Il collo di bottiglia è in ciò che lo fai fare.
Rarst

@Rarst In realtà ho fatto un benchmark dell'utilizzo della CPU e non posso puntare il dito su un luogo specifico che causa il problema. Simile alla memoria - sembra essere diffuso in tutto il luogo. Tuttavia, il mio benchmarking potrebbe non essere eseguito in modo ottimale - utilizzo il profiler XDebug e Cachegrind - ad esempio è abbastanza difficile distinguere la latenza a causa delle chiamate al database. Sarei grato per suggerimenti su tecniche di profilazione migliori.
Roman Zenka,

È stato aggiunto lo screenshot di @Rarst Profiling.
Roman Zenka,

4
Potrebbe anche essere che i server di GoDaddy siano lenti. Sono noti per non avere l'hardware migliore e " preferirebbero pagare per le pubblicità televisive piuttosto che aggiornare i loro server "
Zack

23

Ed è per questo che penso che WordPress abbia seriamente bisogno di una riscrittura. Non puoi più incolpare il suo consumo di memoria sulla pura complessità di ciò che fa. Fa semplicemente cose sbagliate.

Che conclusione ingenua. Leggi cose che non dovrebbe mai fare, Parte I .

Grazie per i grafici sull'utilizzo della memoria, però.

Molto più tardi modifica: Autommatic ha rilasciato una libreria chiamata prefork che sembra fare quello che stai chiedendo: caricare il codice WordPress nella RAM solo una volta.


È vero, è ingenuo. Forse avrei dovuto dire "refactor" invece di "riscrivere", quindi suona molto meglio. Post aggiornato.
Roman Zenka,

2
Ok, bene, se hai suggerimenti specifici (in particolare le patch), non esitare a pubblicarli su trac: core.trac.wordpress.org
scribu,

Ci sto lavorando proprio ora. Sto cercando di tracciare una mappa di oggetti nella memoria, in modo da poter vedere quanto viene utilizzato da cosa. Esiste uno strumento che potrebbe prendere un dump della memoria e tracciarlo?
Roman Zenka,

5
@scribu - +1 per il link al post di Joel!
MikeSchinkel,

1
Ok, tieni presente che WP_Object_Cache può essere sostituito con un'implementazione memcached ecc.
scribu,

17

A partire da WordPress 3.2, PHP 5.2 sarà il requisito minimo. Penso che sotto le nostre cinture, i frammenti del nucleo possano iniziare a essere ristrutturati e utilizzare le classi con caricamento automatico. Questo ci permetterebbe di evitare di caricare alcuni blocchi di codice a meno che non fossero effettivamente necessari. Ad esempio, se non ci fossero incorporamenti o gallerie in una visualizzazione di pagina, potremmo essere in grado di evitare di caricare molto del codice multimediale.

Tuttavia, anche se decidessero di percorrere quella strada, mi aspetterei che si tratti di una lenta evoluzione (come molti degli altri cambiamenti nascosti che si sono verificati). Richiederebbe la confusione nella posizione di molti file e codice, il che potrebbe eventualmente rompere la compatibilità all'indietro per alcuni plugin.

Parte del problema (se si può davvero chiamare così) è che senza quel tipo di caricamento condizionale, il framework principale non può sapere in anticipo quale funzionalità sarà necessaria o meno per generare la visualizzazione del contenuto. Quindi molte funzioni devono essere caricate nel caso in cui siano necessarie.


@Dougal Campbell Ho iniziato una generosità su questa domanda, per vedere se possiamo hackerare almeno questa istanza di WordPress abbastanza male da ottenere almeno il 30% di miglioramento del consumo di memoria ora, relativamente indolore. Potrebbe ispirare alcuni degli sviluppi futuri.
Roman Zenka,

Il caricamento condizionale, pur riducendo potenzialmente il consumo di memoria, fa male alla velocità quando è coinvolta la cache dell'opcode . Tendiamo a favorire la velocità.
scribu,

Altri pensieri su caricamento automatico: stackoverflow.com/questions/4788452/...
scribu

@scribu Quando dici "caricamento condizionale", stai parlando di caricamento automatico o di caricamento del codice in base a una condizione? Quanto fa male alla velocità?
Roman Zenka,

1
Grazie! Come ho detto, non so se il core WP prenderà mai quella strada (il refactoring richiesto potrebbe essere troppo estremo). Ma sono rimasto molto colpito dallo sforzo che hai fatto per analizzare questo e dai grafici che hai prodotto. Continua così!
Dougal Campbell

16

Come possiamo fare in modo che Wordpress inizializzi il suo ambiente in memoria solo una volta, e poi riutilizzalo più volte per ogni hit?

Si chiama opcode-caching.

http://en.wikipedia.org/wiki/PHP_accelerator


1
Proverò APC a vedere cosa succede. Quando inizialmente avevo posto questa domanda, intendevo qualcosa di più della semplice memorizzazione nella cache del codice operativo - intendevo riutilizzare l'intero ambiente creato da WordPress - codice + dati. Memcached ti aiuterà a ottenere i dati più velocemente, ma continuerai a clonare i dati nella memoria del server. Ora sembra che la cache del codice operativo potrebbe occuparsi di circa il 90% di tutto il consumo di memoria.
Roman Zenka,

Se disponi delle risorse per alcuni esperimenti, potresti anche provare a configurare un ambiente FastCGI. Sarei molto interessato ad alcuni confronti tra mod_php e l'esecuzione in FastCGI.
Dougal Campbell,

5

probabilmente non riuscirai a ridurre così tanto l'utilizzo dell'ariete. Ma se stai usando mod_php, potresti voler passare mod_fcgidinvece a.

mentre mod_php è leggermente più lento, carica php anche quando non è necessario, come pubblicare immagini, file statici o persino cache. Se hai molte richieste, questo è un sacco di RAM.

l'uso di fcgid lo ridurrà molto.

inoltre, l'uso di una cache statica (come la cache w3total) eviterà di chiamare php , il che è davvero un grande vantaggio: meno utilizzo di RAM, meno connessioni db.


4

Ha. Sto lavorando su un'app Web ora che ho intenzione di sovraccaricare di dati e utilizzo oltre ciò che il mio account di hosting condiviso può gestire, quindi ho deciso - mentre sarebbe stato semplicissimo da creare in WP - provare a lavorare da BackPress come un framework e costruisci solo ciò di cui avevo bisogno per i miei casi d'uso specifici.

Quindi sono stato in grado di ridurre il mio ambiente principale dalle centinaia di file PHP in WP a solo una ventina di quelle di cui ho effettivamente bisogno, pur essendo in grado di sfruttare tutto il db, HTTP, gestione degli utenti, formattazione e cron funzioni che adoro in WordPress.

Il problema è che è un sacco di lavoro, e non mi fiderei mai del mio hackjob per qualsiasi cosa oltre il mio uso personale. Se si desidera utilizzare l'intero ambiente WP, prenderlo così com'è. È buono come lo è a causa di centinaia di sviluppatori che lo hanno perfezionato per diversi anni. Come tutti hanno già detto qui, otterrai molto di più trovando un piano di hosting migliore e ricercando tecniche di memorizzazione nella cache di quelle che potresti ottenere hackerando il core.


1
Concordo sul fatto che WP è stato messo a punto per molto tempo. Ma non credo che sia stato messo a punto per funzionare su hosting scadente, con una particolare miscela di plugin. Sono curioso di vedere fino a che punto posso spingerlo. Anche se le modifiche non entrano nel core, è bene avere un modo documentato di hackerare il core se pensi di doverlo fare.
Roman Zenka,

3

Sì, WordPress carica prima tutto e poi fa quello che gli chiediamo di fare. Ricordo da qualche parte che possiamo creare un pool virtuale nella RAM in cui possiamo inserire i file. Ho avuto l'idea di mettere in memoria l'intero WordPress (<10 MB) e quindi possiamo risparmiare un sacco di I / O che da soli dovrebbero dare un impulso alla velocità. Ma non ho mai avuto la possibilità di provarlo e inoltre non sono molto bravo nel perseguire qualcosa del genere. Ma vale la pena provare.


E sono d'accordo con Rarst di utilizzare un plug-in di cache statica in modo che non venga eseguita alcuna elaborazione. Ma può essere usato anche con buone dinamiche. :)
Ashfame,

Mi piace quell'idea. Non sono sicuro di quanto questo problema sia dovuto alle latenze I / O e quanto sia dovuto al fatto che PHP mastica lentamente i dati. Sai come dire?
Roman Zenka,

Mi dispiace è solo un'idea nella mia testa. Può darsi che non influisca sulle prestazioni tanto quanto potrebbe sembrare dato che i dati vengono generalmente letti dal disco rigido come blocchi, quindi molti altri dati richiesti potrebbero essere già stati recuperati. Non ne sono troppo sicuro.
Ashfame,

3

alcuni suggerimenti di base:

  1. w3 plugin di cache totale per la memorizzazione nella cache ..
  2. installa e abilita memcache, abilita anche dalle impostazioni della cache totale di w3 (anche la cache opcode è una buona opzione ma non va bene con il plugin della cache totale di w3)
  3. minimizzare le query per indirizzare i collegamenti nei file dei temi ..
  4. Disabilita tutti i plugin extra non utilizzati e rimuovili.
  5. ottimizzare il database.

sto gestendo un noto sito wordpress con un traffico enorme ogni giorno .. non sono nemmeno dedicato, sto andando alla grande per me :)

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.