2011-11-05 15 views
21

Mi sto avvicinando alla distribuzione di un'applicazione basata su Rails 3.1.x e ho iniziato a eseguire alcuni test delle prestazioni. Dopo aver giocherellato un po 'con lo ab, sto vedendo alcuni risultati molto scoraggianti che producono circa 15 richieste al secondo su Heroku.Rails Ottimizzazione delle prestazioni per la produzione?

Durante il test locale, vedo risultati simili che dimostrano che si tratta di un problema di app più di ogni altra cosa.

Sto eseguendo Unicorn, che è circa il 40% più veloce di sottile su Celadon Cedar. Inoltre, sto usando il db condiviso di PGSQL.

Sono fiducioso che qualcuno possa condividere una lista di bucato o essenzialmente una lista di controllo del lancio che dovrei spostare durante la preparazione di un'app per la produzione e il passaggio alla necessità di regolazione della velocità. Finora ho non trovato un elenco conciso di elementi utilizzabili da spostare che sembra avere senso data la mia situazione.

Oppure, se hai una solida esperienza pratica che passa attraverso problemi come questo, qualsiasi input sarebbe apprezzato!

risposta

19

Ho passato un po 'di tempo a sintonizzare la mia app su heroku e ho trascorso un po' di tempo a lavorare sull'ottimizzazione delle prestazioni delle app Rails in una varietà di impostazioni.

Quando eseguo ab -n 300 -c 75 ... myapp.com .... #, che è un sostegno al mio sito principale, ed è sul piano di cedro libero con unicorno

