Ile procesów powinienem określić w procesie WSGIDaemonProces podczas uruchamiania Django przez mod_wsgi?

23

Załóżmy, że mam 2 witryny (Superuser i Serverfault) uruchomione z własnego wirtualnego hosta Apache na jednym urządzeniu. Dwie strony są obsługiwane przez Django i działają na Apache z mod-wsgi. Typowy plik konfiguracyjny dla jednej witryny wygląda następująco:

WSGIDaemonProcess serverfault.com user=www-data group=www-data processes=5

Host jest maszyną linux z 4 GB pamięci RAM z systemem Ubuntu. Czy ktoś może zasugerować liczbę procesów, które powinienem określić powyżej dla moich 2 witryn? Załóżmy, że mają taki sam ruch jak rzeczywiste witryny Superuser i Serverfault.

Thierry Lam
źródło

Odpowiedzi:

22

Cóż, ile ruchu ma faktyczne strony Superuser i Serverfault? Hipotetyczne nie są zbyt przydatne, jeśli nie mają wystarczającej ilości informacji, aby ułatwić odpowiedź ...

Liczba procesów w najgorszym przypadku powinna wynosić maksymalną liczbę żądań na sekundę, którą witryna może obsłużyć, podzieloną przez liczbę żądań na sekundę, którą jeden proces może obsłużyć, jeśli wszystkie te żądania zostaną wykonane zgodnie z najwolniejszym działaniem (więc odwrotność czasu przetwarzania tego działania). Dodaj dowolny współczynnik krówki, który Twoim zdaniem jest odpowiedni, na podstawie przedziału ufności twojego zapotrzebowania na sekundę i pomiarów czasu.

Średnia liczba przypadków jest taka sama, ale dzielisz wymagania / s przez średnią ważoną liczby żądań na sekundę dla każdego działania (waga to odsetek żądań, które mają trafić w to działanie). Ponownie przydatne są czynniki krówki.

Rzeczywista górna granica liczby procesów, które można uruchomić na komputerze, jest podyktowana górną ilością pamięci zajmowanej przez każdy proces; buforuj jeden proces, a następnie uruchamiaj na nim różne czynności wymagające dużej ilości pamięci (zwykle takie, które pobierają i przetwarzają dużo danych) przy użyciu realistycznego zestawu danych (jeśli używasz tylko zestawu danych do testowania, powiedzmy 50 lub 100 wierszy, a następnie, jeśli jedna z twoich akcji pobiera i manipuluje każdym wierszem w tabeli, nie będzie to dobry pomiar, gdy ta tabela wzrośnie do 10.000 wierszy), aby zobaczyć, do czego dochodzi użycie pamięci. Możesz sztucznie ograniczyć wykorzystanie pamięci na proces za pomocą skryptu, który zbiera pracowników, którzy osiągną określony próg zużycia pamięci, narażając się na ryzyko spowodowania nieprzyjemnych problemów, jeśli ustawisz zbyt niski próg.

Po określeniu wykorzystania pamięci odejmujesz pewną ilość pamięci dla obciążenia systemu (ja sam lubię 512 MB), odejmujesz stos więcej, jeśli masz inne procesy uruchomione na tym samym komputerze (np. Baza danych), a następnie trochę więcej, aby upewnić się, że nie zabraknie miejsca w pamięci podręcznej dysku (zależy od rozmiaru działającego zestawu dysków, ale ponownie wybrałbym nie mniej niż 512 MB). Jest to ilość pamięci, którą dzielisz przez użycie pamięci na proces, aby uzyskać pułap.

Jeśli liczba procesów potrzebnych do obsługi obciążenia szczytowego jest większa niż liczba procesów, które można zmieścić na urządzeniu, potrzebujesz więcej komputerów (lub, w najprostszym przypadku, przeniesienia bazy danych na inny komputer).

Oto kilka lat doświadczenia w skalowaniu stron internetowych destylowanych w jeden mały i prosty post SF.

