2012-06-25 8 views
6

Ich bin daran interessiert, meine Unicorn-Setup für meine Ruby on Rails 3.1.3 App zu optimieren. Ich erstelle derzeit 14 Worker-Prozesse auf einer extra großen Instanz mit hoher CPU, da meine Anwendung während Lasttests als CPU-gebunden angezeigt wird. Bei etwa 20 Anfragen pro Sekunde, die während eines Simulationslasttests Anforderungen wiederholen, werden alle 8 Kerne in meiner Instanz ausgespielt, und die Boxlast steigt auf 7-8. Jede Unicorn-Instanz verwendet etwa 56-60% CPU.Unicorn CPU-Auslastung bei Belastungstests, Möglichkeiten zur Optimierung

Ich bin gespannt, was sind Möglichkeiten, dass ich das optimieren kann? Ich möchte in der Lage sein, mehr Anfragen pro Sekunde auf eine Instanz dieser Größe zu trichterieren. Speicher ist völlig in Ordnung, wie alle anderen I/O. Die CPU wird während meiner Tests getankt.

+0

Verwenden Sie Ruby 1.9? Wenn nicht, könnte das helfen. – Reactormonk

+0

Ich benutze Ruby 1.9.3 – randombits

+4

Profilieren Sie Ihren Code (Ruby-Prof) finden Sie heraus, warum es langsam ist, versuchen Sie, den Engpass neu zu schreiben. Wiederholen bis schnell genug. Mit 0 Informationen können wir nicht erraten, warum Ihr Code nicht schneller ist. –

Antwort

1

Zunächst einmal wollen Sie wahrscheinlich keine Instanzen bei 45-60% CPU. In diesem Fall, wenn Sie eine Verkehrsspitze bekommen, werden alle Ihre Instanzen ersticken.

Als nächstes scheint 14 Unicorn-Instanzen groß. Unicorn verwendet kein Threading. Vielmehr läuft jeder Prozess mit einem einzigen Thread. Unicorn Master-Prozess wird nur select ein Thread, wenn es in der Lage ist, damit umzugehen. Aus diesem Grund ist die Anzahl an Kernen keine Metrik, die Sie verwenden sollten, um die Leistung mit Unicorn zu messen.

Eine konservativere Konfiguration kann 4 oder so Unicorn-Prozesse pro Instanz verwenden, die auf 5-8 Anfragen pro Sekunde reagieren. Passen Sie dann die Anzahl der Instanzen an, bis die CPU-Auslastung etwa 35% beträgt. Dies wird die Stabilität unter dem stressigen Szenario von 20 Anfragen pro Sekunde gewährleisten.

Schließlich können Sie mehr düstere Statistiken und Details mit God erhalten.

+2

1) Das OP sagte, dies ist während des Belastungstests, also ist dies * eine Verkehrsspitze. 2) Was hat keine Gewindeprozesse mit der Anzahl der Kerne zu tun? –

6

Wenn Sie CPU-gebunden sind, möchten Sie keine Unicorn-Prozesse mehr verwenden als Kerne. Andernfalls überlasten Sie das System und verlangsamen den Scheduler. Sie können dies mit dev auf einer Dev-Box testen. Sie werden bemerken, dass 2 Einhörner 20 übertreffen werden (Anzahl hängt von Kernen ab, aber das Konzept wird wahr).

Die Ausnahme von dieser Regel ist, wenn Ihr IO gebunden ist. In diesem Fall fügen Sie so viele Einhörner wie Speicher hinzu.

Ein guter Leistungstrick besteht darin, E/A-gebundene Anforderungen an einen anderen Anwendungsserver zu leiten, der viele Einhörner enthält. Zum Beispiel, wenn Sie eine Anfrage haben, die eine langsame SQL-Abfrage verwendet, oder wenn Sie auf eine externe Anfrage wie eine Kreditkartentransaktion warten. Wenn Sie nginx verwenden, definieren Sie einen Upstream-Server für die E/A-gebundenen Anforderungen, und leiten Sie diese URLs an eine Box mit 40 Unicorns weiter. CPU-gebundene oder sehr schnelle Anfragen, weiterleiten an eine Box mit 8 Unicorns (Sie haben angegeben, dass Sie 8 Cores haben, aber auf aws möchten Sie vielleicht 4-6 ausprobieren, da ihre Scheduler überlastet und bereits sehr beschäftigt sind).

Auch ich bin mir nicht sicher, dass Sie sich darauf verlassen können, dass Ihnen aws eine zuverlässige CPU-Auslastung bietet, da Sie einen Prozentsatz eines obskuren Prozentsatzes erhalten.

1

Für eine extra große CPU-Instanz sind 20 Anfragen pro Sekunde sehr niedrig. Es ist wahrscheinlich ein Problem mit dem Code. Ein Einhorn-spezifisches Problem scheint weniger wahrscheinlich. Wenn Sie Zweifel haben, können Sie einen anderen App-Server ausprobieren und bestätigen, dass es immer noch passiert.

In diesem Szenario würde ich Fragen zu denken ...

1 - Sind Sie etwas CPU-Kapazität in Code tun - vielleicht etwas, das wirklich in der Datenbank enthalten sein sollte. Wenn Sie beispielsweise ein großes Recordset zurückbringen und es in Ruby/Rails durchlaufen, um es zu sortieren oder eine andere Operation durchzuführen, würde dies einen CPU-Engpass auf dieser Ebene im Gegensatz zur Datenbank erklären. Die Empfehlung in diesem Fall ist, die Abfrage zu überarbeiten, um mehr zu tun und die Schienen zu entlasten.Wenn Sie beispielsweise die Ergebnismenge in Ihrem Controller und nicht über SQL sortieren, würde dies ein Problem wie dieses verursachen.

2 - Machst du etwas Ungewöhnliches im Vergleich zu einer Vanille-Crud-App, wie den Zugriff auf eine freigegebene Ressource oder irgendetwas, wo Konflikte ein Problem sein könnten?

3 - Haben Sie irgendwelche Schleifen, die die CPU brennen könnten, besonders wenn es zu einer Konkurrenz kam?

4 - Versuchen Sie, verschiedene Teile der betreffenden Steuerungslogik loszuhaken. Zum Beispiel, wie gut skaliert es, wenn Sie Ihren Code hacken, um stattdessen nur eine statische Hello-Weltreaktion zurückzugeben? Ich wette, plötzlich wird Einhorn blitzschnell sein. Versuchen Sie dann, Teile Ihres Codes wieder hinzuzufügen, bis Sie die Quelle der Langsamkeit entdecken.