Buduję pakiet analityczny, a wymagania projektu mówią, że muszę obsługiwać 1 miliard trafień dziennie. Tak, „miliard”. Innymi słowy, nie mniej niż 12 000 trafień na sekundę zostało utrzymanych, a najlepiej trochę miejsca na wybuch. Wiem, że potrzebuję do tego wielu serwerów, ale staram się uzyskać maksymalną wydajność z każdego węzła, zanim „wrzucę w to więcej sprzętu”.
W tej chwili mam ukończoną część śledzenia trafień i dobrze zoptymalizowaną. Praktycznie zapisuję żądania bezpośrednio w Redis (do późniejszego przetworzenia za pomocą Hadoop). Aplikacja to Python / Django z gunicorn dla bramy.
Mój serwer Rackspace 2 GB Ubuntu 10.04 (nie maszyna produkcyjna) może obsługiwać około 1200 plików statycznych na sekundę (testowany przy użyciu Apache AB względem pojedynczego zasobu statycznego). Dla porównania, jeśli zamienię link do pliku statycznego za pomocą linku śledzącego, nadal otrzymuję około 600 żądań na sekundę - myślę, że to oznacza, że mój moduł śledzący jest dobrze zoptymalizowany, ponieważ jest tylko 2 razy wolniejszy niż ten sam zasób statyczny wielokrotnie.
Jednak gdy porównuję miliony hitów, zauważam kilka rzeczy -
- Brak użycia dysku - jest to oczekiwane, ponieważ wyłączyłem wszystkie dzienniki Nginx, a mój niestandardowy kod nic nie robi, tylko zapisuje szczegóły żądania w Redis.
- Niestałe użycie pamięci - prawdopodobnie ze względu na zarządzanie pamięcią przez Redis, moje użycie pamięci będzie stopniowo rosło, a następnie spadało, ale nigdy nie było to moim wąskim gardłem.
- Obciążenie systemu oscyluje wokół 2-4, system nadal reaguje nawet podczas moich najcięższych testów i wciąż mogę ręcznie przeglądać http://mysite.com/tracking/pixel z niewielkim widocznym opóźnieniem, podczas gdy mój (inny) serwer wykonuje 600 żądań na druga.
- Jeśli przeprowadzę krótki test, powiedzmy 50 000 trafień (zajmuje około 2 m), otrzymam stałe, niezawodne 600 żądań na sekundę. Jeśli przeprowadzę dłuższy test (do tej pory próbowałem do 3,5 m), mój r / s obniży się do około 250.
Moje pytania --
za. Czy wygląda na to, że maksymalnie wykorzystuję ten serwer? Czy wydajność plików statycznych 1200 Ns / s jest porównywalna z wydajnością innych?
b. Czy istnieją wspólne strojenie Nginx dla takich aplikacji o dużej głośności? Mam wątki robocze ustawione na 64, a wątki robocze gunicorn ustawione na 8, ale poprawianie tych wartości nie pomaga mi ani nie szkodzi.
do. Czy są jakieś ustawienia na poziomie linuksa, które mogłyby ograniczać moje połączenia przychodzące?
re. Co może spowodować spadek wydajności do 250r / s podczas długotrwałych testów? Ponownie pamięć nie wyczerpuje się podczas tych testów, a użycie dysku twardego jest zerowe.
Z góry dziękuję wszystkim :)
EDYCJA Oto moja konfiguracja nginx - http://pastie.org/1450749 - jest to głównie wanilia, z oczywistym tłuszczem odciętym.
źródło
Odpowiedzi:
Nadużywasz wątków robotniczych Nginx. Nie ma absolutnie potrzeby prowadzenia tylu pracowników. Powinieneś uruchomić tyle pracowników, ile masz procesorów i nazwać to dzień. Jeśli używasz gunicorn na tym samym serwerze, prawdopodobnie powinieneś ograniczyć pracowników nginx do dwóch. W przeciwnym razie po prostu przebijesz procesory wszystkimi przełączeniami kontekstu wymaganymi do zarządzania wszystkimi tymi procesami.
źródło
Użyłem nginx do obsługi żądania 5K na sekundę dla zawartości statycznej. Możesz zwiększyć liczbę połączeń pracownik_ aktualnie ustawionych na 1024.
Obliczenie max_client wyglądałoby następująco.
Pracownik_połączenia i pracownik_proceses z sekcji głównej pozwalają obliczyć wartość maxclients:
max_clients = procesy_procesowe * połączenia_procesowe
W sytuacji odwrotnego proxy staje się max_clients
max_clients = procesy_procesowe * połączenia_procesowe / 4
http://wiki.nginx.org/EventsModule#worker_connections
Obliczenie maksymalnej liczby połączeń roboczych jest łatwe, gdy poznasz pojemność konfiguracji. Całkowita pojemność / liczba rdzeni to maksymalna liczba połączeń roboczych. Aby obliczyć całkowitą pojemność, istnieje wiele sposobów.
Jeśli powyższa metoda nie działa, wypróbuj poniższe metody. Robię ogólne założenia, ignorując pamięć RAM i operacje wejścia / wyjścia, one również wezmą pod uwagę, ale te dadzą ci punkty początkowe i odtąd będziesz mógł wprowadzić poprawki.
Zakładając, że przepustowość jest wąskim gardłem, weź średni rozmiar obiektu, który obsługuje nginx, i podziel z nim swoją przepustowość, a otrzymasz maksymalną obsługiwaną szybkość transmisji.
W drugim założeniu procesor jest wąskim gardłem. W takim przypadku zmierz czas żądania i podziel go przez 1 i pomnóż przez liczbę rdzeni w twoim systemie. To da liczbę żądań na sekundę, które nginx może obsłużyć.
źródło