womble
źródło
Innym ważnym czynnikiem dla liczby procesów / wątków jest to, jak długo mogą być przetwarzane poszczególne żądania i ogólny rozkład na wszystkie możliwe długości czasu. Innymi słowy, ile żądań musi zostać obsłużonych w danym momencie, co zajmuje więcej niż średni czas odpowiedzi. Nie jest to tak proste, jak tylko teoretyczne żądania / s, ponieważ wpływ tych dłużej działających żądań może być znaczny i nadmiernie dyktować ogólne parametry konfiguracji. FWIW mod_wsgi 3.0 będzie zawierał wbudowane zbieranie statystyk, aby spróbować przechwytywać dane na ten temat, aby pomóc w konfiguracji.
Graham Dumpleton
@Graham: Zapoznaj się z moją odpowiedzią, omówiłem ją szczegółowo. Żądania / s to tylko odwrotność czasu odpowiedzi, i łatwiej jest podzielić przez liczbę całkowitą wymaganą / s niż pomnożyć przez liczbę dziesiętną.
womble
Nie możesz jednak skupić się tylko na najgorszym przypadku, ani tylko na średniej w tej sprawie. Musi być ważony na różne sposoby w oparciu o procent żądań przypadających na przedziały czasowe, tj. Rozkład we wszystkich możliwych zajętych czasach. Jeśli naprawdę wykorzystasz swój najgorszy czas reakcji na sprawę, wymyślisz nierealistyczne wymagania. Problem naprawdę trudno wiedzieć, jakiej formuły użyć. Właśnie dlatego w mod_wsgi 3.0 będzie wbudowane gromadzenie statystyk, które sprawdzają wykorzystanie wątków oraz jaki procent według liczby i czasu, w jakiejkolwiek liczbie wątków jest używanych w danym momencie.
Graham Dumpleton
3
Problemem może być to, że patrzysz na procesy tylko tam, gdzie martwię się o to, w jaki sposób wątki każdy proces wykorzystuje do tego czynnik, i to nie jest tak proste. Innymi słowy, ta dyrektywa WSGIDaemonProcess wskazuje 5 procesów, w których każdy proces domyślnie używa 15 wątków. O ile czytam w twoim opisie, zakłada on procesy jednowątkowe. Jeśli nie, wskaż mi, jak twój model obsługuje wątki oraz problemy z rywalizacją / skalowaniem wokół GIL. Więc zakwalifikuj się, że twój opis jest poprawny tylko dla procesów jednowątkowych i nie będę się kłócił.
Graham Dumpleton
2
Czy podejście „wielowątkowy-Apache + multiprocess-wsgi” nie jest najlepszym rozwiązaniem, dopóki nie będziesz w 99% pewien, że kod Pythona i wszystkie zależności są bezpieczne dla wątków?
Tomasz Zieliński
9

Odpowiedź womble jest niesamowita, choć trochę trudna do zrozumienia i ubiegania się o niedoświadczonego. Chciałbym podać kilka danych empirycznych oraz porównanie „prostych treści” z „e-commerce”.

Nie ma zbyt wiele materiału na temat ustawiania różnych przypadków użycia w związku z ich odpowiednią konfiguracją mod_wsgi, więc mam nadzieję, że można tu użyć trochę prozy.

A) Witryny CMS i mikrostrony

Prowadzimy kilka witryn dla klientów, większość z nich to głównie witryny z treściami lub mikro witryny z systemem Django CMS, niektóre niestandardowe formularze, a czasem Selery do zaplanowanych zadań w tle. Witryny te nie są głodne zasobów, niektóre z nich działają równolegle na jednym 4-rdzeniowym procesorze Intel Xeon z 32 GB pamięci RAM. Oto konfiguracja, której używamy dla każdego z tego rodzaju witryn:

WSGIDaemonProcess example.com user=www-data processes=2 maximum-requests=100

Mówię o około 40 witrynach na jednym serwerze, w większości z witryną pomostową działającą w trybie gotowości. Dzięki 2 procesom (domyślnie 15 wątków) witryny są zamożne, aczkolwiek ograniczone możliwości alokacji zasobów serwera. Dlaczego ta konfiguracja jest wystarczająca, można uzasadnić prostym charakterem aplikacji (CMS): nigdy nie oczekuje się, że wykonanie żądania zajmie więcej niż kilka milisekund. Apache zawsze pozostanie zrelaksowany, podobnie jak obciążenie procesora.

