Piszę serwer i wysyłam każdą akcję do osobnego wątku po otrzymaniu żądania. Robię to, ponieważ prawie każde żądanie wykonuje zapytanie do bazy danych. Korzystam z biblioteki wątków, aby ograniczyć budowę / niszczenie wątków.
Moje pytanie brzmi: jaki jest dobry punkt odcięcia dla takich wątków we / wy? Wiem, że to byłby tylko przybliżony szacunek, ale czy mówimy setki? Tysiące?
Jak mógłbym dowiedzieć się, co to będzie za granica?
EDYTOWAĆ:
Dziękuję wszystkim za odpowiedzi, wygląda na to, że będę musiał to przetestować, aby sprawdzić pułap liczby wątków. Pytanie jednak brzmi: skąd mam wiedzieć, że trafiłem w sufit? Co dokładnie powinienem zmierzyć?
Odpowiedzi:
Niektórzy powiedzieliby, że dwa wątki to za dużo - nie jestem w tym obozie :-)
Oto moja rada: zmierz, nie zgaduj. Jedną z sugestii jest skonfigurowanie go i ustawienie początkowo na 100, a następnie wypuszczenie oprogramowania na wolność i monitorowanie tego, co się stanie.
Jeśli użycie wątku osiąga wartość szczytową 3, to 100 to za dużo. Jeśli pozostanie na poziomie 100 przez większą część dnia, podnieś go do 200 i zobacz, co się stanie.
Państwo mogłoby rzeczywiście mają swój kod sama monitorowania użycia i dostosować konfigurację do następnej chwili jej rozpoczęcia, ale to chyba przesada.
W celu wyjaśnienia i opracowania:
Nie opowiadam się za stworzeniem własnego podsystemu pulowania wątków, za wszelką cenę użyj tego, który masz. Ale ponieważ pytałeś o dobry punkt odcięcia dla wątków, zakładam, że twoja implementacja puli wątków ma możliwość ograniczenia maksymalnej liczby utworzonych wątków (co jest dobrą rzeczą).
Napisałem kod puli połączeń wątków i baz danych i mają one następujące funkcje (które moim zdaniem są niezbędne dla wydajności):
Pierwszy określa punkt odniesienia dla minimalnej wydajności pod względem klienta puli wątków (ta liczba wątków jest zawsze dostępna do użycia). Drugi określa ograniczenie wykorzystania zasobów przez aktywne wątki. Trzeci powraca do linii podstawowej w spokojnych czasach, aby zminimalizować zużycie zasobów.
Musisz zrównoważyć zużycie zasobów wynikające z nieużywanych wątków (A) z zużyciem zasobów, ponieważ nie ma wystarczającej liczby wątków do wykonania pracy (B).
(A) to ogólnie użycie pamięci (stosy i tak dalej), ponieważ wątek niedziałający nie będzie zużywał dużo procesora. (B) zazwyczaj opóźnia przetwarzanie żądań, gdy przychodzą, ponieważ musisz poczekać, aż wątek stanie się dostępny.
Właśnie dlatego mierzysz. Jak twierdzisz, ogromna większość twoich wątków będzie czekała na odpowiedź z bazy danych, więc nie będą działać. Istnieją dwa czynniki, które wpływają na liczbę wątków, na które powinieneś zezwolić.
Pierwszy to liczba dostępnych połączeń DB. Może to być twardy limit, chyba że możesz go zwiększyć w DBMS - Zakładam, że twój DBMS może w tym przypadku przyjmować nieograniczoną liczbę połączeń (chociaż najlepiej też to mierzysz).
Następnie liczba wątków, które powinieneś mieć, zależy od twojego historycznego wykorzystania. Minimum, które powinieneś mieć, to minimalna liczba, którą kiedykolwiek miałeś + A%, z absolutnym minimum (na przykład i skonfiguruj go tak jak A) 5.
Maksymalna liczba wątków powinna być historycznym maksimum + B%.
Powinieneś także monitorować zmiany zachowań. Jeśli z jakiegoś powodu twoje użycie osiągnie 100% dostępnego poziomu przez dłuższy czas (tak, aby wpłynęło to na wydajność klientów), powinieneś podnieść maksymalne dozwolone maksimum, aż znów będzie wyższe o B%.
W odpowiedzi na pytanie „co dokładnie powinienem zmierzyć?” pytanie:
To, co powinieneś dokładnie zmierzyć, to maksymalna liczba wątków jednocześnie używanych (np. Oczekujących na powrót z wywołania DB) pod obciążeniem. Następnie dodaj na przykład współczynnik bezpieczeństwa wynoszący 10% (podkreślono, ponieważ inne plakaty wydają się brać moje przykłady za stałe rekomendacje).
Ponadto należy to zrobić w środowisku produkcyjnym w celu dostrojenia. Wcześniej można uzyskać oszacowanie, ale nigdy nie wiadomo, jaka produkcja rzuci Ci drogę (dlatego wszystkie te rzeczy powinny być konfigurowalne w czasie wykonywania). Ma to na celu uchwycenie sytuacji, takiej jak nieoczekiwane podwojenie przychodzących połączeń klientów.
źródło
To pytanie zostało dość dokładnie omówione i nie miałem okazji przeczytać wszystkich odpowiedzi. Ale oto kilka rzeczy, które należy wziąć pod uwagę, patrząc na górną granicę liczby jednoczesnych wątków, które mogą pokojowo współistnieć w danym systemie.
Teraz możesz dostroić rozmiar stosu, aby uwzględnić więcej wątków, ale musisz wziąć pod uwagę koszty zarządzania wątkami (tworzenie / niszczenie i planowanie). Możesz wymusić powinowactwo procesora do danego procesu, a także do danego wątku, aby powiązać je z konkretnymi procesorami, aby uniknąć narzutu migracji wątków między procesorami i uniknąć problemów z zimną gotówką.
Zauważ, że można utworzyć tysiące wątków na jego życzenie, ale kiedy Linuxowi zabraknie VM, to po prostu losowo zaczyna zabijać procesy (czyli wątki). Ma to na celu uniknięcie maksymalnego przekroczenia profilu narzędzia. (Funkcja użyteczności mówi o ogólnosystemowym narzędziu dla określonej ilości zasobów. Przy stałych zasobach w tym przypadku Cykli procesora i pamięci, krzywa użyteczności spłaszcza się z coraz większą liczbą zadań).
Jestem pewien, że program planujący jądro systemu Windows również robi coś takiego, aby poradzić sobie z nadmiernym wykorzystaniem zasobów
[1] http://adywicaksono.wordpress.com/2007/07/10/i-can-not-create-more-than-255-threads-on-linux-what-is-the-solutions/
źródło
Jeśli twoje wątki wykonują jakąkolwiek pracę wymagającą dużych zasobów (procesor / dysk), wtedy rzadko widzisz korzyści przekraczające jeden lub dwa, a zbyt wiele zabija wydajność bardzo szybko.
„Najlepszy przypadek” polega na tym, że twoje późniejsze wątki utkną, gdy pierwsze zostaną ukończone, lub niektóre będą miały narzuty blokujące zasoby o niskiej rywalizacji. Najgorsze jest to, że zaczynasz przerzucać pamięć podręczną / dysk / sieć, a ogólna przepustowość spada.
Dobrym rozwiązaniem jest umieszczanie żądań w puli, które są następnie wysyłane do wątków roboczych z puli wątków (i tak, unikanie ciągłego tworzenia / niszczenia wątków to świetny pierwszy krok).
Liczbę aktywnych wątków w tej puli można następnie dostosować i skalować w oparciu o wyniki profilowania, sprzęt, na którym pracujesz, i inne rzeczy, które mogą wystąpić na komputerze.
źródło
Należy pamiętać, że Python (przynajmniej wersja oparta na języku C) używa tak zwanej globalnej blokady interpretera, która może mieć ogromny wpływ na wydajność na komputerach wielordzeniowych.
Jeśli naprawdę potrzebujesz jak najwięcej z wielowątkowego Pythona, możesz rozważyć użycie Jython lub czegoś takiego.
źródło
Jak słusznie powiedział Pax, zmierz, nie zgaduj . To, co zrobiłem dla DNSwitness i wyniki, było zaskakujące: idealna liczba wątków była znacznie wyższa niż myślałem, około 15 000 wątków, aby uzyskać najszybsze wyniki.
Oczywiście zależy to od wielu rzeczy, dlatego musisz się zmierzyć.
Kompletne środki (tylko w języku francuskim) w Combien de fils d'exécution? .
źródło
Napisałem wiele bardzo wielowątkowych aplikacji. Zasadniczo zezwalam na określenie liczby potencjalnych wątków w pliku konfiguracyjnym. Po dostrojeniu się do konkretnych klientów, ustawiłem wystarczająco wysoką liczbę, aby moje wykorzystanie wszystkich rdzeni procesora było dość wysokie, ale nie tak wysokie, że napotkałem problemy z pamięcią (były to 32-bitowe systemy operacyjne na czas).
Mówiąc inaczej, po osiągnięciu pewnego wąskiego gardła, czy to procesora, przepustowości bazy danych, przepustowości dysku itp., Dodanie większej liczby wątków nie zwiększy ogólnej wydajności. Ale dopóki nie osiągniesz tego punktu, dodaj więcej wątków!
Pamiętaj, że zakłada to, że omawiane systemy są dedykowane twojej aplikacji i nie musisz dobrze grać (unikaj głodowania) innych aplikacji.
źródło
Odpowiedź „dużego żelaza” to na ogół jeden wątek na ograniczony zasób - procesor (związany z procesorem), uzbrojenie (związany z we / wy) itp. - ale działa to tylko wtedy, gdy można skierować pracę do właściwego wątku dla zasobu być dostępnym.
Jeśli nie jest to możliwe, weź pod uwagę, że masz zasoby wymienne (CPU) i zasoby nie wymienne (uzbrojenie). W przypadku procesorów nie jest ważne przypisanie każdego wątku do konkretnego procesora (choć pomaga to w zarządzaniu pamięcią podręczną), ale w przypadku uzbrojenia, jeśli nie można przypisać wątku do ramienia, przechodzi się do teorii kolejkowania i optymalnej liczby, aby zachować uzbrojenie zajęty. Ogólnie myślę, że jeśli nie możesz kierować żądań w oparciu o używane ramię, to posiadanie 2-3 wątków na ramię będzie odpowiednie.
Komplikacja pojawia się, gdy jednostka pracy przekazana do wątku nie wykonuje rozsądnie atomowej jednostki pracy. Na przykład wątek może mieć dostęp do dysku w innym miejscu, w innym miejscu należy zaczekać w sieci. Zwiększa to liczbę „pęknięć”, do których mogą dostać się dodatkowe wątki i wykonują użyteczną pracę, ale także zwiększa możliwość wzajemnego zanieczyszczania pamięci podręcznych itp. I zapychania systemu.
Oczywiście musisz to wszystko porównać z „ciężarem” nici. Niestety większość systemów ma bardzo ciężkie wątki (a tak zwane „wątki lekkie” często wcale nie są wątkami), więc lepiej jest pomylić się z niskimi stronami.
W praktyce widziałem, że bardzo subtelne różnice mogą mieć ogromny wpływ na to, ile wątków jest optymalnych. W szczególności problemy z pamięcią podręczną i konflikty blokad mogą znacznie ograniczyć praktyczną współbieżność.
źródło
Jedną rzeczą do rozważenia jest to, ile rdzeni istnieje na komputerze, który będzie wykonywał kod. Jest to twardy limit liczby wątków, które mogą być wykonywane w danym momencie. Jeśli jednak, tak jak w twoim przypadku, wątki często oczekują na wykonanie zapytania przez bazę danych, prawdopodobnie zechcesz dostroić wątki na podstawie liczby jednoczesnych zapytań, które baza danych może przetworzyć.
źródło
Myślę, że to trochę unika twojego pytania, ale dlaczego nie podzielić ich na procesy? Moje rozumienie sieci (od mglistych dni, tak naprawdę wcale nie koduję sieci) było takie, że każde połączenie przychodzące może być traktowane jako osobny proces, ponieważ wtedy, gdy ktoś robi coś nieprzyjemnego w twoim procesie, nie robi to nuke cały program.
źródło
ryeguy, obecnie opracowuję podobną aplikację, a mój numer wątków jest ustawiony na 15. Niestety, jeśli zwiększę ją o 20, zawiesza się. Tak, tak, myślę, że najlepszym sposobem na poradzenie sobie z tym jest sprawdzenie, czy twoja obecna konfiguracja pozwala na więcej lub mniej X wątków.
źródło
W większości przypadków należy pozwolić puli wątków sobie z tym poradzić. Jeśli opublikujesz jakiś kod lub podasz więcej szczegółów, łatwiej będzie sprawdzić, czy istnieje jakiś powód, dla którego domyślne zachowanie puli wątków nie byłoby najlepsze.
Więcej informacji o tym, jak to powinno działać, można znaleźć tutaj: http://en.wikipedia.org/wiki/Thread_pool_pattern
źródło
Często słyszałem tyle wątków, ile rdzeni procesora.
źródło