PYTANIE: Instancje vs. rdzenie przy użyciu EC2
Pracując nad czymś, co często można nazwać projektami „średnich danych”, byłem w stanie zrównoleglać mój kod (głównie do modelowania i prognozowania w Pythonie) w jednym systemie w dowolnym miejscu od 4 do 32 rdzeni. Teraz zastanawiam się nad skalowaniem do klastrów w EC2 (prawdopodobnie z StarCluster / IPython, ale także otwartym na inne sugestie) i zastanawiałem się, jak pogodzić dystrybucję pracy między rdzeniami w instancji vs. instancje w klastrze.
Czy praktyczna jest nawet równoległość między instancjami, a także między rdzeniami w każdej instancji?
Jeśli tak, to czy ktoś może szybko podsumować zalety i wady prowadzenia wielu instancji z kilkoma rdzeniami w porównaniu do kilku instancji z wieloma rdzeniami? Czy istnieje ogólna zasada wyboru właściwego stosunku liczby instancji do liczby rdzeni na instancję?
Przepustowość i pamięć RAM nie są trywialnymi problemami w moich projektach, ale łatwo jest zauważyć, kiedy są to wąskie gardła i dostosować je. Wyobrażam sobie, że o wiele trudniej jest porównać właściwą kombinację rdzeni z instancjami bez powtarzania testów, a moje projekty różnią się zbytnio, aby każdy test mógł być zastosowany w każdych okolicznościach. Z góry dziękuję, a jeśli nie udało mi się poprawnie google google, możesz wskazać mi właściwą odpowiedź w innym miejscu!
ODPOWIEDŹ: Korzystając z IPython, prawie nie musisz się o to martwić (kosztem pewnej utraty wydajności / większego narzutu komunikacji). Równoległa wtyczka IPython w StarCluster domyślnie uruchomi jeden silnik na fizyczny rdzeń w każdym węźle (uważam, że można to skonfigurować, ale nie jestem pewien, gdzie). Po prostu uruchamiasz, co chcesz we wszystkich silnikach, używając interfejsu API DirectView (map_sync, Apply_sync,…) lub magicznych poleceń %px. Jeśli używasz już IPython równolegle na jednym komputerze, użycie go w klastrze nie różni się. Odpowiadając na niektóre z twoich szczegółowych pytań: „jak pogodzić dystrybucję pracy między rdzeniami w instancji a instancjami w klastrze” – otrzymujesz przynajmniej jeden silnik na rdzeń (przynajmniej); praca jest automatycznie dystrybuowana we wszystkich rdzeniach i we wszystkich instancjach. „Czy praktyczna jest nawet równoległość między instancjami, a także między rdzeniami w każdej instancji?” – Tak 🙂 Jeśli kod, który uruchamiasz, jest krępująco równoległy (dokładnie ten sam algorytm na wielu zestawach danych), możesz w większości zignorować, gdzie działa dany silnik. Jeśli rdzeń wymaga dużej komunikacji między silnikami, to oczywiście musisz go tak skonstruować, aby silniki komunikowały się przede wszystkim z innymi silnikami na tej samej maszynie fizycznej; ale myślę, że tego rodzaju problem nie jest idealny dla IPython. „Jeśli tak, to czy ktoś może szybko podsumować zalety i wady prowadzenia wielu instancji z kilkoma rdzeniami w porównaniu do kilku instancji z wieloma rdzeniami? Czy istnieje ogólna zasada wyboru właściwego stosunku liczby instancji do liczby rdzeni na instancję? ” – Użyj największych instancji c3 dla ograniczeń obliczeniowych, a najmniejszych dla problemów związanych z przepustowością pamięci (lub wystarczająco małych, aby problem prawie przestał być związany z przepustowością pamięci); w przypadku problemów związanych z przekazywaniem wiadomości należy również użyć największych instancji, ale spróbuj podzielić problem na partycje, aby każda partycja działała na jednym fizycznym komputerze, a większość przekazywanych wiadomości była w tej samej partycji. Problemy, które działają znacznie wolniej na N poczwórnej c3 niż na 2N podwójnej c3, są rzadkie (sztuczny przykład może polegać na uruchamianiu wielu prostych filtrów na dużej liczbie obrazów, w których przeglądasz wszystkie obrazy dla każdego filtra zamiast wszystkich filtrów dla tego samego obrazu ). Używanie największych instancji jest dobrą regułą.
ODPOWIEDŹ: Ogólną zasadą jest, aby nie rozpowszechniać, dopóki nie będziesz musiał. Zazwyczaj bardziej wydajne jest posiadanie N serwerów o określonej pojemności niż 2N serwerów o połowie takiej pojemności. Większy dostęp do danych będzie lokalny, a zatem szybki w pamięci w porównaniu do wolnego w sieci.
W pewnym momencie skalowanie jednej maszyny staje się nieekonomiczne, ponieważ koszt dodatkowych zasobów skaluje się bardziej niż liniowo. Jednak ten punkt jest wciąż niezwykle wysoki. W szczególności na Amazon, ekonomia każdego typu instancji może się znacznie różnić, jeśli używasz instancji rynku kasowego. Domyślna wycena mniej więcej oznacza, że ta sama kwota kosztów zasobów mniej więcej taka sama, niezależnie od typu wystąpienia, która może się znacznie różnić; duże instancje mogą być tańsze niż małe lub N małych instancji może być znacznie tańsze niż jedna duża maszyna z równoważnymi zasobami. Ogromne znaczenie ma tutaj to, że algorytm obliczeń może się bardzo zmienić, gdy przenosisz się z jednej maszyny na wiele maszyn. Kompromisy, które wywołują narzuty komunikacyjne, mogą zmusić Cię do przyjęcia na przykład paradygmatu równoległego do skalowania. Oznacza to inny wybór narzędzi i algorytmu. Na przykład SGD wygląda zupełnie inaczej w pamięci iw Pythonie niż na MapReduce. Abyś tak zrobił należy to rozważyć przed zrównolegleniem. Możesz zdecydować się na dystrybucję pracy w klastrze, nawet jeśli jeden węzeł i niedystrybuowane paradygmaty działają dla Ciebie, dla niezawodności. Jeśli pojedynczy węzeł zawiedzie, tracisz wszystkie obliczenia; obliczenia rozproszone mogą potencjalnie odzyskać i zakończyć tylko część obliczeń, która została utracona.
ODPOWIEDŹ: Wszystkie rzeczy uważane za równe (koszt, wydajność procesora itp.), Możesz wybrać najmniejszą instancję, która może przechowywać cały mój zestaw danych w pamięci i skalować. W ten sposób upewniasz się, że nie wywołujesz niepotrzebnych opóźnień z powodu komunikacji sieciowej i dążysz do maksymalizacji całkowitej dostępnej przepustowości pamięci dla swoich procesów. Zakładając, że korzystasz z jakiegoś schematu weryfikacji krzyżowej w celu zoptymalizowania niektórych meta-parametrów twojego modelu, przypisz każdemu rdzeniu wartość do przetestowania i wybierz wiele instancji w razie potrzeby, aby pokryć całą przestrzeń parametrów w tak małej liczbie rund, jak uznasz za stosowne. Jeśli Twoje dane nie mieszczą się w pamięci jednego systemu, oczywiście musisz rozdzielić je między instancje. Następnie chodzi o zrównoważenie opóźnienia pamięci (lepiej w wielu instancjach) z opóźnieniem sieci (lepiej w mniejszej liczbie instancji), ale biorąc pod uwagę naturę EC2, założę się, że często wolisz pracować z kilkoma grubymi instancjami.