2013-03-05 12 views
9

Próbuję zobaczyć, dlaczego moja strona django (gunicorn 4 pracowników) jest wolna pod dużym obciążeniem, zrobiłem trochę profilowania http://djangosnippets.org/snippets/186/ bez jasnej odpowiedzi, więc zacząłem niektóre testy obciążenia od zarysowanie za pomocą ab -n 1000 -c 100 http://localhost:8888/Django, niskie żądania na sekundę z gunicorn 4 pracowników

prosty Httpreponse ("Hello world") nie pośredniej ==> 3600req/s

prosty Httpreponse ("Hello world") z middleware (buforowanym sesji uwierzytelniania buforowane) ==> 2300req/s

Prosta render_to_response, która drukuje tylko formularz (szablon buforowany) ==> 12 00req/s (czas reakcji została podzielona przez 2)

Prosty render_to_response 50 Memcache zapytaniami ==> 157req/s

Memcache zapytania powinny być znacznie szybsze niż (używam PyLibMCCache)? Czy renderowanie szablonu jest tak wolne, jak ten wynik?

Próbowałem różnych technik profilowania bez powodzenia.

$ ulimit -a 
core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 0 
file size    (blocks, -f) unlimited 
pending signals     (-i) 46936 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 400000 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 46936 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

$ sysctl -p 

fs.file-max = 700000 
net.core.somaxconn = 5000 
net.ipv4.tcp_keepalive_intvl = 30 

Używam Ubuntu 12.04 (6Go RAM, Core i5)

Każda pomoc proszę?

+1

+1 za badania, które wykonałeś – Private

+0

To zależy ... co robisz w widokach? jakie zapytania uruchamiasz? na czym je prowadzisz? – ionelmc

+0

jest twoim memcached serwera na tym samym komputerze lub na zewnętrznym? –

Odpowiedz

1

To naprawdę zależy od tego, ile czasu zajmuje zrobienie memcached request i otwarcie nowego połączenia (django zamyka połączenie, gdy żądanie się kończy), zarówno twój pracownik, jak i memcached są w stanie poradzić sobie z dużo większym stresem, ale oczywiście jeśli wykonanie połączenia z pamięci memphached zajmuje 5/10 ms, a 50 z nich będzie wąskim gardłem, ponieważ opóźnienie sieci zostanie pomnożone przez liczbę połączeń.

W tej chwili jesteś po prostu testowania porównawczego django, gunicorn, swojego komputera i sieci.

Jeśli na tym poziomie nie wystąpi coś bardzo nie tak, testy te nie wskazują na interesujące odkrycia.

To, co spowalnia działanie aplikacji, najprawdopodobniej jest związane ze sposobem korzystania z bazy danych i memcached (i może przy renderowaniu szablonu).

Z tego powodu naprawdę sugeruję, aby uzyskać pasek narzędzi debugowania django i zobaczyć, co dzieje się na twoich prawdziwych stronach.

Jeśli okaże się, że otwarcie połączenia z memcached jest wąskim gardłem, można spróbować użyć puli połączeń i pozostawić otwarte połączenie.

+0

Zrobiłem wszystkie te rzeczy (memcache-debug-panel, profilowanie ...), w zasadzie rozwiązałem mój problem, minimalizując zapytania memcache i zapisując kod html bezpośrednio na memcache (ponieważ niektóre znaczniki szablonu django są bardzo wolne również). w ten sposób pomnożyłem r/s * 100 – surfeurX

0

Możesz zbadać skuteczność memcached.

$ python manage.py shell 
>>> from django.core.cache import cache 
>>> cache.set("unique_key_name_12345", "some value with a size representative of the real world memcached usage", timeout=3600) 
>>> from datetime import datetime 
>>> def how_long(n): 
     start = datetime.utcnow() 
     for _ in xrange(n): 
      cache.get("unique_key_name_12345") 
     return (datetime.utcnow() - start).total_seconds() 

Z tego rodzaju testem w obie strony widzę, że 1 przegląd memcached zajmie około 0,2 ms na moim serwerze.

Problem z django.core.cache i pylibmc polega na tym, że funkcje są blokowane. Potencjalnie można uzyskać 50 razy tyle w obie strony za żądanie HTTP. 50 razy 0,2 ms to już 10 ms.

Jeśli osiągnąłeś 1200 req/s na 4 pracownikach bez memcached, średni czas podróży w obie strony HTTP wynosił 1/(1200/4) = 3,33 ms. Dodaj 10 ms do tego i to staje się 13,33 ms. Przepustowość z 4 pracownikami spadłaby do 300 req/s (co zdarza się w parku z twoim 157 numerem).