Requests per second: 132.11 [#/sec] (mean) 
Time per request:  567.707 [ms] (mean) 
Time per request:  7.569 [ms] (mean, across all concurrent requests) 

(questo è contro una home page che non fa nulla di intenso, quindi lo sto fornendo solo come "quanto velocemente potrebbe esserlo sul piano gratuito con una pagina molto semplice?" esempio, non un "le tue app dovrebbero essere questo veloce ")

Ecco il mio Rails performance Tuning 101 checklist:

  1. Misurare prima il tempo di caricamento del browser/della pagina (il browser fa molte richieste, ab ne parla solo di uno, e di solito la richiesta della pagina principale non è il problema), ottieni i numeri di base della pagina di caricamento da strumenti come www.webpagetest.org o www.gtmetrix.com per le pagine pubbliche o gli strumenti del browser Yslow, la velocità della pagina di google o dynatrace per le pagine private. Se si guarda il diagramma della cascata di caricamento della pagina (il pannello 'Rete' in chrome/firefox), di solito mostra che il tuo html si carica rapidamente (meno di un secondo), ma poi tutto il resto richiede 1-3 secondi per caricarsi. Segui i consigli di velocità Yslow/pagina su come migliorare (assicurati di utilizzare la roba per le risorse di Rails 3.1 nella sua intera estensione)

  2. Leggi i tuoi file di registro/nuova reliquia per trovare il punto debole del 'più lento/più frequentemente richiesta "hit" e profilo di ciò che accade per quella richiesta (è un lento ruby ​​/ un sacco di utilizzo di mem, o un sacco di domande?) È necessario disporre di un modo affidabile per rilevare e monitorare i problemi di prestazioni, e non solo andare a cambiare cose a caso. Dopo aver identificato alcune aree di destinazione, creare script di test per aiutare prima/dopo i test e dimostrare che il cambiamento aiuta e rilevare se si verifica una regressione.

  3. La mancanza di indici su colonne DB è una delle più comuni problemi, e più facile da affrontare. Esegui spiegazioni sulle query di destinazione o controlla il log delle query lente per vedere cosa sta facendo il pianificatore di query. Aggiungi indici per chiavi esterne, colonne di ricerca o dati primari (indice di copertura) come appropriato. Ripetere il test con i dati di produzione effettivi per dimostrare che fa la differenza. (puoi eseguire spiegazioni in heroku ed eseguire query per indici mancanti o inutilizzati)

  4. Le app di Rails più scadenti presentano query N + 1 perché è così facile scrivere order.owner.address.city e non pensa a cosa succede quando è in un ciclo.Le query N + 1 non sono necessariamente query lente, quindi non vengono visualizzate nel registro delle query lente, ma solo che ce ne sono molte, ed è più efficiente farlo tutto in una volta. Usa: include o .includes() per il caricamento ansioso di quei dati, o guarda a fare la tua domanda in un altro modo.

  5. Analizza il flusso della tua app e cerca opportunità di memorizzazione nella cache. Se l'utente rimbalza avanti e indietro tra la pagina indice e una pagina dei dettagli, e viceversa, forse una vista ajax dei dettagli, senza lasciare la pagina indice, darà loro i dati di cui hanno bisogno in un modo più veloce. Ho scritto qualche more thoughts about that on my blog

ho dato una presentazione su queste tecniche e altre idee a Chicago alla conferenza WindyCityRails di quest'anno. È possibile see the video here on my www.RailsPerformance.com blog Quello che amo di heroku è che devi essere scalabile dall'inizio. Quando si esaminano le discussioni sulla mailing list, si nota che la maggior parte delle persone conosce le best practice sulle prestazioni e come ottenere il massimo dal server. Mi piace anche come tu, se vuoi rimanere a buon mercato, impari come i trucchi per l'ottimizzazione delle prestazioni ti faranno ottenere il massimo.

Buona fortuna!

+0

Ciao, potresti verificare la mia domanda su una situazione simile per favore? http://stackoverflow.com/questions/22580297/how-to-tune-a-production-level-heroku-postgres-with-a-ruby-on-rails-application – scaryguy

2

Poiché non è stato ancora visualizzato nulla, fornirò una risposta per la parte PostgreSQL. Non posso aiutare con Ruby.

È possibile trovare punti di partenza eccellenti per l'ottimizzazione delle prestazioni nel wiki PostgreSQL.

+0

Poiché in genere non si scrivono query SQL nelle applicazioni Rails e (come indicato) le impostazioni del server e l'hardware sono irrilevanti su Heroku, la risposta non è molto mirata. – coreyward

+0

@coreyward: abbastanza giusto. La mia risposta sembra aver suscitato una certa attenzione, tuttavia, che ha prodotto due risposte in più sul target. –

+1

Grazie per aver sollevato le teste @ErwinBrandstetter! In effetti, non c'è molto che si possa fare per quanto riguarda il tweak del dbs PGSQL condiviso basato su AWS di Heroku, tuttavia, come per le altre note, le query probabilmente sono i kicker dei pneumatici. – ylluminate

4

La risposta singolo più completo è usare qualcosa come NewRelic per strumentare la tua applicazione e trovare i punti lenti. Quindi, puoi applicare le ottimizzazioni o il caching al tuo codice per appianare quei punti lenti. Come cliente Heroku, ottieni un'installazione di NewRelic gratuitamente - è un componente aggiuntivo che puoi aggiungere alla tua implementazione dalla console di Heroku.

Una volta che hai capito cosa ti sta rallentando, puoi iniziare ad avvicinarti. Heroku gestisce la maggior parte del fine tuning degli sviluppatori, quindi non devi fare nulla lì. Tuttavia, sarai comunque in grado di ottenere grandi guadagni ottimizzando le query del database e eseguendo il caching a livello di frammentazione e azione, laddove appropriato.

+0

Grazie. Ho usato leggermente NewRelic come servizio gratuito, ma sembra che dovrei davvero considerare le altre opzioni al momento per vedere dove sono i punti cigolanti. Grazie! Tornerai da te qui sui risultati. – ylluminate

6

ci sono alcuni frutti piuttosto low-hanging che producono quasi sempre guadagni di prestazioni abbastanza meritevoli:

  1. ridurre il numero di query DB utilizzando istruzioni di ActiveRecord più efficienti. Assicurati di utilizzare include e join se necessario, e assicurati di utilizzare empty? su any? dove possibile per evitare SELECT s quando hai solo bisogno di un COUNT.
  2. Soprattutto nelle pagine più pesanti, le visualizzazioni cache, anche se solo per pochi minuti. Spesso puoi spezzare pezzi più grandi o dinamici in partial che possono essere memorizzati nella cache senza alcun effetto negativo.
  3. Sposta qualsiasi attività fuori rete in lavori in background. Ciò include l'invio di e-mail, il recupero di pagine da un altro sito Web e l'esecuzione di chiamate API (anche [specialmente?] A Heroku).Ci sono un certo numero di librerie di elaborazione di lavoro in background molto buone in Ruby, DelayedJob è molto popolare perché funziona con qualsiasi database ActiveRecord, ma il mio preferito è Resque.

È necessario fare attenzione a non perdere troppo tempo per ottimizzare le routine Ruby. A meno che tu non stia facendo qualcosa con un'enorme quantità di dati o elaborazione (ad esempio il ridimensionamento delle immagini) probabilmente non vedrai guadagni molto significativi dall'ottimizzazione dei loop o dalla riduzione dell'utilizzo della memoria. E se trovi che alcune pagine sono problematiche, consulta i tuoi registri e guarda cosa succede durante tali richieste.

E se non lo sei già, le applicazioni di scalabilità automatica come HireFireApp sono ideali per gestire carichi di richieste scalando orizzontalmente senza il costo di eseguire dinamiche estranee durante periodi lenti.

PS: è disponibile un nuovo componente aggiuntivo Heroku denominato Blitz che consente di verificare un carico simultaneo di fino a 5.000 utenti.

+0

Roba buona, grazie per le osservazioni. Sì, HireFire è fantastico e Michael è un ragazzo eccezionale e lo considera un amico. Andando a scavare più a fondo nelle tue osservazioni e ti farò sapere i miei risultati. Alcuni di essi non sono applicabili al momento, ma apprezzo il fatto che "non ottimizzi le routine di ruby", poiché questa è stata una delle mie prime considerazioni, ma sembra produrre risultati non così stellari. – ylluminate

+0

@coreyward, hi corey, sei disponibile per la consulenza sui binari semplici? non è riuscito a trovare le informazioni di contatto sul tuo sito web. In tal caso, si prega di inviare un'e-mail a panabee dot com. Grazie! – Crashalot

Problemi correlati