B) Witryny e-commerce

Bardziej złożone witryny, które wykonujemy, charakteryzują się nadal niedrogimi operacjami lokalnymi pod względem obliczeniowym, ale zewnętrznymi zależnościami (np. Serwisami internetowymi dostarczającymi dane do rezerwacji), które są drogie pod względem czasu transakcji. Operacje z zewnętrznymi żądaniami zajmują wątki przez znacznie dłuższy czas, więc potrzebujesz więcej wątków, aby obsłużyć tę samą liczbę użytkowników (w porównaniu do prostej strony CMS z góry). Co gorsza, wątki są czasami blokowane, gdy usługa zewnętrzna nie może natychmiast odpowiedzieć na żądanie, czasami przez kilka sekund. Może to prowadzić do nieprzyjemnego efektu ubocznego polegającego na tym, że wątki umieszczające żądania w tej samej kolejce usług w górę, dopóki wszystkie dostępne wątki mod_wsgi nie zostaną zużyte i zablokowane.

W przypadku tych scenariuszy próbowaliśmy używać 6procesów, nie widząc dużej różnicy, i ostatecznie 12dostrzegliśmy nieporównywalny wzrost wydajności i stabilności operacyjnej:

WSGIDaemonProcess example.com user=www-data processes=12 maximum-requests=100

Niektóre proste testy obciążenia z 150 i 250 równoległymi użytkownikami są łatwo obsługiwane przez witrynę pozostającą dobrze reagującą (podczas gdy z 2procesami strona nie nadaje się do obsługi 50 użytkowników równolegle). Dwurdzeniowy 6-rdzeniowy procesor Intel Xeon z 32 GB pamięci RAM działa znacznie poniżej 25% wykorzystania procesora pod tym obciążeniem, zużycie pamięci RAM prawie pozostaje na stałym poziomie poniżej 25%. Pamiętaj, że używamy tutaj dedykowanej maszyny tylko dla jednej witryny, więc nie będziemy kraść zasobów potrzebnych innym stronom.

Wniosek

Korzystanie z większej liczby procesów jest kompromisem między umożliwieniem Apache korzystania z dostępnych zasobów systemowych lub nie. Jeśli chcesz utrzymać stabilny system serwera (nie stronę internetową!) W warunkach „ataku”, utrzymuj niską liczbę. Jeśli chcesz, aby Apache pomagał ci w korzystaniu z zasobów systemowych (procesora, pamięci RAM) w razie potrzeby, wybierz wyższą liczbę. To, jak wysoko możesz przejść, oblicza się nieco tak, jak opisano w zaakceptowanej odpowiedzi powyżej, i jest ostatecznie ograniczone dostępną mocą procesora i pamięci RAM.

(PS: Trzymam sekcję ConfigurationDirectives wiki projektu modwsgi pod moją poduszką do czytania w tle podobnego do Apache. Pamiętaj również, aby zrozumieć i monitorować otwarte połączenia twojego serwera Apache .)

Peterino
źródło
Świetny post, ale dlaczego nie ustawiasz liczby wątków? Ponieważ GIL Pythona neguje wiele zalet wątków, zakładam, że chciałbyś mieć więcej procesów niż wątków, ale czy jest jakaś zaleta w określaniu liczby wątków?
Cerin,
Domyślna liczba threadsto 15 zgodnie z dokumentacją . Nie sądzę, aby istniała zaleta, aby to wyraźnie określić. W rzeczywistości pamiętam, aby go pominąć z jakiegoś powodu: Był pewien post na SO lub część dokumentacji, która zalecała pominięcie wartości, aby uniknąć skutków ubocznych (wiem, że to brzmi dziwnie). Niestety nie mogę teraz znaleźć tego źródła. W pozostałej części pytania (GIL) prawdopodobnie bardziej jesteś ode mnie ekspertem, przepraszam.
Peterino,
Dziękujemy za tę konfigurację empiryczną. Należy jednak pamiętać, że zgodnie z tym post You should never use maximum-requests in a production system unless you understand the implications and have a specific temporary need.
raratiru